lock shared texture.

This commit is contained in:
hecomi
2017-01-07 15:28:13 +09:00
parent c41fe42aa3
commit 10091be4b3
7 changed files with 75 additions and 19 deletions
@@ -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;