From 1053b30d7ec0b5d351c3ec692c10b5d4517d24d9 Mon Sep 17 00:00:00 2001 From: hecomi Date: Thu, 5 Jan 2017 12:24:25 +0900 Subject: [PATCH] remove ThreadedDesktopDuplicator.cpp #10 --- .../Plugins/x86_64/uDesktopDuplication.dll | Bin 91648 -> 91136 bytes .../uDesktopDuplication/Monitor.cpp | 475 ++++++++++++++---- .../uDesktopDuplication/Monitor.h | 10 +- .../uDesktopDuplication/MonitorManager.cpp | 8 +- .../ThreadedDesktopDuplicator.cpp | 393 --------------- .../uDesktopDuplication.vcxproj | 1 - .../uDesktopDuplication.vcxproj.filters | 1 - 7 files changed, 396 insertions(+), 492 deletions(-) delete mode 100644 Plugins/uDesktopDuplication/uDesktopDuplication/ThreadedDesktopDuplicator.cpp diff --git a/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll b/Assets/uDesktopDuplication/Plugins/x86_64/uDesktopDuplication.dll index 5b10eb26474987dcb410d41b376b1c6ba6e002ad..19962a124e3614d7e6dde9f79b6ce4688bfbf7e0 100644 GIT binary patch delta 34473 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 delta 34717 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 diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp index 9d92259..cd26c6b 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp @@ -1,13 +1,125 @@ #include #include +#include #include "Debug.h" #include "Cursor.h" #include "MonitorManager.h" #include "Monitor.h" +#pragma comment(lib, "d3d11.lib") + using namespace Microsoft::WRL; +/// +/// Thraed safe self created ID3D11Device from specified adapter +/// +class IsolatedD3D11Device +{ + ComPtr m_device; + ComPtr m_copyTarget; + +public: + ComPtr GetDevice()const { return m_device; } + + bool CreateDevice(const ComPtr &adapter) + { + UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT // D2D Compatible + //| D3D11_CREATE_DEVICE_SINGLETHREADED + //| D3D11_CREATE_DEVICE_VIDEO_SUPPORT // MediaFoundation + ; + + D3D_FEATURE_LEVEL FeatureLevelsRequested[6] = { + D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; + + UINT numLevelsRequested = sizeof(FeatureLevelsRequested) / sizeof(D3D_FEATURE_LEVEL); + D3D_FEATURE_LEVEL FeatureLevelsSupported; + + if (FAILED(D3D11CreateDevice(adapter.Get() + , adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, nullptr + , flags + , FeatureLevelsRequested, numLevelsRequested + , D3D11_SDK_VERSION + , &m_device + , &FeatureLevelsSupported + , nullptr + ))) { + return false; + } + return true; + } + + ComPtr CreateCopyTargetWithSharedFlag(const ComPtr &src) + { + D3D11_TEXTURE2D_DESC desc; + src->GetDesc(&desc); + + if (m_copyTarget) { + D3D11_TEXTURE2D_DESC target_desc; + m_copyTarget->GetDesc(&target_desc); + if ( + target_desc.Format == desc.Format + && target_desc.Width == desc.Width + && target_desc.Height == desc.Height + ) { + // already created + return m_copyTarget; + } + } + + //desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; // for share texture with unity device + + if (FAILED(m_device->CreateTexture2D(&desc, NULL, &m_copyTarget))) + { + return nullptr; + } + return m_copyTarget; + } +}; + + +struct QueueItem +{ + ComPtr Texture; + DXGI_OUTDUPL_FRAME_INFO Info; + + QueueItem() + {} + + QueueItem(const ComPtr &texture + , const DXGI_OUTDUPL_FRAME_INFO &info + ) + : Texture(texture), Info(info) + {} +}; +class TextureQueue +{ + std::queue m_queue; + std::mutex m_mutex; + +public: + void Enqueue(const QueueItem &item) + { + std::lock_guard lk(m_mutex); + m_queue.push(item); + } + + QueueItem Dequeue() + { + std::lock_guard lk(m_mutex); + if (m_queue.empty()) { + return QueueItem(); + } + auto front = m_queue.front(); + m_queue.pop(); + return front; + } +}; + + Monitor::Monitor(int id) : id_(id) { @@ -31,94 +143,127 @@ Monitor::~Monitor() } -void Monitor::Initialize(IDXGIOutput* output) +void Monitor::Initialize( + const ComPtr &adapter, + const ComPtr &output +) { - if (FAILED(output->GetDesc(&outputDesc_))) - { - Debug::Error("Monitor::Initialize() => IDXGIOutput::GetDesc() failed."); - return; - } + m_pIsolated = std::make_shared(); + m_textureQueue = std::make_shared(); - monitorInfo_.cbSize = sizeof(MONITORINFOEX); - if (!GetMonitorInfo(outputDesc_.Monitor, &monitorInfo_)) - { - Debug::Error("Monitor::Initialize() => GetMonitorInfo() failed."); - return; - } - else - { - const auto rect = monitorInfo_.rcMonitor; - width_ = rect.right - rect.left; - height_ = rect.bottom - rect.top; - } + if (!m_pIsolated->CreateDevice(adapter)) { + return; + } - if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_))) - { - Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed."); - // DPI is set as -1, so the application has to use the appropriate value. - } + if (FAILED(output->GetDesc(&outputDesc_))) + { + Debug::Error("Monitor::Initialize() => IDXGIOutput::GetDesc() failed."); + return; + } - auto output1 = reinterpret_cast(output); - switch (output1->DuplicateOutput(GetDevice().Get(), &deskDupl_)) - { - case S_OK: - { - state_ = State::Available; - const auto rot = static_cast(GetRotation()); - Debug::Log("Monitor::Initialize() => OK."); - Debug::Log(" ID : ", GetId()); - Debug::Log(" Size : (", GetWidth(), ", ", GetHeight(), ")"); - Debug::Log(" DPI : (", GetDpiX(), ", ", GetDpiY(), ")"); - Debug::Log(" Rot : ", - rot == DXGI_MODE_ROTATION_IDENTITY ? "Landscape" : - rot == DXGI_MODE_ROTATION_ROTATE90 ? "Portrait" : - rot == DXGI_MODE_ROTATION_ROTATE180 ? "Landscape (flipped)" : - rot == DXGI_MODE_ROTATION_ROTATE270 ? "Portrait (flipped)" : - "Unspecified"); - break; - } - case E_INVALIDARG: - { - state_ = State::InvalidArg; - Debug::Error("Monitor::Initialize() => Invalid arguments."); - break; - } - case E_ACCESSDENIED: - { - // For example, when the user presses Ctrl + Alt + Delete and the screen - // switches to admin screen, this error occurs. - state_ = State::AccessDenied; - Debug::Error("Monitor::Initialize() => Access denied."); - break; - } - case DXGI_ERROR_UNSUPPORTED: - { - // If the display adapter on the computer is running under the Microsoft Hybrid system, - // this error occurs. - state_ = State::Unsupported; - Debug::Error("Monitor::Initialize() => Unsupported display."); - break; - } - case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: - { - // When other application use Desktop Duplication API, this error occurs. - state_ = State::CurrentlyNotAvailable; - Debug::Error("Monitor::Initialize() => Currently not available."); - break; - } - case DXGI_ERROR_SESSION_DISCONNECTED: - { - state_ = State::SessionDisconnected; - Debug::Error("Monitor::Initialize() => Session disconnected."); - break; - } - default: - { - state_ = State::Unknown; - Debug::Error("Monitor::Render() => Unknown Error."); - break; - } - } + monitorInfo_.cbSize = sizeof(MONITORINFOEX); + if (!GetMonitorInfo(outputDesc_.Monitor, &monitorInfo_)) + { + Debug::Error("Monitor::Initialize() => GetMonitorInfo() failed."); + return; + } + else + { + const auto rect = monitorInfo_.rcMonitor; + width_ = rect.right - rect.left; + height_ = rect.bottom - rect.top; + } + + if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_))) + { + Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed."); + // DPI is set as -1, so the application has to use the appropriate value. + } + + ComPtr output1; + if (FAILED(output.As(&output1))) { + return; + } + + // use self created device + auto hr = output1->DuplicateOutput(m_pIsolated->GetDevice().Get(), &deskDupl_); + switch (hr) + { + case S_OK: + { + state_ = State::Available; + const auto rot = static_cast(GetRotation()); + Debug::Log("Monitor::Initialize() => OK."); + Debug::Log(" ID : ", GetId()); + Debug::Log(" Size : (", GetWidth(), ", ", GetHeight(), ")"); + Debug::Log(" DPI : (", GetDpiX(), ", ", GetDpiY(), ")"); + Debug::Log(" Rot : ", + rot == DXGI_MODE_ROTATION_IDENTITY ? "Landscape" : + rot == DXGI_MODE_ROTATION_ROTATE90 ? "Portrait" : + rot == DXGI_MODE_ROTATION_ROTATE180 ? "Landscape (flipped)" : + rot == DXGI_MODE_ROTATION_ROTATE270 ? "Portrait (flipped)" : + "Unspecified"); + break; + } + case E_INVALIDARG: + { + state_ = State::InvalidArg; + Debug::Error("Monitor::Initialize() => Invalid arguments."); + break; + } + case E_ACCESSDENIED: + { + // For example, when the user presses Ctrl + Alt + Delete and the screen + // switches to admin screen, this error occurs. + state_ = State::AccessDenied; + Debug::Error("Monitor::Initialize() => Access denied."); + break; + } + case DXGI_ERROR_UNSUPPORTED: + { + // If the display adapter on the computer is running under the Microsoft Hybrid system, + // this error occurs. + state_ = State::Unsupported; + Debug::Error("Monitor::Initialize() => Unsupported display."); + break; + } + case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: + { + // When other application use Desktop Duplication API, this error occurs. + state_ = State::CurrentlyNotAvailable; + Debug::Error("Monitor::Initialize() => Currently not available."); + break; + } + case DXGI_ERROR_SESSION_DISCONNECTED: + { + state_ = State::SessionDisconnected; + Debug::Error("Monitor::Initialize() => Session disconnected."); + break; + } + default: + { + state_ = State::Unknown; + Debug::Error("Monitor::Render() => Unknown Error."); + break; + } + } + + // check adapter + DXGI_ADAPTER_DESC adapterDesc; + adapter->GetDesc(&adapterDesc); + const auto unityAdapterLuid = GetUnityAdapterLuid(); + const auto isUnityAdapter = + adapterDesc.AdapterLuid.HighPart == unityAdapterLuid.HighPart && + adapterDesc.AdapterLuid.LowPart == unityAdapterLuid.LowPart; + + // start desktop duplication thread + m_stopLoop = false; + if (isUnityAdapter) { + m_desktopDuplicationThread = std::thread(std::bind(&Monitor::DuplicateAndCopyLoop, this)); + } + else { + m_desktopDuplicationThread = std::thread(std::bind(&Monitor::DuplicateAndMapLoop, this)); + } } @@ -249,6 +394,168 @@ void Monitor::Render(UINT timeout) } +void Monitor::CopyTextureFromThread() +{ + QueueItem item; + if (m_textureQueue) { + item=m_textureQueue->Dequeue(); + } + auto texture = item.Texture; + if (!texture) { + return; + } + auto &frameInfo = item.Info; + + // Get texture + if (unityTexture_) + { + D3D11_TEXTURE2D_DESC srcDesc, dstDesc; + texture->GetDesc(&srcDesc); + unityTexture_->GetDesc(&dstDesc); + if (srcDesc.Width != dstDesc.Width || + srcDesc.Height != dstDesc.Height) + { + Debug::Error("Monitor::Render() => Texture sizes are defferent."); + Debug::Error(" Source : (", srcDesc.Width, ", ", srcDesc.Height, ")"); + Debug::Error(" Dest : (", dstDesc.Width, ", ", dstDesc.Height, ")"); + //Debug::Log(" => Try modifying width/height using reported value from DDA."); + //width_ = srcDesc.Width; + //height_ = srcDesc.Height; + state_ = MonitorState::TextureSizeInconsistent; + //SendMessageToUnity(Message::TextureSizeChanged); + } + else + { + ComPtr context; + GetDevice()->GetImmediateContext(&context); + context->CopyResource(unityTexture_, texture.Get()); + } + } + + UpdateMetadata(frameInfo); + + if (frameInfo.PointerPosition.Visible) + { + GetMonitorManager()->SetCursorMonitorId(id_); + } + + if (GetMonitorManager()->GetCursorMonitorId() == id_) + { + UpdateCursor(frameInfo); + } + + if (UseGetPixels()) + { + CopyTextureFromGpuToCpu(texture.Get()); + } + + hasBeenUpdated_ = true; +} + + +void Monitor::DuplicateAndCopyLoop() +{ + if (!deskDupl_) return; + + while (!m_stopLoop) + { + ComPtr resource; + DXGI_OUTDUPL_FRAME_INFO frameInfo; + + const auto hr = deskDupl_->AcquireNextFrame(INFINITE, &frameInfo, &resource); + if (FAILED(hr)) + { + switch (hr) + { + case DXGI_ERROR_ACCESS_LOST: + { + // 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."); + 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."); + break; + } + case DXGI_ERROR_INVALID_CALL: + { + //Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL."); + break; + } + case E_INVALIDARG: + { + //Debug::Error("Monitor::Render() => E_INVALIDARG."); + break; + } + default: + { + state_ = State::Unknown; + //Debug::Error("Monitor::Render() => Unknown Error."); + break; + } + } + continue; + } + + ScopedReleaser releaser([this] + { + const auto hr = deskDupl_->ReleaseFrame(); + if (FAILED(hr)) + { + switch (hr) + { + case DXGI_ERROR_ACCESS_LOST: + { + Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST."); + state_ = State::AccessLost; + break; + } + case DXGI_ERROR_INVALID_CALL: + { + Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL."); + break; + } + default: + { + state_ = State::Unknown; + Debug::Error("Monitor::Render() => Unknown Error."); + break; + } + } + } + }); + + ComPtr texture; + if (FAILED(resource.As(&texture))) { + return; + } + + // copy target + auto copyTarget = m_pIsolated->CreateCopyTargetWithSharedFlag(texture); + if (!copyTarget) { + return; + } + + // copy + ComPtr context; + m_pIsolated->GetDevice()->GetImmediateContext(&context); + context->CopyResource(copyTarget.Get(), texture.Get()); + + m_textureQueue->Enqueue(QueueItem(copyTarget, frameInfo)); + } +} + + +void Monitor::DuplicateAndMapLoop() +{ + // not implemented; +} + + void Monitor::UpdateCursor(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) { auto cursor_ = GetMonitorManager()->GetCursor(); diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h index a6dcd93..f46ee56 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h @@ -31,7 +31,10 @@ public: explicit Monitor(int id); ~Monitor(); - void Initialize(IDXGIOutput* output); + void Initialize( + const Microsoft::WRL::ComPtr &adapter, + const Microsoft::WRL::ComPtr &output); + void CopyTextureFromThread(); void Render(UINT timeout = 0); public: @@ -60,11 +63,6 @@ public: bool UseGetPixels() const; bool GetPixels(BYTE* output, int x, int y, int width, int height); -public: - void InitializeThreaded(const Microsoft::WRL::ComPtr &adapter - , bool isUnityDeviceAdapter - , const Microsoft::WRL::ComPtr &output); - void CopyTextureFromThread(); private: void DuplicateAndCopyLoop(); void DuplicateAndMapLoop(); diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/MonitorManager.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/MonitorManager.cpp index e156008..fac5786 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/MonitorManager.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/MonitorManager.cpp @@ -46,19 +46,13 @@ void MonitorManager::Initialize() ComPtr adapter; for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i) { - DXGI_ADAPTER_DESC desc; - adapter->GetDesc(&desc); - // Search the main monitor from all outputs ComPtr output; for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j) { auto monitor = std::make_shared(id++); const auto unityAdapterLuid = GetUnityAdapterLuid(); - monitor->InitializeThreaded(adapter - , desc.AdapterLuid.HighPart == unityAdapterLuid.HighPart - && desc.AdapterLuid.LowPart == unityAdapterLuid.LowPart - , output); + monitor->Initialize(adapter, output); monitors_.push_back(monitor); } } diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/ThreadedDesktopDuplicator.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/ThreadedDesktopDuplicator.cpp deleted file mode 100644 index da51d2a..0000000 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/ThreadedDesktopDuplicator.cpp +++ /dev/null @@ -1,393 +0,0 @@ -#include "Monitor.h" -#include "MonitorManager.h" -#include "Debug.h" -#include -#include -#pragma comment(lib, "d3d11.lib") - -using namespace Microsoft::WRL; - - -/// -/// Thraed safe self created ID3D11Device from specified adapter -/// -class IsolatedD3D11Device -{ - ComPtr m_device; - ComPtr m_copyTarget; - -public: - ComPtr GetDevice()const { return m_device; } - - bool CreateDevice(const ComPtr &adapter) - { - UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT // D2D Compatible - //| D3D11_CREATE_DEVICE_SINGLETHREADED - //| D3D11_CREATE_DEVICE_VIDEO_SUPPORT // MediaFoundation - ; - - D3D_FEATURE_LEVEL FeatureLevelsRequested[6] = { - D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; - - UINT numLevelsRequested = sizeof(FeatureLevelsRequested) / sizeof(D3D_FEATURE_LEVEL); - D3D_FEATURE_LEVEL FeatureLevelsSupported; - - if (FAILED(D3D11CreateDevice(adapter.Get() - , adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, nullptr - , flags - , FeatureLevelsRequested, numLevelsRequested - , D3D11_SDK_VERSION - , &m_device - , &FeatureLevelsSupported - , nullptr - ))) { - return false; - } - return true; - } - - ComPtr CreateCopyTargetWithSharedFlag(const ComPtr &src) - { - D3D11_TEXTURE2D_DESC desc; - src->GetDesc(&desc); - - if (m_copyTarget) { - D3D11_TEXTURE2D_DESC target_desc; - m_copyTarget->GetDesc(&target_desc); - if ( - target_desc.Format == desc.Format - && target_desc.Width == desc.Width - && target_desc.Height == desc.Height - ) { - // already created - return m_copyTarget; - } - } - - //desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; - desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; // for share texture with unity device - - if (FAILED(m_device->CreateTexture2D(&desc, NULL, &m_copyTarget))) - { - return nullptr; - } - return m_copyTarget; - } -}; - - -struct QueueItem -{ - ComPtr Texture; - DXGI_OUTDUPL_FRAME_INFO Info; - - QueueItem() - {} - - QueueItem(const ComPtr &texture - , const DXGI_OUTDUPL_FRAME_INFO &info - ) - : Texture(texture), Info(info) - {} -}; -class TextureQueue -{ - std::queue m_queue; - std::mutex m_mutex; - -public: - void Enqueue(const QueueItem &item) - { - std::lock_guard lk(m_mutex); - m_queue.push(item); - } - - QueueItem Dequeue() - { - std::lock_guard lk(m_mutex); - if (m_queue.empty()) { - return QueueItem(); - } - auto front = m_queue.front(); - m_queue.pop(); - return front; - } -}; - - -void Monitor::InitializeThreaded( - const ComPtr &adapter - , bool isUnityDeviceAdapter - , const ComPtr &output -) -{ - m_pIsolated = std::make_shared(); - m_textureQueue = std::make_shared(); - - if (!m_pIsolated->CreateDevice(adapter)) { - return; - } - - if (FAILED(output->GetDesc(&outputDesc_))) - { - Debug::Error("Monitor::Initialize() => IDXGIOutput::GetDesc() failed."); - return; - } - - monitorInfo_.cbSize = sizeof(MONITORINFOEX); - if (!GetMonitorInfo(outputDesc_.Monitor, &monitorInfo_)) - { - Debug::Error("Monitor::Initialize() => GetMonitorInfo() failed."); - return; - } - else - { - const auto rect = monitorInfo_.rcMonitor; - width_ = rect.right - rect.left; - height_ = rect.bottom - rect.top; - } - - if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_))) - { - Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed."); - // DPI is set as -1, so the application has to use the appropriate value. - } - - ComPtr output1; - if (FAILED(output.As(&output1))) { - return; - } - - // use self created device - auto hr = output1->DuplicateOutput(m_pIsolated->GetDevice().Get(), &deskDupl_); - switch (hr) - { - case S_OK: - { - state_ = State::Available; - const auto rot = static_cast(GetRotation()); - Debug::Log("Monitor::Initialize() => OK."); - Debug::Log(" ID : ", GetId()); - Debug::Log(" Size : (", GetWidth(), ", ", GetHeight(), ")"); - Debug::Log(" DPI : (", GetDpiX(), ", ", GetDpiY(), ")"); - Debug::Log(" Rot : ", - rot == DXGI_MODE_ROTATION_IDENTITY ? "Landscape" : - rot == DXGI_MODE_ROTATION_ROTATE90 ? "Portrait" : - rot == DXGI_MODE_ROTATION_ROTATE180 ? "Landscape (flipped)" : - rot == DXGI_MODE_ROTATION_ROTATE270 ? "Portrait (flipped)" : - "Unspecified"); - break; - } - case E_INVALIDARG: - { - state_ = State::InvalidArg; - Debug::Error("Monitor::Initialize() => Invalid arguments."); - break; - } - case E_ACCESSDENIED: - { - // For example, when the user presses Ctrl + Alt + Delete and the screen - // switches to admin screen, this error occurs. - state_ = State::AccessDenied; - Debug::Error("Monitor::Initialize() => Access denied."); - break; - } - case DXGI_ERROR_UNSUPPORTED: - { - // If the display adapter on the computer is running under the Microsoft Hybrid system, - // this error occurs. - state_ = State::Unsupported; - Debug::Error("Monitor::Initialize() => Unsupported display."); - break; - } - case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: - { - // When other application use Desktop Duplication API, this error occurs. - state_ = State::CurrentlyNotAvailable; - Debug::Error("Monitor::Initialize() => Currently not available."); - break; - } - case DXGI_ERROR_SESSION_DISCONNECTED: - { - state_ = State::SessionDisconnected; - Debug::Error("Monitor::Initialize() => Session disconnected."); - break; - } - default: - { - state_ = State::Unknown; - Debug::Error("Monitor::Render() => Unknown Error."); - break; - } - } - - // start desktop duplication thread - m_stopLoop = false; - if (isUnityDeviceAdapter) { - m_desktopDuplicationThread = std::thread(std::bind(&Monitor::DuplicateAndCopyLoop, this)); - } - else { - m_desktopDuplicationThread = std::thread(std::bind(&Monitor::DuplicateAndMapLoop, this)); - } -} - -void Monitor::CopyTextureFromThread() -{ - QueueItem item; - if (m_textureQueue) { - item=m_textureQueue->Dequeue(); - } - auto texture = item.Texture; - if (!texture) { - return; - } - auto &frameInfo = item.Info; - - // Get texture - if (unityTexture_) - { - D3D11_TEXTURE2D_DESC srcDesc, dstDesc; - texture->GetDesc(&srcDesc); - unityTexture_->GetDesc(&dstDesc); - if (srcDesc.Width != dstDesc.Width || - srcDesc.Height != dstDesc.Height) - { - Debug::Error("Monitor::Render() => Texture sizes are defferent."); - Debug::Error(" Source : (", srcDesc.Width, ", ", srcDesc.Height, ")"); - Debug::Error(" Dest : (", dstDesc.Width, ", ", dstDesc.Height, ")"); - //Debug::Log(" => Try modifying width/height using reported value from DDA."); - //width_ = srcDesc.Width; - //height_ = srcDesc.Height; - state_ = MonitorState::TextureSizeInconsistent; - //SendMessageToUnity(Message::TextureSizeChanged); - } - else - { - ComPtr context; - GetDevice()->GetImmediateContext(&context); - context->CopyResource(unityTexture_, texture.Get()); - } - } - - UpdateMetadata(frameInfo); - - if (frameInfo.PointerPosition.Visible) - { - GetMonitorManager()->SetCursorMonitorId(id_); - } - - if (GetMonitorManager()->GetCursorMonitorId() == id_) - { - UpdateCursor(frameInfo); - } - - if (UseGetPixels()) - { - CopyTextureFromGpuToCpu(texture.Get()); - } - - hasBeenUpdated_ = true; -} - -void Monitor::DuplicateAndCopyLoop() -{ - if (!deskDupl_)return; - - while (!m_stopLoop) - { - ComPtr resource; - DXGI_OUTDUPL_FRAME_INFO frameInfo; - auto hr = deskDupl_->AcquireNextFrame(INFINITE, &frameInfo, &resource); - - if (FAILED(hr)) { - switch (hr) - { - case DXGI_ERROR_ACCESS_LOST: - { - // 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."); - 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."); - break; - } - case DXGI_ERROR_INVALID_CALL: - { - //Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL."); - break; - } - case E_INVALIDARG: - { - //Debug::Error("Monitor::Render() => E_INVALIDARG."); - break; - } - default: - { - state_ = State::Unknown; - //Debug::Error("Monitor::Render() => Unknown Error."); - break; - } - } - } - else - { - ScopedReleaser releaser([this] - { - const auto hr = deskDupl_->ReleaseFrame(); - if (FAILED(hr)) - { - switch (hr) - { - case DXGI_ERROR_ACCESS_LOST: - { - Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST."); - state_ = State::AccessLost; - break; - } - case DXGI_ERROR_INVALID_CALL: - { - Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL."); - break; - } - default: - { - state_ = State::Unknown; - Debug::Error("Monitor::Render() => Unknown Error."); - break; - } - } - } - }); - - ComPtr texture; - if (FAILED(resource.As(&texture))) { - return; - } - - // copy target - auto copyTarget = m_pIsolated->CreateCopyTargetWithSharedFlag(texture); - if (!copyTarget) { - return; - } - - // copy - ComPtr context; - m_pIsolated->GetDevice()->GetImmediateContext(&context); - context->CopyResource(copyTarget.Get(), texture.Get()); - - m_textureQueue->Enqueue(QueueItem(copyTarget, frameInfo)); - } - } -} - -void Monitor::DuplicateAndMapLoop() -{ - // not implemented; -} diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/uDesktopDuplication.vcxproj b/Plugins/uDesktopDuplication/uDesktopDuplication/uDesktopDuplication.vcxproj index b39a6c5..637e1d4 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/uDesktopDuplication.vcxproj +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/uDesktopDuplication.vcxproj @@ -145,7 +145,6 @@ copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetName).pdb" "$(Soluti - diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/uDesktopDuplication.vcxproj.filters b/Plugins/uDesktopDuplication/uDesktopDuplication/uDesktopDuplication.vcxproj.filters index b584073..48179e2 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/uDesktopDuplication.vcxproj.filters +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/uDesktopDuplication.vcxproj.filters @@ -28,6 +28,5 @@ - \ No newline at end of file