fix cursor bugs #11
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include "Cursor.h"
|
||||
#include "Debug.h"
|
||||
@@ -20,11 +19,8 @@ Cursor::~Cursor()
|
||||
}
|
||||
|
||||
|
||||
void Cursor::UpdateBuffer(Duplicator* duplicator)
|
||||
void Cursor::UpdateBuffer(Duplicator* duplicator, const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||
{
|
||||
auto monitor = duplicator->GetMonitor();
|
||||
const auto& frameInfo = duplicator->GetFrame().info;
|
||||
|
||||
if (frameInfo.LastMouseUpdateTime.QuadPart == 0)
|
||||
{
|
||||
return;
|
||||
@@ -66,15 +62,16 @@ void Cursor::UpdateBuffer(Duplicator* duplicator)
|
||||
}
|
||||
|
||||
|
||||
void Cursor::Draw(Duplicator* duplicator)
|
||||
void Cursor::Draw(
|
||||
Duplicator* duplicator,
|
||||
const ComPtr<ID3D11Texture2D>& targetTexture)
|
||||
{
|
||||
auto monitor = duplicator->GetMonitor();
|
||||
const auto& frame = duplicator->GetFrame();
|
||||
|
||||
// Check desktop texure
|
||||
if (frame.texture == nullptr)
|
||||
if (targetTexture == nullptr)
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => texture is null.");
|
||||
Debug::Error("Cursor::UpdateTexture() => target texture is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -233,7 +230,7 @@ void Cursor::Draw(Duplicator* duplicator)
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
duplicator->GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, frame.texture.Get(), 0, &capturedImageArea);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, targetTexture.Get(), 0, &capturedImageArea);
|
||||
}
|
||||
|
||||
// Get mapped surface to access pixels in CPU
|
||||
@@ -364,7 +361,7 @@ void Cursor::Draw(Duplicator* duplicator)
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
duplicator->GetDevice()->GetImmediateContext(&context);
|
||||
context->UpdateSubresource(frame.texture.Get(), 0, &capturedImageArea, bgraBuffer_.Get(), capturedImageWidth * 4, 0);
|
||||
context->UpdateSubresource(targetTexture.Get(), 0, &capturedImageArea, bgraBuffer_.Get(), capturedImageWidth * 4, 0);
|
||||
}
|
||||
|
||||
if (FAILED(surface->Unmap()))
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <wrl/client.h>
|
||||
#include <memory>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
class Duplicator;
|
||||
@@ -12,8 +14,12 @@ class Cursor
|
||||
public:
|
||||
explicit Cursor();
|
||||
~Cursor();
|
||||
void UpdateBuffer(Duplicator* duplicator);
|
||||
void Draw(Duplicator* duplicator);
|
||||
void UpdateBuffer(
|
||||
Duplicator* duplicator,
|
||||
const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
|
||||
void Draw(
|
||||
Duplicator* duplicator,
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& targetTexture);
|
||||
void GetTexture(ID3D11Texture2D* texture);
|
||||
|
||||
bool IsVisible() const;
|
||||
|
||||
@@ -301,60 +301,55 @@ bool Duplicator::Duplicate()
|
||||
device_->GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(copyTarget.Get(), texture.Get());
|
||||
|
||||
UpdateCursor(copyTarget, frameInfo);
|
||||
UpdateMetadata(frameInfo.TotalMetadataBufferSize);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
lastFrame_.texture = copyTarget;
|
||||
lastFrame_.info = frameInfo;
|
||||
lastFrame_.metaData = metaData_;
|
||||
}
|
||||
|
||||
UpdateMetadata();
|
||||
UpdateCursor();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Duplicator::UpdateCursor()
|
||||
void Duplicator::UpdateCursor(
|
||||
const ComPtr<ID3D11Texture2D>& texture,
|
||||
const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||
{
|
||||
auto& manager = GetMonitorManager();
|
||||
if (!manager) return;
|
||||
|
||||
if (lastFrame_.info.PointerPosition.Visible)
|
||||
if (frameInfo.PointerPosition.Visible)
|
||||
{
|
||||
manager->SetCursorMonitorId(monitor_->GetId());
|
||||
}
|
||||
|
||||
if (monitor_->GetId() == manager->GetCursorMonitorId())
|
||||
{
|
||||
auto cursor = GetMonitorManager()->GetCursor();
|
||||
cursor->UpdateBuffer(this);
|
||||
cursor->Draw(this);
|
||||
auto cursor = manager->GetCursor();
|
||||
cursor->UpdateBuffer(this, frameInfo);
|
||||
cursor->Draw(this, texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Duplicator::UpdateMetadata()
|
||||
void Duplicator::UpdateMetadata(UINT totalBufferSize)
|
||||
{
|
||||
metaData_.buffer.ExpandIfNeeded(lastFrame_.info.TotalMetadataBufferSize);
|
||||
metaData_.buffer.ExpandIfNeeded(totalBufferSize);
|
||||
if (!metaData_.buffer.Empty())
|
||||
{
|
||||
UpdateMoveRects();
|
||||
UpdateDirtyRects();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
lastFrame_.metaData = metaData_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Duplicator::UpdateMoveRects()
|
||||
{
|
||||
metaData_.moveRectSize = metaData_.buffer.Size();
|
||||
|
||||
const auto hr = dupl_->GetFrameMoveRects(
|
||||
metaData_.moveRectSize,
|
||||
metaData_.buffer.Size(),
|
||||
metaData_.buffer.As<DXGI_OUTDUPL_MOVE_RECT>(),
|
||||
&metaData_.moveRectSize);
|
||||
|
||||
@@ -395,10 +390,8 @@ void Duplicator::UpdateMoveRects()
|
||||
|
||||
void Duplicator::UpdateDirtyRects()
|
||||
{
|
||||
metaData_.dirtyRectSize = metaData_.buffer.Size() - metaData_.moveRectSize;
|
||||
|
||||
const auto hr = dupl_->GetFrameDirtyRects(
|
||||
metaData_.dirtyRectSize,
|
||||
metaData_.buffer.Size() - metaData_.moveRectSize,
|
||||
metaData_.buffer.As<RECT>(metaData_.moveRectSize /* offset */),
|
||||
&metaData_.dirtyRectSize);
|
||||
|
||||
|
||||
@@ -68,8 +68,10 @@ private:
|
||||
|
||||
bool Duplicate();
|
||||
|
||||
void UpdateCursor();
|
||||
void UpdateMetadata();
|
||||
void UpdateCursor(
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture,
|
||||
const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
|
||||
void UpdateMetadata(UINT totalBufferSize);
|
||||
void UpdateMoveRects();
|
||||
void UpdateDirtyRects();
|
||||
|
||||
|
||||
@@ -59,16 +59,12 @@ void Monitor::Initialize(
|
||||
}
|
||||
|
||||
duplicator_ = std::make_shared<Duplicator>(this);
|
||||
if (duplicator_->GetState() == DuplicatorState::Ready)
|
||||
{
|
||||
duplicator_->Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Monitor::Finalize()
|
||||
{
|
||||
duplicator_->Stop();
|
||||
StopCapture();
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +112,21 @@ void Monitor::Render()
|
||||
}
|
||||
|
||||
|
||||
void Monitor::StartCapture()
|
||||
{
|
||||
if (duplicator_->GetState() == DuplicatorState::Ready)
|
||||
{
|
||||
duplicator_->Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Monitor::StopCapture()
|
||||
{
|
||||
duplicator_->Stop();
|
||||
}
|
||||
|
||||
|
||||
int Monitor::GetId() const
|
||||
{
|
||||
return id_;
|
||||
|
||||
@@ -24,6 +24,8 @@ public:
|
||||
const Microsoft::WRL::ComPtr<struct IDXGIOutput> &output);
|
||||
void Finalize();
|
||||
void Render();
|
||||
void StartCapture();
|
||||
void StopCapture();
|
||||
|
||||
public:
|
||||
int GetId() const;
|
||||
|
||||
@@ -21,7 +21,6 @@ using namespace Microsoft::WRL;
|
||||
MonitorManager::MonitorManager(LUID unityAdapterLuid)
|
||||
: unityAdapterLuid_(unityAdapterLuid)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +54,7 @@ void MonitorManager::Initialize()
|
||||
auto monitor = std::make_shared<Monitor>(id++);
|
||||
const auto unityAdapterLuid = GetUnityAdapterLuid();
|
||||
monitor->Initialize(adapter, output);
|
||||
monitor->StartCapture();
|
||||
monitors_.push_back(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ class MonitorManager
|
||||
public:
|
||||
explicit MonitorManager(LUID unityAdapterLuid_);
|
||||
~MonitorManager();
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
void Reinitialize();
|
||||
void Update();
|
||||
bool HasMonitorCountChanged() const;
|
||||
@@ -24,10 +26,6 @@ public:
|
||||
std::shared_ptr<Monitor> GetMonitor(int id) const;
|
||||
std::shared_ptr<Cursor> GetCursor() const;
|
||||
|
||||
private:
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
|
||||
public:
|
||||
int GetMonitorCount() const;
|
||||
int GetTotalWidth() const;
|
||||
|
||||
@@ -57,12 +57,15 @@ extern "C"
|
||||
dxgiAdapter->GetDesc(&desc);
|
||||
|
||||
g_manager = std::make_unique<MonitorManager>(desc.AdapterLuid);
|
||||
g_manager->Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API Finalize()
|
||||
{
|
||||
if (!g_manager) return;
|
||||
|
||||
g_manager->Finalize();
|
||||
g_manager.reset();
|
||||
|
||||
std::queue<Message> empty;
|
||||
|
||||
Reference in New Issue
Block a user