lock shared texture.
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -7,6 +7,7 @@
|
|||||||
#include "IUnityGraphicsD3D11.h"
|
#include "IUnityGraphicsD3D11.h"
|
||||||
#include "Device.h"
|
#include "Device.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
#pragma comment(lib, "d3d11.lib")
|
#pragma comment(lib, "d3d11.lib")
|
||||||
|
|
||||||
@@ -14,9 +15,39 @@ using namespace Microsoft::WRL;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
IsolatedD3D11Device::IsolatedD3D11Device(UINT cachedTextureNum)
|
Microsoft::WRL::ComPtr<ID3D11Texture2D> SharedTextureWrapper::Get()
|
||||||
: cachedTextures_(cachedTextureNum)
|
|
||||||
{
|
{
|
||||||
|
return pointer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SharedTextureWrapper::Lock()
|
||||||
|
{
|
||||||
|
if (locked_) return false;
|
||||||
|
locked_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SharedTextureWrapper::Unlock()
|
||||||
|
{
|
||||||
|
locked_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SharedTextureWrapper::IsLocked() const
|
||||||
|
{
|
||||||
|
return locked_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IsolatedD3D11Device::IsolatedD3D11Device(UINT cachedTextureNum)
|
||||||
|
{
|
||||||
|
for (UINT i = 0; i < cachedTextureNum; ++i)
|
||||||
|
{
|
||||||
|
cachedSharedTextures_.push_back(std::make_shared<SharedTextureWrapper>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -65,42 +96,43 @@ ComPtr<ID3D11Device> IsolatedD3D11Device::GetDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ComPtr<ID3D11Texture2D> IsolatedD3D11Device::GetCompatibleSharedTexture(
|
std::shared_ptr<SharedTextureWrapper> IsolatedD3D11Device::GetCompatibleSharedTexture(
|
||||||
const ComPtr<ID3D11Texture2D>& src,
|
const ComPtr<ID3D11Texture2D>& src,
|
||||||
UINT index)
|
UINT index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= cachedTextures_.size())
|
if (index < 0 || index >= cachedSharedTextures_.size())
|
||||||
{
|
{
|
||||||
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => ", index, " is out of cachedTextures range.");
|
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => ", index, " is out of cachedTextures range.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& cachedTexture = cachedTextures_.at(index);
|
auto& sharedTextureWrapper = cachedSharedTextures_.at(index);
|
||||||
|
auto& texture = sharedTextureWrapper->pointer_;
|
||||||
|
|
||||||
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 (texture)
|
||||||
{
|
{
|
||||||
D3D11_TEXTURE2D_DESC targetDesc;
|
D3D11_TEXTURE2D_DESC targetDesc;
|
||||||
cachedTexture->GetDesc(&targetDesc);
|
texture->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 sharedTextureWrapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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, &texture)))
|
||||||
{
|
{
|
||||||
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => Creating shared texture failed.");
|
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => Creating shared texture failed.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedTexture;
|
return sharedTextureWrapper;
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Shared texture wrapper to manager locking state
|
||||||
|
class SharedTextureWrapper
|
||||||
|
{
|
||||||
|
friend class IsolatedD3D11Device;
|
||||||
|
public:
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11Texture2D> Get();
|
||||||
|
bool Lock();
|
||||||
|
void Unlock();
|
||||||
|
bool IsLocked() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic<bool> locked_ = false;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11Texture2D> pointer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Thraed safe self created ID3D11Device from specified adapter
|
// Thraed safe self created ID3D11Device from specified adapter
|
||||||
class IsolatedD3D11Device
|
class IsolatedD3D11Device
|
||||||
{
|
{
|
||||||
@@ -14,11 +32,11 @@ public:
|
|||||||
|
|
||||||
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(
|
std::shared_ptr<SharedTextureWrapper> GetCompatibleSharedTexture(
|
||||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src,
|
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src,
|
||||||
UINT index);
|
UINT index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Microsoft::WRL::ComPtr<ID3D11Device> device_;
|
Microsoft::WRL::ComPtr<ID3D11Device> device_;
|
||||||
std::vector<Microsoft::WRL::ComPtr<ID3D11Texture2D>> cachedTextures_;
|
std::vector<std::shared_ptr<SharedTextureWrapper>> cachedSharedTextures_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -315,13 +315,16 @@ void Duplicator::Duplicate(UINT timeout)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sharedTexture = device_->GetCompatibleSharedTexture(texture, lastFrameId_ % 2);
|
auto sharedTextureWrapper = device_->GetCompatibleSharedTexture(texture, 0);
|
||||||
if (!sharedTexture)
|
if (!sharedTextureWrapper)
|
||||||
{
|
{
|
||||||
Debug::Error("Duplicator::Duplicate() => Shared Texture was null.");
|
Debug::Error("Duplicator::Duplicate() => Shared Texture was null.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sharedTextureWrapper->IsLocked()) return;
|
||||||
|
auto sharedTexture = sharedTextureWrapper->Get();
|
||||||
|
|
||||||
ComPtr<ID3D11DeviceContext> context;
|
ComPtr<ID3D11DeviceContext> context;
|
||||||
device_->GetDevice()->GetImmediateContext(&context);
|
device_->GetDevice()->GetImmediateContext(&context);
|
||||||
context->CopyResource(sharedTexture.Get(), texture.Get());
|
context->CopyResource(sharedTexture.Get(), texture.Get());
|
||||||
@@ -334,7 +337,7 @@ void Duplicator::Duplicate(UINT timeout)
|
|||||||
lastFrame_ = Frame
|
lastFrame_ = Frame
|
||||||
{
|
{
|
||||||
lastFrameId_++,
|
lastFrameId_++,
|
||||||
sharedTexture,
|
sharedTextureWrapper,
|
||||||
frameInfo,
|
frameInfo,
|
||||||
metaData_
|
metaData_
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
struct Frame
|
struct Frame
|
||||||
{
|
{
|
||||||
UINT id;
|
UINT id;
|
||||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
|
std::shared_ptr<class SharedTextureWrapper> texture;
|
||||||
DXGI_OUTDUPL_FRAME_INFO info;
|
DXGI_OUTDUPL_FRAME_INFO info;
|
||||||
Metadata metaData;
|
Metadata metaData;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -75,10 +75,13 @@ void Monitor::Render()
|
|||||||
if (frame.id == lastFrameId_) return;
|
if (frame.id == lastFrameId_) return;
|
||||||
lastFrameId_ = frame.id;
|
lastFrameId_ = frame.id;
|
||||||
|
|
||||||
const auto& texture = frame.texture;
|
const auto& sharedTextureWrapper = frame.texture;
|
||||||
if (!texture) return;
|
if (!sharedTextureWrapper->Lock()) return;
|
||||||
|
ScopedReleaser releaser([&] { sharedTextureWrapper->Unlock(); });
|
||||||
|
|
||||||
|
auto texture = sharedTextureWrapper->Get();
|
||||||
|
if (!texture) return;
|
||||||
|
|
||||||
// Get texture
|
|
||||||
if (unityTexture_)
|
if (unityTexture_)
|
||||||
{
|
{
|
||||||
D3D11_TEXTURE2D_DESC srcDesc, dstDesc;
|
D3D11_TEXTURE2D_DESC srcDesc, dstDesc;
|
||||||
|
|||||||
Reference in New Issue
Block a user