diff --git a/Assets/uDesktopDuplication/Plugins/uDesktopDuplication.dll b/Assets/uDesktopDuplication/Plugins/uDesktopDuplication.dll index 4bbc507..db746b1 100644 Binary files a/Assets/uDesktopDuplication/Plugins/uDesktopDuplication.dll and b/Assets/uDesktopDuplication/Plugins/uDesktopDuplication.dll differ diff --git a/Assets/uDesktopDuplication/Scripts/Cursor.cs b/Assets/uDesktopDuplication/Scripts/Cursor.cs index 0f7ab83..794aab4 100644 --- a/Assets/uDesktopDuplication/Scripts/Cursor.cs +++ b/Assets/uDesktopDuplication/Scripts/Cursor.cs @@ -54,14 +54,15 @@ public class Cursor : MonoBehaviour } var cursorTexture = textures_[scale]; - monitor.UpdateCursorTexture(cursorTexture.GetNativeTexturePtr()); + monitor.GetCursorTexture(cursorTexture.GetNativeTexturePtr()); uddTexture_.material.SetTexture("_CursorTex", cursorTexture); } void UpdateMaterial() { - var x = (float)monitor.cursorX / monitor.width; - var y = (float)monitor.cursorY / monitor.height; + Debug.Log(monitor.isCursorVisible); + var x = monitor.isCursorVisible ? (float)monitor.cursorX / monitor.width : -9999f; + var y = monitor.isCursorVisible ? (float)monitor.cursorY / monitor.height : -9999f; var w = (float)monitor.cursorShapeWidth / monitor.width; var h = (float)monitor.cursorShapeHeight / monitor.height; uddTexture_.material.SetVector("_CursorPositionScale", new Vector4(x, y, w, h)); diff --git a/Assets/uDesktopDuplication/Scripts/Lib.cs b/Assets/uDesktopDuplication/Scripts/Lib.cs index a628a74..12b23c4 100644 --- a/Assets/uDesktopDuplication/Scripts/Lib.cs +++ b/Assets/uDesktopDuplication/Scripts/Lib.cs @@ -98,7 +98,7 @@ public static class Lib [DllImport("uDesktopDuplication")] public static extern CursorShapeType GetCursorShapeType(int id); [DllImport("uDesktopDuplication")] - public static extern void UpdateCursorTexture(int id, System.IntPtr ptr); + public static extern void GetCursorTexture(int id, System.IntPtr ptr); [DllImport("uDesktopDuplication")] public static extern int SetTexturePtr(int id, IntPtr ptr); diff --git a/Assets/uDesktopDuplication/Scripts/Manager.cs b/Assets/uDesktopDuplication/Scripts/Manager.cs index 5764d03..5093693 100644 --- a/Assets/uDesktopDuplication/Scripts/Manager.cs +++ b/Assets/uDesktopDuplication/Scripts/Manager.cs @@ -12,7 +12,17 @@ public class Manager : MonoBehaviour { get { - if (instance_) return instance_; + if (instance_) { + return instance_; + } + + var manager = FindObjectOfType(); + if (manager) { + manager.Awake(); + instance_ = manager; + return instance_; + } + var go = new GameObject("uDesktopDuplicationManager"); return go.AddComponent(); } @@ -81,12 +91,19 @@ public class Manager : MonoBehaviour UpdateMessage(); } + [ContextMenu("Reinitialize")] + void Reinitialize() + { + Lib.Reinitialize(); + } + void ReinitializeIfNeeded() { for (int i = 0; i < monitors.Count; ++i) { var monitor = monitors[i]; if (monitor.state == MonitorState.AccessLost || - monitor.state == MonitorState.AccessDenied) { + monitor.state == MonitorState.AccessDenied || + monitor.state == MonitorState.SessionDisconnected) { if (!shouldReinitialize) { shouldReinitialize = true; reinitializationTimer = 0f; @@ -97,7 +114,7 @@ public class Manager : MonoBehaviour if (shouldReinitialize) { if (reinitializationTimer > retryReinitializationDuration) { - Lib.Reinitialize(); + Reinitialize(); shouldReinitialize = false; } reinitializationTimer += Time.deltaTime; @@ -110,8 +127,7 @@ public class Manager : MonoBehaviour while (message != Message.None) { switch (message) { case Message.Reinitialized: - Debug.Log("Reinitialize"); - Reinitialize(); + ReinitializeMonitors(); break; default: break; @@ -141,7 +157,7 @@ public class Manager : MonoBehaviour } } - void Reinitialize() + void ReinitializeMonitors() { for (int i = 0; i < monitorCount; ++i) { if (i == monitors.Count) { diff --git a/Assets/uDesktopDuplication/Scripts/Monitor.cs b/Assets/uDesktopDuplication/Scripts/Monitor.cs index b2d2f06..baeea76 100644 --- a/Assets/uDesktopDuplication/Scripts/Monitor.cs +++ b/Assets/uDesktopDuplication/Scripts/Monitor.cs @@ -8,6 +8,27 @@ public class Monitor public Monitor(int id) { this.id = id; + + switch (state) + { + case MonitorState.InvalidArg: + Debug.LogErrorFormat("[{0}:{1}] Invalid.", id, name); + break; + case MonitorState.AccessDenied: + Debug.LogErrorFormat("[{0}:{1}] Access Denied.", id, name); + break; + case MonitorState.Unsupported: + Debug.LogErrorFormat("[{0}:{1}] Unsupported.", id, name); + break; + case MonitorState.SessionDisconnected: + Debug.LogErrorFormat("[{0}:{1}] Disconnected.", id, name); + break; + case MonitorState.NotSet: + Debug.LogErrorFormat("[{0}:{1}] Something wrong.", id, name); + break; + default: + break; + } } public int id @@ -150,9 +171,9 @@ public class Monitor } } - public void UpdateCursorTexture(System.IntPtr ptr) + public void GetCursorTexture(System.IntPtr ptr) { - Lib.UpdateCursorTexture(id, ptr); + Lib.GetCursorTexture(id, ptr); } void CreateTexture() diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp index 0b66378..8cdd4a0 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.cpp @@ -26,54 +26,64 @@ Cursor::~Cursor() } -void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) +void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) { - isVisible_ = frameInfo.PointerPosition.Visible != 0; - x_ = frameInfo.PointerPosition.Position.x; - y_ = frameInfo.PointerPosition.Position.y; + if (frameInfo.LastMouseUpdateTime.QuadPart == 0) + { + return; + } - // TODO: see more information to check where the cursor is. - if (isVisible_) - { - GetMonitorManager()->SetCursorMonitorId(monitor_->GetId()); - } + x_ = frameInfo.PointerPosition.Position.x; + y_ = frameInfo.PointerPosition.Position.y; + if (frameInfo.PointerPosition.Visible != 0) { + GetMonitorManager()->SetCursorMonitorId(monitor_->GetId()); + timestamp_ = frameInfo.LastMouseUpdateTime; + isVisible_ = frameInfo.PointerPosition.Visible != 0; + } - if (GetMonitorManager()->GetCursorMonitorId() != monitor_->GetId()) { - return; - } + if (frameInfo.PointerShapeBufferSize == 0) + { + return; + } - // Increase the buffer size if needed - if (frameInfo.PointerShapeBufferSize > apiBufferSize_) - { - if (apiBuffer_) delete[] apiBuffer_; - apiBuffer_ = new BYTE[frameInfo.PointerShapeBufferSize]; - apiBufferSize_ = frameInfo.PointerShapeBufferSize; - } - if (apiBuffer_ == nullptr) return; + // Increase the buffer size if needed + if (frameInfo.PointerShapeBufferSize > apiBufferSize_) + { + if (apiBuffer_) delete[] apiBuffer_; + apiBuffer_ = new BYTE[frameInfo.PointerShapeBufferSize]; + apiBufferSize_ = frameInfo.PointerShapeBufferSize; + } + if (apiBuffer_ == nullptr) return; - // Get information about the mouse pointer if needed - if (frameInfo.PointerShapeBufferSize != 0) - { - UINT bufferSize; - monitor_->GetDeskDupl()->GetFramePointerShape( - frameInfo.PointerShapeBufferSize, - reinterpret_cast(apiBuffer_), - &bufferSize, - &shapeInfo_); - } + // Get mouse pointer information + UINT bufferSize; + const auto hr = monitor_->GetDeskDupl()->GetFramePointerShape( + frameInfo.PointerShapeBufferSize, + reinterpret_cast(apiBuffer_), + &bufferSize, + &shapeInfo_); + if (FAILED(hr)) + { + delete[] apiBuffer_; + apiBuffer_ = nullptr; + apiBufferSize_ = 0; + } +} + +void Cursor::UpdateTexture() +{ // cursor type - const auto cursorType = shapeInfo_.Type; - const bool isMono = cursorType == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME; - const bool isColorMask = cursorType == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR; + const bool isMono = GetType() == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME; + const bool isColorMask = GetType() == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR; // Size - const auto w = shapeInfo_.Width; - const auto h = shapeInfo_.Height / (isMono ? 2 : 1); - const auto p = shapeInfo_.Pitch; + const auto w = GetWidth(); + const auto h = GetHeight(); + const auto p = GetPitch(); // Convert the buffer given by API into BGRA32 - const auto bgraBufferSize = w * h * 4; + const UINT bgraBufferSize = w * h * 4; if (bgraBufferSize > bgra32BufferSize_) { if (bgra32Buffer_) delete[] bgra32Buffer_; @@ -145,10 +155,10 @@ void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) if (isMono) { - for (UINT row = 0; row < h; ++row) + for (int row = 0; row < h; ++row) { BYTE mask = 0x80; - for (UINT col = 0; col < w; ++col) + for (int col = 0; col < w; ++col) { const int i = row * w + col; const BYTE andMask = apiBuffer_[col / 8 + row * p] & mask; @@ -164,9 +174,9 @@ void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) { const auto buffer32 = reinterpret_cast(apiBuffer_); - for (UINT row = 0; row < h; ++row) + for (int row = 0; row < h; ++row) { - for (UINT col = 0; col < w; ++col) + for (int col = 0; col < w; ++col) { const int i = row * w + col; const int j = row * p / sizeof(UINT) + col; @@ -195,7 +205,7 @@ void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) { auto output32 = reinterpret_cast(bgra32Buffer_); const auto buffer32 = reinterpret_cast(apiBuffer_); - for (UINT i = 0; i < w * h; ++i) + for (int i = 0; i < w * h; ++i) { output32[i] = buffer32[i]; } @@ -205,7 +215,7 @@ void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo) } -void Cursor::UpdateTexture(ID3D11Texture2D* texture) +void Cursor::GetTexture(ID3D11Texture2D* texture) { if (bgra32Buffer_ == nullptr) return; ID3D11DeviceContext* context; diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.h index 37777cc..3ed54bb 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Cursor.h @@ -9,8 +9,9 @@ class Cursor public: explicit Cursor(Monitor* monitor); ~Cursor(); - void Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); - void UpdateTexture(ID3D11Texture2D* texture); + void UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo); + void UpdateTexture(); + void GetTexture(ID3D11Texture2D* texture); bool IsVisible() const; int GetX() const; @@ -30,4 +31,5 @@ private: BYTE* bgra32Buffer_ = nullptr; UINT bgra32BufferSize_ = 0; DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo_; + LARGE_INTEGER timestamp_; }; \ No newline at end of file diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp index 38c6c5a..f7e9360 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.cpp @@ -77,12 +77,20 @@ HRESULT Monitor::Render(UINT timeout) const auto hr = deskDupl_->AcquireNextFrame(timeout, &frameInfo, &resource); if (FAILED(hr)) { - // If any monitor setting has changed (e.g. monitor size has changed), - // it is necessary to re-initialize monitors. - if (hr == DXGI_ERROR_ACCESS_LOST) - { - state_ = State::AccessLost; - } + 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. + state_ = State::AccessLost; + break; + case DXGI_ERROR_WAIT_TIMEOUT: + break; + case DXGI_ERROR_INVALID_CALL: + break; + case E_INVALIDARG: + break; + } return hr; } @@ -94,7 +102,8 @@ HRESULT Monitor::Render(UINT timeout) context->CopyResource(unityTexture_, texture); context->Release(); - cursor_->Update(frameInfo); + cursor_->UpdateBuffer(frameInfo); + cursor_->UpdateTexture(); resource->Release(); deskDupl_->ReleaseFrame(); @@ -139,9 +148,9 @@ const std::unique_ptr& Monitor::GetCursor() } -void Monitor::UpdateCursorTexture(ID3D11Texture2D* texture) +void Monitor::GetCursorTexture(ID3D11Texture2D* texture) { - cursor_->UpdateTexture(texture); + cursor_->GetTexture(texture); } diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h index a7f35c6..6b2e727 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/Monitor.h @@ -25,7 +25,7 @@ public: ~Monitor(); HRESULT Initialize(IDXGIOutput* output); HRESULT Render(UINT timeout = 0); - void UpdateCursorTexture(ID3D11Texture2D* texture); + void GetCursorTexture(ID3D11Texture2D* texture); public: int GetId() const; diff --git a/Plugins/uDesktopDuplication/uDesktopDuplication/main.cpp b/Plugins/uDesktopDuplication/uDesktopDuplication/main.cpp index 4c63e59..6fda3b3 100644 --- a/Plugins/uDesktopDuplication/uDesktopDuplication/main.cpp +++ b/Plugins/uDesktopDuplication/uDesktopDuplication/main.cpp @@ -304,12 +304,12 @@ extern "C" return -1; } - UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API UpdateCursorTexture(int id, ID3D11Texture2D* texture) + UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API GetCursorTexture(int id, ID3D11Texture2D* texture) { if (!g_manager) return; if (auto monitor = g_manager->GetMonitor(id)) { - monitor->UpdateCursorTexture(texture); + monitor->GetCursorTexture(texture); } }