use ComPtr for resources instead of standard smart pointers.
This commit is contained in:
@@ -69,8 +69,6 @@ public class MultipleMonitorCreator : MonoBehaviour
|
||||
{
|
||||
ResetRemoveTimer();
|
||||
|
||||
Debug.Log(uDesktopDuplication.Manager.monitorCount);
|
||||
|
||||
// Create monitors
|
||||
for (int i = 0; i < uDesktopDuplication.Manager.monitorCount; ++i) {
|
||||
// Create monitor obeject
|
||||
|
||||
Binary file not shown.
@@ -13,18 +13,6 @@ struct ID3D11Device;
|
||||
ID3D11Device* GetDevice();
|
||||
|
||||
|
||||
// Utility
|
||||
template <class T>
|
||||
auto MakeUniqueWithReleaser(T* ptr)
|
||||
{
|
||||
const auto deleter = [](T* ptr)
|
||||
{
|
||||
if (ptr != nullptr) ptr->Release();
|
||||
};
|
||||
return std::unique_ptr<T, decltype(deleter)>(ptr, deleter);
|
||||
}
|
||||
|
||||
|
||||
// Manager getter
|
||||
class MonitorManager;
|
||||
const std::unique_ptr<MonitorManager>& GetMonitorManager();
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
#include "Common.h"
|
||||
#include "Debug.h"
|
||||
#include "MonitorManager.h"
|
||||
#include "Monitor.h"
|
||||
#include "Cursor.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
Cursor::Cursor(Monitor* monitor)
|
||||
: monitor_(monitor)
|
||||
@@ -149,9 +152,8 @@ void Cursor::UpdateTexture()
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
ID3D11Texture2D* texture = nullptr;
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
hr = GetDevice()->CreateTexture2D(&desc, nullptr, &texture);
|
||||
const auto textureReleaser = MakeUniqueWithReleaser(texture);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => GetDevice()->CreateTexture2D() failed.");
|
||||
@@ -172,14 +174,14 @@ void Cursor::UpdateTexture()
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture, 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
|
||||
context->Release();
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
|
||||
}
|
||||
|
||||
IDXGISurface* surface = nullptr;
|
||||
hr = texture->QueryInterface(__uuidof(IDXGISurface), (void**)&surface);
|
||||
const auto surfaceReleaser = MakeUniqueWithReleaser(surface);
|
||||
ComPtr<IDXGISurface> surface;
|
||||
hr = texture.As<IDXGISurface>(&surface);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => texture->QueryInterface() failed.");
|
||||
@@ -286,10 +288,9 @@ void Cursor::GetTexture(ID3D11Texture2D* texture)
|
||||
return;
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* context;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->UpdateSubresource(texture, 0, nullptr, bgra32Buffer_.get(), GetWidth() * 4, 0);
|
||||
context->Release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "MonitorManager.h"
|
||||
#include "Monitor.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
Monitor::Monitor(int id)
|
||||
: id_(id)
|
||||
@@ -28,17 +30,14 @@ void Monitor::Initialize(IDXGIOutput* output)
|
||||
GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_);
|
||||
|
||||
auto output1 = reinterpret_cast<IDXGIOutput1*>(output);
|
||||
IDXGIOutputDuplication* deskDupl;
|
||||
const auto hr = output1->DuplicateOutput(GetDevice(), &deskDupl);
|
||||
const auto hr = output1->DuplicateOutput(GetDevice(), &deskDupl_);
|
||||
|
||||
// TODO: error check
|
||||
switch (hr)
|
||||
{
|
||||
case S_OK:
|
||||
state_ = State::Available;
|
||||
deskDupl_ = std::shared_ptr<IDXGIOutputDuplication>(
|
||||
deskDupl,
|
||||
[](IDXGIOutputDuplication* ptr) { if (ptr != nullptr) ptr->Release(); });
|
||||
Debug::Log("Monitor::Initialize() => OK.");
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
state_ = State::InvalidArg;
|
||||
@@ -73,12 +72,11 @@ void Monitor::Render(UINT timeout)
|
||||
{
|
||||
if (!deskDupl_) return;
|
||||
|
||||
IDXGIResource* resource = nullptr;
|
||||
ComPtr<IDXGIResource> resource;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
HRESULT hr;
|
||||
|
||||
hr = deskDupl_->AcquireNextFrame(timeout, &frameInfo, &resource);
|
||||
const auto resourceReleaser = MakeUniqueWithReleaser(resource);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
switch (hr)
|
||||
@@ -107,13 +105,12 @@ void Monitor::Render(UINT timeout)
|
||||
|
||||
if (unityTexture_)
|
||||
{
|
||||
ID3D11Texture2D* texture;
|
||||
resource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&texture));
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
resource.As<ID3D11Texture2D>(&texture);
|
||||
|
||||
ID3D11DeviceContext* context;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(unityTexture_, texture);
|
||||
context->Release();
|
||||
context->CopyResource(unityTexture_, texture.Get());
|
||||
}
|
||||
|
||||
cursor_->UpdateBuffer(frameInfo);
|
||||
@@ -151,7 +148,7 @@ ID3D11Texture2D* Monitor::GetUnityTexture() const
|
||||
}
|
||||
|
||||
|
||||
const std::shared_ptr<IDXGIOutputDuplication>& Monitor::GetDeskDupl()
|
||||
const ComPtr<IDXGIOutputDuplication>& Monitor::GetDeskDupl()
|
||||
{
|
||||
return deskDupl_;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <wrl/client.h>
|
||||
#include <memory>
|
||||
|
||||
class Cursor;
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
int GetRotation() const;
|
||||
int GetDpiX() const;
|
||||
int GetDpiY() const;
|
||||
const std::shared_ptr<IDXGIOutputDuplication>& GetDeskDupl();
|
||||
const Microsoft::WRL::ComPtr<IDXGIOutputDuplication>& GetDeskDupl();
|
||||
const std::unique_ptr<Cursor>& GetCursor();
|
||||
|
||||
private:
|
||||
@@ -53,7 +54,7 @@ private:
|
||||
UINT dpiX_ = -1, dpiY_ = -1;
|
||||
State state_ = State::NotSet;
|
||||
std::unique_ptr<Cursor> cursor_;
|
||||
std::shared_ptr<IDXGIOutputDuplication> deskDupl_;
|
||||
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> deskDupl_;
|
||||
ID3D11Texture2D* unityTexture_ = nullptr;
|
||||
DXGI_OUTPUT_DESC outputDesc_;
|
||||
MONITORINFOEX monitorInfo_;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <wrl/client.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
@@ -12,6 +13,8 @@
|
||||
#include "Cursor.h"
|
||||
#include "MonitorManager.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
MonitorManager::MonitorManager()
|
||||
{
|
||||
@@ -30,23 +33,20 @@ void MonitorManager::Initialize()
|
||||
Finalize();
|
||||
|
||||
// Get factory
|
||||
IDXGIFactory1* factory;
|
||||
CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&factory));
|
||||
const auto factoryReleaser = MakeUniqueWithReleaser(factory);
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
CreateDXGIFactory1(IID_PPV_ARGS(&factory));
|
||||
|
||||
// Check all display adapters
|
||||
int id = 0;
|
||||
IDXGIAdapter1* adapter;
|
||||
ComPtr<IDXGIAdapter1> adapter;
|
||||
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
||||
{
|
||||
const auto adapterReleaser = MakeUniqueWithReleaser(adapter);
|
||||
// Search the main monitor from all outputs
|
||||
IDXGIOutput* output;
|
||||
ComPtr<IDXGIOutput> output;
|
||||
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
||||
{
|
||||
const auto outputReleaser = MakeUniqueWithReleaser(output);
|
||||
auto monitor = std::make_shared<Monitor>(id++);
|
||||
monitor->Initialize(output);
|
||||
monitor->Initialize(output.Get());
|
||||
monitors_.push_back(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user