prepare multiple texture buffer for each device to avoid flickering cursor #11
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -14,7 +14,8 @@ using namespace Microsoft::WRL;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
IsolatedD3D11Device::IsolatedD3D11Device()
|
IsolatedD3D11Device::IsolatedD3D11Device(UINT cachedTextureNum)
|
||||||
|
: cachedTextures_(cachedTextureNum)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,33 +65,42 @@ ComPtr<ID3D11Device> IsolatedD3D11Device::GetDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ComPtr<ID3D11Texture2D> IsolatedD3D11Device::GetCompatibleSharedTexture(const ComPtr<ID3D11Texture2D>& src)
|
ComPtr<ID3D11Texture2D> IsolatedD3D11Device::GetCompatibleSharedTexture(
|
||||||
|
const ComPtr<ID3D11Texture2D>& src,
|
||||||
|
UINT index)
|
||||||
{
|
{
|
||||||
|
if (index < 0 || index >= cachedTextures_.size())
|
||||||
|
{
|
||||||
|
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => ", index, " is out of cachedTextures range.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& cachedTexture = cachedTextures_.at(index);
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC srcDesc;
|
D3D11_TEXTURE2D_DESC srcDesc;
|
||||||
src->GetDesc(&srcDesc);
|
src->GetDesc(&srcDesc);
|
||||||
|
|
||||||
// check if the format and size of the current texture are same as the source one
|
// check if the format and size of the current texture are same as the source one
|
||||||
if (cachedTexture_)
|
if (cachedTexture)
|
||||||
{
|
{
|
||||||
D3D11_TEXTURE2D_DESC targetDesc;
|
D3D11_TEXTURE2D_DESC targetDesc;
|
||||||
cachedTexture_->GetDesc(&targetDesc);
|
cachedTexture->GetDesc(&targetDesc);
|
||||||
if (targetDesc.Format == srcDesc.Format &&
|
if (targetDesc.Format == srcDesc.Format &&
|
||||||
targetDesc.Width == srcDesc.Width &&
|
targetDesc.Width == srcDesc.Width &&
|
||||||
targetDesc.Height == srcDesc.Height)
|
targetDesc.Height == srcDesc.Height)
|
||||||
{
|
{
|
||||||
return cachedTexture_;
|
return cachedTexture;
|
||||||
}
|
}
|
||||||
cachedTexture_ = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for sharing this texture with unity device
|
// for sharing this texture with unity device
|
||||||
srcDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
srcDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||||
|
|
||||||
if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &cachedTexture_)))
|
if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &cachedTexture)))
|
||||||
{
|
{
|
||||||
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => Creating shared texture failed.");
|
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => Creating shared texture failed.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedTexture_;
|
return cachedTexture;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
|
|
||||||
@@ -8,15 +9,16 @@
|
|||||||
class IsolatedD3D11Device
|
class IsolatedD3D11Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IsolatedD3D11Device();
|
explicit IsolatedD3D11Device(UINT cachedTextureNum);
|
||||||
~IsolatedD3D11Device();
|
~IsolatedD3D11Device();
|
||||||
|
|
||||||
HRESULT Create(const Microsoft::WRL::ComPtr<IDXGIAdapter>& adapter);
|
HRESULT Create(const Microsoft::WRL::ComPtr<IDXGIAdapter>& adapter);
|
||||||
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
|
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
|
||||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> GetCompatibleSharedTexture(
|
Microsoft::WRL::ComPtr<ID3D11Texture2D> GetCompatibleSharedTexture(
|
||||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src);
|
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src,
|
||||||
|
UINT index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Microsoft::WRL::ComPtr<ID3D11Device> device_;
|
Microsoft::WRL::ComPtr<ID3D11Device> device_;
|
||||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> cachedTexture_;
|
std::vector<Microsoft::WRL::ComPtr<ID3D11Texture2D>> cachedTextures_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ Duplicator::~Duplicator()
|
|||||||
|
|
||||||
void Duplicator::InitializeDevice()
|
void Duplicator::InitializeDevice()
|
||||||
{
|
{
|
||||||
device_ = std::make_shared<IsolatedD3D11Device>();
|
const UINT cachedTextureNum = 2;
|
||||||
|
device_ = std::make_shared<IsolatedD3D11Device>(cachedTextureNum);
|
||||||
|
|
||||||
if (FAILED(device_->Create(monitor_->GetAdapter())))
|
if (FAILED(device_->Create(monitor_->GetAdapter())))
|
||||||
{
|
{
|
||||||
@@ -210,6 +211,17 @@ const Duplicator::Frame& Duplicator::GetLastFrame() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Duplicator::CopyLastTexture(
|
||||||
|
const Microsoft::WRL::ComPtr<ID3D11Device>& device,
|
||||||
|
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
ComPtr<ID3D11DeviceContext> context;
|
||||||
|
device->GetImmediateContext(&context);
|
||||||
|
context->CopyResource(texture.Get(), lastFrame_.texture.Get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Duplicator::Duplicate()
|
bool Duplicator::Duplicate()
|
||||||
{
|
{
|
||||||
if (!dupl_ || !device_) return false;
|
if (!dupl_ || !device_) return false;
|
||||||
@@ -291,22 +303,23 @@ bool Duplicator::Duplicate()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto copyTarget = device_->GetCompatibleSharedTexture(texture);
|
auto sharedTexture = device_->GetCompatibleSharedTexture(texture, frame % 2);
|
||||||
if (!copyTarget)
|
if (!sharedTexture)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ComPtr<ID3D11DeviceContext> context;
|
ComPtr<ID3D11DeviceContext> context;
|
||||||
device_->GetDevice()->GetImmediateContext(&context);
|
device_->GetDevice()->GetImmediateContext(&context);
|
||||||
context->CopyResource(copyTarget.Get(), texture.Get());
|
context->CopyResource(sharedTexture.Get(), texture.Get());
|
||||||
|
|
||||||
UpdateCursor(copyTarget, frameInfo);
|
UpdateCursor(sharedTexture, frameInfo);
|
||||||
UpdateMetadata(frameInfo.TotalMetadataBufferSize);
|
UpdateMetadata(frameInfo.TotalMetadataBufferSize);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
lastFrame_.texture = copyTarget;
|
lastFrame_.frame = frame++;
|
||||||
|
lastFrame_.texture = sharedTexture;
|
||||||
lastFrame_.info = frameInfo;
|
lastFrame_.info = frameInfo;
|
||||||
lastFrame_.metaData = metaData_;
|
lastFrame_.metaData = metaData_;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public:
|
|||||||
|
|
||||||
struct Frame
|
struct Frame
|
||||||
{
|
{
|
||||||
|
UINT frame = 0;
|
||||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
|
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
|
||||||
DXGI_OUTDUPL_FRAME_INFO info;
|
DXGI_OUTDUPL_FRAME_INFO info;
|
||||||
Metadata metaData;
|
Metadata metaData;
|
||||||
@@ -60,6 +61,9 @@ public:
|
|||||||
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
|
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
|
||||||
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> GetDuplication();
|
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> GetDuplication();
|
||||||
const Frame& GetLastFrame() const;
|
const Frame& GetLastFrame() const;
|
||||||
|
void CopyLastTexture(
|
||||||
|
const Microsoft::WRL::ComPtr<ID3D11Device>& device,
|
||||||
|
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitializeDevice();
|
void InitializeDevice();
|
||||||
@@ -81,6 +85,7 @@ private:
|
|||||||
std::shared_ptr<class IsolatedD3D11Device> device_;
|
std::shared_ptr<class IsolatedD3D11Device> device_;
|
||||||
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> dupl_;
|
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> dupl_;
|
||||||
Frame lastFrame_;
|
Frame lastFrame_;
|
||||||
|
UINT frame = 0;
|
||||||
|
|
||||||
volatile bool shouldRun_ = false;
|
volatile bool shouldRun_ = false;
|
||||||
std::thread thread_;
|
std::thread thread_;
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ void Monitor::Finalize()
|
|||||||
void Monitor::Render()
|
void Monitor::Render()
|
||||||
{
|
{
|
||||||
const auto& frame = duplicator_->GetLastFrame();
|
const auto& frame = duplicator_->GetLastFrame();
|
||||||
const auto texture = frame.texture;
|
const auto& texture = frame.texture;
|
||||||
const auto frameInfo = frame.info; // clone
|
|
||||||
|
|
||||||
if (!texture) return;
|
if (!texture) return;
|
||||||
|
|
||||||
@@ -97,9 +96,7 @@ void Monitor::Render()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ComPtr<ID3D11DeviceContext> context;
|
duplicator_->CopyLastTexture(GetDevice(), unityTexture_);
|
||||||
GetDevice()->GetImmediateContext(&context);
|
|
||||||
context->CopyResource(unityTexture_, texture.Get());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user