diff --git a/Assets/uDesktopDuplication/Plugins/x86/uDesktopDuplication.dll b/Assets/uDesktopDuplication/Plugins/x86/uDesktopDuplication.dll index da9b2dc..17c5a37 100644 Binary files a/Assets/uDesktopDuplication/Plugins/x86/uDesktopDuplication.dll and b/Assets/uDesktopDuplication/Plugins/x86/uDesktopDuplication.dll differ diff --git a/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll b/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll index 3f96f84..ef95c90 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/Device.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Device.cpp index 01240e7..7873e5f 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Device.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Device.cpp @@ -7,6 +7,7 @@ #include "IUnityGraphicsD3D11.h" #include "Device.h" #include "Debug.h" +#include "Common.h" #pragma comment(lib, "d3d11.lib") @@ -14,9 +15,39 @@ using namespace Microsoft::WRL; -IsolatedD3D11Device::IsolatedD3D11Device(UINT cachedTextureNum) - : cachedTextures_(cachedTextureNum) +Microsoft::WRL::ComPtr SharedTextureWrapper::Get() { + return pointer_; +} + + +bool SharedTextureWrapper::Lock() +{ + if (locked_) return false; + locked_ = true; + return true; +} + + +void SharedTextureWrapper::Unlock() +{ + locked_ = false; +} + + +bool SharedTextureWrapper::IsLocked() const +{ + return locked_; +} + + + +IsolatedD3D11Device::IsolatedD3D11Device(UINT cachedTextureNum) +{ + for (UINT i = 0; i < cachedTextureNum; ++i) + { + cachedSharedTextures_.push_back(std::make_shared()); + } } @@ -65,42 +96,43 @@ ComPtr IsolatedD3D11Device::GetDevice() } -ComPtr IsolatedD3D11Device::GetCompatibleSharedTexture( +std::shared_ptr IsolatedD3D11Device::GetCompatibleSharedTexture( const ComPtr& src, UINT index) { - if (index < 0 || index >= cachedTextures_.size()) + if (index < 0 || index >= cachedSharedTextures_.size()) { Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => ", index, " is out of cachedTextures range."); return nullptr; } - auto& cachedTexture = cachedTextures_.at(index); + auto& sharedTextureWrapper = cachedSharedTextures_.at(index); + auto& texture = sharedTextureWrapper->pointer_; D3D11_TEXTURE2D_DESC srcDesc; src->GetDesc(&srcDesc); // check if the format and size of the current texture are same as the source one - if (cachedTexture) + if (texture) { D3D11_TEXTURE2D_DESC targetDesc; - cachedTexture->GetDesc(&targetDesc); + texture->GetDesc(&targetDesc); if (targetDesc.Format == srcDesc.Format && targetDesc.Width == srcDesc.Width && targetDesc.Height == srcDesc.Height) { - return cachedTexture; + return sharedTextureWrapper; } } // for sharing this texture with unity device srcDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; - if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &cachedTexture))) + if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &texture))) { Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => Creating shared texture failed."); return nullptr; } - return cachedTexture; + return sharedTextureWrapper; } \ No newline at end of file diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Device.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Device.h index 70db375..ff10978 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Device.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Device.h @@ -1,10 +1,28 @@ #pragma once +#include #include +#include #include #include +// Shared texture wrapper to manager locking state +class SharedTextureWrapper +{ +friend class IsolatedD3D11Device; +public: + Microsoft::WRL::ComPtr Get(); + bool Lock(); + void Unlock(); + bool IsLocked() const; + +private: + std::atomic locked_ = false; + Microsoft::WRL::ComPtr pointer_; +}; + + // Thraed safe self created ID3D11Device from specified adapter class IsolatedD3D11Device { @@ -14,11 +32,11 @@ public: HRESULT Create(const Microsoft::WRL::ComPtr& adapter); Microsoft::WRL::ComPtr GetDevice(); - Microsoft::WRL::ComPtr GetCompatibleSharedTexture( + std::shared_ptr GetCompatibleSharedTexture( const Microsoft::WRL::ComPtr& src, UINT index); private: Microsoft::WRL::ComPtr device_; - std::vector> cachedTextures_; + std::vector> cachedSharedTextures_; }; diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp index bf2a3d2..9f0f3b0 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp @@ -315,13 +315,16 @@ void Duplicator::Duplicate(UINT timeout) return; } - auto sharedTexture = device_->GetCompatibleSharedTexture(texture, lastFrameId_ % 2); - if (!sharedTexture) + auto sharedTextureWrapper = device_->GetCompatibleSharedTexture(texture, 0); + if (!sharedTextureWrapper) { Debug::Error("Duplicator::Duplicate() => Shared Texture was null."); return; } + if (sharedTextureWrapper->IsLocked()) return; + auto sharedTexture = sharedTextureWrapper->Get(); + ComPtr context; device_->GetDevice()->GetImmediateContext(&context); context->CopyResource(sharedTexture.Get(), texture.Get()); @@ -334,7 +337,7 @@ void Duplicator::Duplicate(UINT timeout) lastFrame_ = Frame { lastFrameId_++, - sharedTexture, + sharedTextureWrapper, frameInfo, metaData_ }; diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h index 3f4523b..b52d361 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h @@ -45,7 +45,7 @@ public: struct Frame { UINT id; - Microsoft::WRL::ComPtr texture; + std::shared_ptr texture; DXGI_OUTDUPL_FRAME_INFO info; Metadata metaData; }; diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp index a041187..10b46c7 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp @@ -75,10 +75,13 @@ void Monitor::Render() if (frame.id == lastFrameId_) return; lastFrameId_ = frame.id; - const auto& texture = frame.texture; - if (!texture) return; + const auto& sharedTextureWrapper = frame.texture; + if (!sharedTextureWrapper->Lock()) return; + ScopedReleaser releaser([&] { sharedTextureWrapper->Unlock(); }); + + auto texture = sharedTextureWrapper->Get(); + if (!texture) return; - // Get texture if (unityTexture_) { D3D11_TEXTURE2D_DESC srcDesc, dstDesc;