fix crash bugs and memory leaks.
This commit is contained in:
@@ -53,16 +53,21 @@ void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||
apiBufferSize_ = frameInfo.PointerShapeBufferSize;
|
||||
apiBuffer_ = std::make_unique<BYTE[]>(apiBufferSize_);
|
||||
}
|
||||
if (!apiBuffer_) return;
|
||||
|
||||
if (!apiBuffer_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get mouse pointer information
|
||||
UINT bufferSize;
|
||||
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo;
|
||||
const auto hr = monitor_->GetDeskDupl()->GetFramePointerShape(
|
||||
apiBufferSize_,
|
||||
reinterpret_cast<void*>(apiBuffer_.get()),
|
||||
apiBuffer_.get(),
|
||||
&bufferSize,
|
||||
&shapeInfo);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateBuffer() => GetFramePointerShape() failed.");
|
||||
@@ -149,13 +154,12 @@ void Cursor::UpdateTexture()
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
ID3D11Texture2D* texture;
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
if (FAILED(GetDevice()->CreateTexture2D(&desc, nullptr, &texture)))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => GetDevice()->CreateTexture2D() failed.");
|
||||
return;
|
||||
}
|
||||
const auto textureReleaser = MakeUniqueWithReleaser(texture);
|
||||
|
||||
D3D11_BOX box;
|
||||
box.front = 0;
|
||||
@@ -171,18 +175,18 @@ void Cursor::UpdateTexture()
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture, 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
|
||||
context->Release();
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
|
||||
}
|
||||
|
||||
IDXGISurface* surface;
|
||||
if (FAILED(texture->QueryInterface<IDXGISurface>(&surface)))
|
||||
ComPtr<IDXGISurface> surface;
|
||||
if (FAILED(texture.As(&surface)))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => texture->QueryInterface() failed.");
|
||||
return;
|
||||
}
|
||||
const auto surfaceReleaser = MakeUniqueWithReleaser(surface);
|
||||
|
||||
DXGI_MAPPED_RECT mappedSurface;
|
||||
if (FAILED(surface->Map(&mappedSurface, DXGI_MAP_READ)))
|
||||
@@ -282,10 +286,9 @@ void Cursor::GetTexture(ID3D11Texture2D* texture)
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* context;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->UpdateSubresource(texture, 0, nullptr, bgra32Buffer_.get(), GetWidth() * 4, 0);
|
||||
context->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ Monitor::~Monitor()
|
||||
if (deskDupl_)
|
||||
{
|
||||
deskDupl_->Release();
|
||||
deskDupl_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ void Monitor::Render(UINT timeout)
|
||||
{
|
||||
if (!deskDupl_) return;
|
||||
|
||||
IDXGIResource* resource;
|
||||
ComPtr<IDXGIResource> resource;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
|
||||
const auto hr = deskDupl_->AcquireNextFrame(timeout, &frameInfo, &resource);
|
||||
@@ -181,10 +182,9 @@ void Monitor::Render(UINT timeout)
|
||||
}
|
||||
else
|
||||
{
|
||||
ID3D11DeviceContext* context;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(unityTexture_, texture);
|
||||
context->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,11 +33,8 @@ void MonitorManager::Initialize()
|
||||
{
|
||||
Finalize();
|
||||
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
ComPtr<IDXGIOutput> output;
|
||||
|
||||
// Get factory
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
||||
{
|
||||
Debug::Error("MonitorManager::Initialize() => CreateDXGIFactory1() failed.");
|
||||
@@ -46,9 +43,11 @@ void MonitorManager::Initialize()
|
||||
|
||||
// Check all display adapters
|
||||
int id = 0;
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
||||
{
|
||||
// Search the main monitor from all outputs
|
||||
ComPtr<IDXGIOutput> output;
|
||||
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
||||
{
|
||||
auto monitor = std::make_shared<Monitor>(id++);
|
||||
@@ -79,31 +78,27 @@ void MonitorManager::Reinitialize()
|
||||
}
|
||||
|
||||
|
||||
void MonitorManager::CheckMonitorNumbers()
|
||||
bool MonitorManager::HasMonitorCountChanged() const
|
||||
{
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
ComPtr<IDXGIOutput> output;
|
||||
|
||||
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
||||
{
|
||||
Debug::Error("MonitorManager::CheckMonitorNumbers() => CreateDXGIFactory1() failed.");
|
||||
return;
|
||||
Debug::Error("MonitorManager::CheckMonitorConnection() => CreateDXGIFactory1() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
||||
{
|
||||
ComPtr<IDXGIOutput> output;
|
||||
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
||||
{
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetMonitorCount() != id)
|
||||
{
|
||||
RequireReinitilization();
|
||||
}
|
||||
return monitors_.size() != id;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,8 +114,6 @@ std::shared_ptr<Monitor> MonitorManager::GetMonitor(int id) const
|
||||
|
||||
void MonitorManager::Update()
|
||||
{
|
||||
CheckMonitorNumbers();
|
||||
|
||||
if (isReinitializationRequired_)
|
||||
{
|
||||
Reinitialize();
|
||||
@@ -146,6 +139,7 @@ int MonitorManager::GetMonitorCount() const
|
||||
return static_cast<int>(monitors_.size());
|
||||
}
|
||||
|
||||
|
||||
int MonitorManager::GetTotalWidth() const
|
||||
{
|
||||
std::vector<int> lefts, rights;
|
||||
@@ -159,6 +153,7 @@ int MonitorManager::GetTotalWidth() const
|
||||
return maxRight - minLeft;
|
||||
}
|
||||
|
||||
|
||||
int MonitorManager::GetTotalHeight() const
|
||||
{
|
||||
std::vector<int> tops, bottoms;
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
explicit MonitorManager();
|
||||
~MonitorManager();
|
||||
void Reinitialize();
|
||||
void CheckMonitorNumbers();
|
||||
bool HasMonitorCountChanged() const;
|
||||
void RequireReinitilization();
|
||||
void SetCursorMonitorId(int id) { cursorMonitorId_ = id; }
|
||||
int GetCursorMonitorId() const { return cursorMonitorId_; }
|
||||
|
||||
@@ -115,6 +115,12 @@ extern "C"
|
||||
return g_manager->GetMonitorCount();
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API HasMonitorCountChanged()
|
||||
{
|
||||
if (!g_manager) return false;
|
||||
return g_manager->HasMonitorCountChanged();
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorMonitorId()
|
||||
{
|
||||
if (!g_manager) return -1;
|
||||
|
||||
Reference in New Issue
Block a user