diff --git a/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll b/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll index 4200a57..8f6aa99 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 2606a62..7f04629 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Common.h @@ -54,8 +54,30 @@ template class Buffer { public: - Buffer() {} - ~Buffer() {} + Buffer() + { + } + + Buffer& operator=(const Buffer& other) + { + if (&other == this) return *this; + + value_.reset(); + size_ = 0; + ExpandIfNeeded(other.size_); + memcpy_s(value_.get(), size_, other.value_.get(), other.size_); + + return *this; + } + + ~Buffer() + { + } + + bool Empty() const + { + return !value_; + } void ExpandIfNeeded(UINT size) { diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp index 852efc6..873de69 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.cpp @@ -3,7 +3,6 @@ #include "Duplicator.h" #include "Monitor.h" #include "Device.h" -#include "Common.h" #include "Debug.h" #include "IUnityInterface.h" @@ -213,30 +212,30 @@ bool Duplicator::Duplicate() { // If any monitor setting has changed (e.g. monitor size has changed), // it is necessary to re-initialize monitors. - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST."); + Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST."); state_ = State::AccessLost; break; } case DXGI_ERROR_WAIT_TIMEOUT: { // This often occurs when timeout value is small and it is not problem. - // Debug::Log("Monitor::Render() => DXGI_ERROR_WAIT_TIMEOUT."); + // Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_WAIT_TIMEOUT."); break; } case DXGI_ERROR_INVALID_CALL: { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL."); + Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL."); break; } case E_INVALIDARG: { - Debug::Error("Monitor::Render() => E_INVALIDARG."); + Debug::Error("Duplicator::Duplicate() => E_INVALIDARG."); break; } default: { state_ = State::Unknown; - Debug::Error("Monitor::Render() => Unknown Error."); + Debug::Error("Duplicator::Duplicate() => Unknown Error."); break; } } @@ -252,19 +251,19 @@ bool Duplicator::Duplicate() { case DXGI_ERROR_ACCESS_LOST: { - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST."); + Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST."); state_ = State::AccessLost; break; } case DXGI_ERROR_INVALID_CALL: { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL."); + Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL."); break; } default: { state_ = State::Unknown; - Debug::Error("Monitor::Render() => Unknown Error."); + Debug::Error("Duplicator::Duplicate() => Unknown Error."); break; } } @@ -289,8 +288,115 @@ bool Duplicator::Duplicate() { std::lock_guard lock(mutex_); - lastFrame_ = Frame { copyTarget, frameInfo }; + lastFrame_.texture = copyTarget; + lastFrame_.info = frameInfo; } + UpdateMetadata(); + return true; +} + + +void Duplicator::UpdateMetadata() +{ + metaData_.buffer.ExpandIfNeeded(lastFrame_.info.TotalMetadataBufferSize); + if (!metaData_.buffer.Empty()) + { + UpdateMoveRects(); + UpdateDirtyRects(); + } + + { + std::lock_guard lock(mutex_); + lastFrame_.metaData = metaData_; + } +} + + +void Duplicator::UpdateMoveRects() +{ + metaData_.moveRectSize = metaData_.buffer.Size(); + + const auto hr = dupl_->GetFrameMoveRects( + metaData_.moveRectSize, + metaData_.buffer.As(), + &metaData_.moveRectSize); + + if (FAILED(hr)) + { + switch (hr) + { + case DXGI_ERROR_ACCESS_LOST: + { + Debug::Log("Duplicator::UpdateMoveRects() => DXGI_ERROR_ACCESS_LOST."); + break; + } + case DXGI_ERROR_MORE_DATA: + { + Debug::Error("Duplicator::UpdateMoveRects() => DXGI_ERROR_MORE_DATA."); + break; + } + case DXGI_ERROR_INVALID_CALL: + { + Debug::Error("Duplicator::UpdateMoveRects() => DXGI_ERROR_INVALID_CALL."); + break; + } + case E_INVALIDARG: + { + Debug::Error("Duplicator::UpdateMoveRects() => E_INVALIDARG."); + break; + } + default: + { + Debug::Error("Duplicator::UpdateMoveRects() => Unknown Error."); + break; + } + } + return; + } +} + + +void Duplicator::UpdateDirtyRects() +{ + metaData_.dirtyRectSize = metaData_.buffer.Size() - metaData_.moveRectSize; + + const auto hr = dupl_->GetFrameDirtyRects( + metaData_.dirtyRectSize, + metaData_.buffer.As(metaData_.moveRectSize /* offset */), + &metaData_.dirtyRectSize); + + if (FAILED(hr)) + { + switch (hr) + { + case DXGI_ERROR_ACCESS_LOST: + { + Debug::Log("Duplicator::UpdateDirtyRects() => DXGI_ERROR_ACCESS_LOST."); + break; + } + case DXGI_ERROR_MORE_DATA: + { + Debug::Error("Duplicator::UpdateDirtyRects() => DXGI_ERROR_MORE_DATA."); + break; + } + case DXGI_ERROR_INVALID_CALL: + { + Debug::Error("Duplicator::UpdateDirtyRects() => DXGI_ERROR_INVALID_CALL."); + break; + } + case E_INVALIDARG: + { + Debug::Error("Duplicator::UpdateDirtyRects() => E_INVALIDARG."); + break; + } + default: + { + Debug::Error("Duplicator::UpdateDirtyRects() => Unknown Error."); + break; + } + } + return; + } } \ No newline at end of file diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h index 86673a2..9330909 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Duplicator.h @@ -7,6 +7,8 @@ #include #include +#include "Common.h" + class Monitor; @@ -32,10 +34,18 @@ class Duplicator public: using State = DuplicatorState; + struct Metadata + { + Buffer buffer; + UINT moveRectSize = 0; + UINT dirtyRectSize = 0; + }; + struct Frame { Microsoft::WRL::ComPtr texture; DXGI_OUTDUPL_FRAME_INFO info; + Metadata metaData; }; explicit Duplicator(Monitor* monitor); @@ -52,7 +62,11 @@ private: void InitializeDevice(); void InitializeDuplication(); void CheckUnityAdapter(); + bool Duplicate(); + void UpdateMetadata(); + void UpdateMoveRects(); + void UpdateDirtyRects(); Monitor* monitor_ = nullptr; State state_ = State::Ready; @@ -64,4 +78,6 @@ private: volatile bool shouldRun_ = false; std::thread thread_; mutable std::mutex mutex_; + + Metadata metaData_; }; diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp index bdad7be..ee0d732 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp @@ -67,9 +67,9 @@ void Monitor::Initialize( void Monitor::Render() { - const auto frame = duplicator_->GetFrame(); // copy + const auto& frame = duplicator_->GetFrame(); const auto texture = frame.texture; - const auto frameInfo = frame.info; + const auto& frameInfo = frame.info; if (!texture) return; @@ -100,8 +100,6 @@ void Monitor::Render() } } - UpdateMetadata(frameInfo); - if (frameInfo.PointerPosition.Visible) { GetMonitorManager()->SetCursorMonitorId(id_); @@ -129,102 +127,6 @@ void Monitor::UpdateCursor(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) } -void Monitor::UpdateMetadata(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) -{ - metaData_.ExpandIfNeeded(frameInfo.TotalMetadataBufferSize); - UpdateMoveRects(frameInfo); - UpdateDirtyRects(frameInfo); -} - - -void Monitor::UpdateMoveRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) -{ - moveRectSize_ = metaData_.Size(); - - const auto hr = GetDeskDupl()->GetFrameMoveRects( - moveRectSize_, - metaData_.As(), - &moveRectSize_); - - if (FAILED(hr)) - { - switch (hr) - { - case DXGI_ERROR_ACCESS_LOST: - { - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST (GetFrameMoveRects())."); - break; - } - case DXGI_ERROR_MORE_DATA: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_MORE_DATA (GetFrameMoveRects())."); - break; - } - case DXGI_ERROR_INVALID_CALL: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL (GetFrameMoveRects())."); - break; - } - case E_INVALIDARG: - { - Debug::Error("Monitor::Render() => E_INVALIDARG (GetFrameMoveRects())."); - break; - } - default: - { - Debug::Error("Monitor::Render() => Unknown Error (GetFrameMoveRects())."); - break; - } - } - return; - } -} - - -void Monitor::UpdateDirtyRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) -{ - dirtyRectSize_ = metaData_.Size() - moveRectSize_; - - const auto hr = GetDeskDupl()->GetFrameDirtyRects( - dirtyRectSize_, - metaData_.As(moveRectSize_ /* offset */), - &dirtyRectSize_); - - if (FAILED(hr)) - { - switch (hr) - { - case DXGI_ERROR_ACCESS_LOST: - { - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST (GetFrameDirtyRects())."); - break; - } - case DXGI_ERROR_MORE_DATA: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_MORE_DATA (GetFrameDirtyRects())."); - break; - } - case DXGI_ERROR_INVALID_CALL: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL (GetFrameDirtyRects())."); - break; - } - case E_INVALIDARG: - { - Debug::Error("Monitor::Render() => E_INVALIDARG (GetFrameDirtyRects())."); - break; - } - default: - { - Debug::Error("Monitor::Render() => Unknown Error (GetFrameDirtyRects())."); - break; - } - } - return; - } -} - - int Monitor::GetId() const { return id_; @@ -341,25 +243,29 @@ int Monitor::GetHeight() const int Monitor::GetMoveRectCount() const { - return moveRectSize_ / sizeof(DXGI_OUTDUPL_MOVE_RECT); + const auto& metaData = duplicator_->GetFrame().metaData; + return metaData.moveRectSize / sizeof(DXGI_OUTDUPL_MOVE_RECT); } DXGI_OUTDUPL_MOVE_RECT* Monitor::GetMoveRects() const { - return metaData_.As(); + const auto& metaData = duplicator_->GetFrame().metaData; + return metaData.buffer.As(); } int Monitor::GetDirtyRectCount() const { - return dirtyRectSize_ / sizeof(RECT); + const auto& metaData = duplicator_->GetFrame().metaData; + return metaData.dirtyRectSize / sizeof(RECT); } RECT* Monitor::GetDirtyRects() const { - return metaData_.As(moveRectSize_); + const auto& metaData = duplicator_->GetFrame().metaData; + return metaData.buffer.As(metaData.moveRectSize); } diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h index 5346f0c..99a8cb2 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h @@ -54,9 +54,6 @@ public: private: void UpdateCursor(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); - void UpdateMetadata(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); - void UpdateMoveRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); - void UpdateDirtyRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); void CopyTextureFromGpuToCpu(ID3D11Texture2D* texture); int id_ = -1; @@ -77,8 +74,4 @@ private: ID3D11Texture2D* unityTexture_ = nullptr; Microsoft::WRL::ComPtr textureForGetPixels_; Buffer bufferForGetPixels_; - - Buffer metaData_; - UINT moveRectSize_ = 0; - UINT dirtyRectSize_ = 0; };