diff --git a/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll b/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll index 1d323d3..8efd3cd 100644 Binary files a/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll and b/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll differ diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h index 088026c..f74067f 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h @@ -2,6 +2,7 @@ #include #include +#include // Unity interface and ID3D11Device getters @@ -12,6 +13,15 @@ struct ID3D11Device; ID3D11Device* GetDevice(); +// Utility +template +auto MakeUniqueWithReleaser(T* ptr) +{ + const auto deleter = [](T* ptr) { ptr->Release(); }; + return std::unique_ptr(ptr, deleter); +} + + // Manager getter class MonitorManager; const std::unique_ptr& GetMonitorManager(); diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp index a9d03de..ec1ce39 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp @@ -1,5 +1,6 @@ #include #include "Common.h" +#include "Debug.h" #include "MonitorManager.h" #include "Monitor.h" #include "Cursor.h" @@ -53,8 +54,10 @@ void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) reinterpret_cast(apiBuffer_.get()), &bufferSize, &shapeInfo_); + if (FAILED(hr)) { + Debug::Error("Cursor::UpdateBuffer() => GetFramePointerShape() failed."); apiBuffer_.reset(); apiBufferSize_ = 0; } @@ -103,8 +106,10 @@ void Cursor::UpdateTexture() hr = GetDevice()->CreateTexture2D(&desc, nullptr, &texture); if (FAILED(hr)) { + Debug::Error("Cursor::UpdateTexture() => GetDevice()->CreateTexture2D() failed."); return; } + const auto textureReleaser = MakeUniqueWithReleaser(texture); D3D11_BOX box; box.front = 0; @@ -114,6 +119,24 @@ void Cursor::UpdateTexture() box.right = x_ + w; box.bottom = y_ + h; + const UINT mw = monitor_->GetWidth(); + const UINT mh = monitor_->GetHeight(); + if (box.left < 0 || box.top < 0 || box.right >= mw || box.bottom >= mh) + { + char buf[256]; + sprintf_s(buf, 256, + "Cursor::UpdateTexture() => D3D11_BOX is out of area (%d, %d) ~ (%d, %d).", + box.left, box.top, box.right, box.bottom); + Debug::Error(buf); + return; + } + + if (monitor_->GetUnityTexture() == nullptr) + { + Debug::Error("Cursor::UpdateTexture() => Monitor::GetUnityTexture() is null."); + return; + } + ID3D11DeviceContext* context; GetDevice()->GetImmediateContext(&context); context->CopySubresourceRegion(texture, 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box); @@ -121,17 +144,18 @@ void Cursor::UpdateTexture() IDXGISurface* surface = nullptr; hr = texture->QueryInterface(__uuidof(IDXGISurface), (void**)&surface); - texture->Release(); if (FAILED(hr)) { + Debug::Error("Cursor::UpdateTexture() => texture->QueryInterface() failed."); return; } + const auto surfaceReleaser = MakeUniqueWithReleaser(surface); DXGI_MAPPED_RECT mappedSurface; hr = surface->Map(&mappedSurface, DXGI_MAP_READ); if (FAILED(hr)) { - surface->Release(); + Debug::Error("Cursor::UpdateTexture() => surface->Map() failed."); return; } @@ -184,7 +208,6 @@ void Cursor::UpdateTexture() } hr = surface->Unmap(); - surface->Release(); if (FAILED(hr)) { return; @@ -206,10 +229,34 @@ void Cursor::UpdateTexture() void Cursor::GetTexture(ID3D11Texture2D* texture) { - if (bgra32Buffer_ == nullptr || texture == nullptr) return; + if (bgra32Buffer_ == nullptr) + { + Debug::Error("Cursor::GetTexture() => bgra32Buffer is null."); + return; + } + + if (texture == nullptr) + { + Debug::Error("Cursor::GetTexture() => The given texture is null."); + return; + } + + D3D11_TEXTURE2D_DESC desc; + texture->GetDesc(&desc); + if ((int)desc.Width < GetWidth() || (int)desc.Height < GetHeight()) + { + char buf[256]; + sprintf_s(buf, 256, + "Cursor::GetTexture() => The given texture has smaller width / height.\n" + "Given => (%d, %d) Buffer => (%d, %d)", + desc.Width, desc.Height, GetWidth(), GetHeight()); + Debug::Error(buf); + return; + } + ID3D11DeviceContext* context; GetDevice()->GetImmediateContext(&context); - context->UpdateSubresource(texture, 0, nullptr, bgra32Buffer_.get(), shapeInfo_.Width * 4, 0); + context->UpdateSubresource(texture, 0, nullptr, bgra32Buffer_.get(), GetWidth() * 4, 0); context->Release(); } diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp index 9c1e1ea..d1d4093 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp @@ -98,6 +98,7 @@ void Monitor::Render(UINT timeout) } return; } + const auto resourceReleaser = MakeUniqueWithReleaser(resource); if (unityTexture_) { @@ -108,8 +109,6 @@ void Monitor::Render(UINT timeout) GetDevice()->GetImmediateContext(&context); context->CopyResource(unityTexture_, texture); context->Release(); - - resource->Release(); } cursor_->UpdateBuffer(frameInfo); diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/MonitorManager.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/MonitorManager.cpp index e985976..0877fbd 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/MonitorManager.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/MonitorManager.cpp @@ -32,24 +32,24 @@ void MonitorManager::Initialize() // Get factory IDXGIFactory1* factory; CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast(&factory)); + const auto factoryReleaser = MakeUniqueWithReleaser(factory); // Check all display adapters int id = 0; IDXGIAdapter1* adapter; for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i) { + const auto adapterReleaser = MakeUniqueWithReleaser(adapter); // Search the main monitor from all outputs IDXGIOutput* output; for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j) { + const auto outputReleaser = MakeUniqueWithReleaser(output); auto monitor = std::make_shared(id++); monitor->Initialize(output); monitors_.push_back(monitor); - output->Release(); } - adapter->Release(); } - factory->Release(); }