fix cursor bugs #11

This commit is contained in:
hecomi
2017-01-06 13:52:23 +09:00
parent 29920b6b94
commit 12726d85dc
11 changed files with 59 additions and 47 deletions
@@ -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;