modify timing to fetch metadata and add it to frame data #10
This commit is contained in:
@@ -54,8 +54,30 @@ template <class T>
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
Buffer() {}
|
||||
~Buffer() {}
|
||||
Buffer()
|
||||
{
|
||||
}
|
||||
|
||||
Buffer<T>& 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)
|
||||
{
|
||||
|
||||
@@ -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<std::mutex> 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<std::mutex> lock(mutex_);
|
||||
lastFrame_.metaData = metaData_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Duplicator::UpdateMoveRects()
|
||||
{
|
||||
metaData_.moveRectSize = metaData_.buffer.Size();
|
||||
|
||||
const auto hr = dupl_->GetFrameMoveRects(
|
||||
metaData_.moveRectSize,
|
||||
metaData_.buffer.As<DXGI_OUTDUPL_MOVE_RECT>(),
|
||||
&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<RECT>(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;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <mutex>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
|
||||
class Monitor;
|
||||
|
||||
@@ -32,10 +34,18 @@ class Duplicator
|
||||
public:
|
||||
using State = DuplicatorState;
|
||||
|
||||
struct Metadata
|
||||
{
|
||||
Buffer<BYTE> buffer;
|
||||
UINT moveRectSize = 0;
|
||||
UINT dirtyRectSize = 0;
|
||||
};
|
||||
|
||||
struct Frame
|
||||
{
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> 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_;
|
||||
};
|
||||
|
||||
@@ -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<DXGI_OUTDUPL_MOVE_RECT>(),
|
||||
&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<RECT>(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<DXGI_OUTDUPL_MOVE_RECT>();
|
||||
const auto& metaData = duplicator_->GetFrame().metaData;
|
||||
return metaData.buffer.As<DXGI_OUTDUPL_MOVE_RECT>();
|
||||
}
|
||||
|
||||
|
||||
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<RECT>(moveRectSize_);
|
||||
const auto& metaData = duplicator_->GetFrame().metaData;
|
||||
return metaData.buffer.As<RECT>(metaData.moveRectSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<ID3D11Texture2D> textureForGetPixels_;
|
||||
Buffer<BYTE> bufferForGetPixels_;
|
||||
|
||||
Buffer<BYTE> metaData_;
|
||||
UINT moveRectSize_ = 0;
|
||||
UINT dirtyRectSize_ = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user