fix crash bugs and memory leaks.
This commit is contained in:
@@ -21,7 +21,7 @@ public class Loupe : MonoBehaviour
|
|||||||
|
|
||||||
// To get other monitor textures, set dirty flag.
|
// To get other monitor textures, set dirty flag.
|
||||||
foreach (var target in uDesktopDuplication.Manager.monitors) {
|
foreach (var target in uDesktopDuplication.Manager.monitors) {
|
||||||
target.CreateTexture();
|
target.CreateTextureIfNeeded();
|
||||||
target.shouldBeUpdated = true;
|
target.shouldBeUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class MultipleMonitorCreator : MonoBehaviour
|
|||||||
go.name = "Monitor " + i;
|
go.name = "Monitor " + i;
|
||||||
|
|
||||||
// Expand AABB
|
// Expand AABB
|
||||||
var mesh = go.GetComponent<MeshFilter>().mesh; // clone
|
var mesh = go.GetComponent<MeshFilter>().sharedMesh;
|
||||||
var aabbScale = mesh.bounds.size;
|
var aabbScale = mesh.bounds.size;
|
||||||
aabbScale.y = Mathf.Max(aabbScale.y, aabbScale.x);
|
aabbScale.y = Mathf.Max(aabbScale.y, aabbScale.x);
|
||||||
aabbScale.z = Mathf.Max(aabbScale.z, aabbScale.x);
|
aabbScale.z = Mathf.Max(aabbScale.z, aabbScale.x);
|
||||||
|
|||||||
Binary file not shown.
@@ -78,6 +78,8 @@ public static class Lib
|
|||||||
[DllImport("uDesktopDuplication")]
|
[DllImport("uDesktopDuplication")]
|
||||||
public static extern int GetMonitorCount();
|
public static extern int GetMonitorCount();
|
||||||
[DllImport("uDesktopDuplication")]
|
[DllImport("uDesktopDuplication")]
|
||||||
|
public static extern bool HasMonitorCountChanged();
|
||||||
|
[DllImport("uDesktopDuplication")]
|
||||||
public static extern int GetCursorMonitorId();
|
public static extern int GetCursorMonitorId();
|
||||||
[DllImport("uDesktopDuplication")]
|
[DllImport("uDesktopDuplication")]
|
||||||
public static extern int GetTotalWidth();
|
public static extern int GetTotalWidth();
|
||||||
|
|||||||
@@ -13,6 +13,19 @@ public class Manager : MonoBehaviour
|
|||||||
get { return CreateInstance(); }
|
get { return CreateInstance(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Manager CreateInstance()
|
||||||
|
{
|
||||||
|
if (instance_) {
|
||||||
|
return instance_;
|
||||||
|
}
|
||||||
|
|
||||||
|
var manager = FindObjectOfType<Manager>();
|
||||||
|
if (manager) return manager;
|
||||||
|
|
||||||
|
var go = new GameObject("uDesktopDuplicationManager");
|
||||||
|
return go.AddComponent<Manager>();
|
||||||
|
}
|
||||||
|
|
||||||
private List<Monitor> monitors_ = new List<Monitor>();
|
private List<Monitor> monitors_ = new List<Monitor>();
|
||||||
static public List<Monitor> monitors
|
static public List<Monitor> monitors
|
||||||
{
|
{
|
||||||
@@ -48,22 +61,6 @@ public class Manager : MonoBehaviour
|
|||||||
public delegate void ReinitializeHandler();
|
public delegate void ReinitializeHandler();
|
||||||
public static event ReinitializeHandler onReinitialized;
|
public static event ReinitializeHandler onReinitialized;
|
||||||
|
|
||||||
public static Manager CreateInstance()
|
|
||||||
{
|
|
||||||
if (instance_) {
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
var manager = FindObjectOfType<Manager>();
|
|
||||||
if (manager) {
|
|
||||||
manager.Awake();
|
|
||||||
return manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
var go = new GameObject("uDesktopDuplicationManager");
|
|
||||||
return go.AddComponent<Manager>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Monitor GetMonitor(int id)
|
public static Monitor GetMonitor(int id)
|
||||||
{
|
{
|
||||||
if (id < 0 || id >= Manager.monitors.Count) {
|
if (id < 0 || id >= Manager.monitors.Count) {
|
||||||
@@ -77,18 +74,21 @@ public class Manager : MonoBehaviour
|
|||||||
{
|
{
|
||||||
Lib.SetDebugMode(debugMode);
|
Lib.SetDebugMode(debugMode);
|
||||||
Lib.InitializeUDD();
|
Lib.InitializeUDD();
|
||||||
|
Lib.SetTimeout(desktopDuplicationApiTimeout);
|
||||||
|
|
||||||
if (instance_ != null) return;
|
if (instance_ != null) {
|
||||||
|
Destroy(gameObject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
instance_ = this;
|
instance_ = this;
|
||||||
|
|
||||||
CreateMonitors();
|
CreateMonitors();
|
||||||
|
|
||||||
Lib.SetTimeout(desktopDuplicationApiTimeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnApplicationQuit()
|
void OnApplicationQuit()
|
||||||
{
|
{
|
||||||
Lib.FinalizeUDD();
|
Lib.FinalizeUDD();
|
||||||
|
DestroyMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEnable()
|
void OnEnable()
|
||||||
@@ -124,20 +124,30 @@ public class Manager : MonoBehaviour
|
|||||||
|
|
||||||
void ReinitializeIfNeeded()
|
void ReinitializeIfNeeded()
|
||||||
{
|
{
|
||||||
|
bool reinitializeNeeded = false;
|
||||||
|
|
||||||
for (int i = 0; i < monitors.Count; ++i) {
|
for (int i = 0; i < monitors.Count; ++i) {
|
||||||
var monitor = monitors[i];
|
var monitor = monitors[i];
|
||||||
if (monitor.state == MonitorState.NotSet ||
|
if (
|
||||||
|
monitor.state == MonitorState.NotSet ||
|
||||||
monitor.state == MonitorState.AccessLost ||
|
monitor.state == MonitorState.AccessLost ||
|
||||||
monitor.state == MonitorState.AccessDenied ||
|
monitor.state == MonitorState.AccessDenied ||
|
||||||
monitor.state == MonitorState.SessionDisconnected) {
|
monitor.state == MonitorState.SessionDisconnected
|
||||||
if (!shouldReinitialize_) {
|
) {
|
||||||
shouldReinitialize_ = true;
|
reinitializeNeeded = true;
|
||||||
reinitializationTimer_ = 0f;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Lib.HasMonitorCountChanged()) {
|
||||||
|
reinitializeNeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shouldReinitialize_ && reinitializeNeeded) {
|
||||||
|
shouldReinitialize_ = true;
|
||||||
|
reinitializationTimer_ = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldReinitialize_) {
|
if (shouldReinitialize_) {
|
||||||
if (reinitializationTimer_ > retryReinitializationDuration) {
|
if (reinitializationTimer_ > retryReinitializationDuration) {
|
||||||
Reinitialize();
|
Reinitialize();
|
||||||
@@ -182,12 +192,20 @@ public class Manager : MonoBehaviour
|
|||||||
|
|
||||||
void CreateMonitors()
|
void CreateMonitors()
|
||||||
{
|
{
|
||||||
monitors.Clear();
|
DestroyMonitors();
|
||||||
for (int i = 0; i < monitorCount; ++i) {
|
for (int i = 0; i < monitorCount; ++i) {
|
||||||
monitors.Add(new Monitor(i));
|
monitors.Add(new Monitor(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DestroyMonitors()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < monitors.Count; ++i) {
|
||||||
|
monitors[i].DestroyTexture();
|
||||||
|
}
|
||||||
|
monitors.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ReinitializeMonitors()
|
void ReinitializeMonitors()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < monitorCount; ++i) {
|
for (int i = 0; i < monitorCount; ++i) {
|
||||||
@@ -202,7 +220,7 @@ public class Manager : MonoBehaviour
|
|||||||
void RecreateTextures()
|
void RecreateTextures()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < monitorCount; ++i) {
|
for (int i = 0; i < monitorCount; ++i) {
|
||||||
monitors[i].CreateTexture();
|
monitors[i].CreateTextureIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ public class Monitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Monitor()
|
||||||
|
{
|
||||||
|
DestroyTexture();
|
||||||
|
}
|
||||||
|
|
||||||
public int id
|
public int id
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -203,21 +208,24 @@ public class Monitor
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Texture2D errorTexture;
|
private static Texture2D errorTexture_;
|
||||||
private static readonly string errorTexturePath = "uDesktopDuplication/Textures/NotAvailable";
|
private static readonly string errorTexturePath = "uDesktopDuplication/Textures/NotAvailable";
|
||||||
|
private Texture2D errorTexture
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return errorTexture_ ??
|
||||||
|
(errorTexture_ = Resources.Load<Texture2D>(errorTexturePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Texture2D texture_;
|
private Texture2D texture_;
|
||||||
public Texture2D texture
|
public Texture2D texture
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!available) {
|
if (!available) return errorTexture;
|
||||||
return errorTexture ??
|
if (texture_ == null) CreateTextureIfNeeded();
|
||||||
(errorTexture = Resources.Load<Texture2D>(errorTexturePath));
|
|
||||||
}
|
|
||||||
if (texture_ == null) {
|
|
||||||
CreateTexture();
|
|
||||||
}
|
|
||||||
return texture_;
|
return texture_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +243,7 @@ public class Monitor
|
|||||||
Lib.GetCursorTexture(id, ptr);
|
Lib.GetCursorTexture(id, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateTexture()
|
public void CreateTextureIfNeeded()
|
||||||
{
|
{
|
||||||
if (!available) return;
|
if (!available) return;
|
||||||
|
|
||||||
@@ -243,13 +251,8 @@ public class Monitor
|
|||||||
var h = isHorizontal ? height : width;
|
var h = isHorizontal ? height : width;
|
||||||
bool shouldCreate = true;
|
bool shouldCreate = true;
|
||||||
|
|
||||||
if (texture_) {
|
if (texture_ && texture_.width == w && texture_.height == h) {
|
||||||
if (texture_.width != w || texture_.height != h) {
|
shouldCreate = false;
|
||||||
Object.DestroyImmediate(texture_);
|
|
||||||
texture_ = null;
|
|
||||||
} else {
|
|
||||||
shouldCreate = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w <= 0 || h <= 0) {
|
if (w <= 0 || h <= 0) {
|
||||||
@@ -257,13 +260,29 @@ public class Monitor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shouldCreate) {
|
if (shouldCreate) {
|
||||||
texture_ = new Texture2D(w, h, TextureFormat.BGRA32, false);
|
CreateTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateTexture()
|
||||||
|
{
|
||||||
|
DestroyTexture();
|
||||||
|
var w = isHorizontal ? width : height;
|
||||||
|
var h = isHorizontal ? height : width;
|
||||||
|
texture_ = new Texture2D(w, h, TextureFormat.BGRA32, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DestroyTexture()
|
||||||
|
{
|
||||||
|
if (texture_) {
|
||||||
|
Object.Destroy(texture_);
|
||||||
|
texture_ = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reinitialize()
|
public void Reinitialize()
|
||||||
{
|
{
|
||||||
CreateTexture();
|
CreateTextureIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,11 @@ public class Texture : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnDisable()
|
||||||
|
{
|
||||||
|
Destroy(material);
|
||||||
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
monitor.shouldBeUpdated = true;
|
monitor.shouldBeUpdated = true;
|
||||||
|
|||||||
@@ -53,16 +53,21 @@ void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
|||||||
apiBufferSize_ = frameInfo.PointerShapeBufferSize;
|
apiBufferSize_ = frameInfo.PointerShapeBufferSize;
|
||||||
apiBuffer_ = std::make_unique<BYTE[]>(apiBufferSize_);
|
apiBuffer_ = std::make_unique<BYTE[]>(apiBufferSize_);
|
||||||
}
|
}
|
||||||
if (!apiBuffer_) return;
|
|
||||||
|
if (!apiBuffer_)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get mouse pointer information
|
// Get mouse pointer information
|
||||||
UINT bufferSize;
|
UINT bufferSize;
|
||||||
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo;
|
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo;
|
||||||
const auto hr = monitor_->GetDeskDupl()->GetFramePointerShape(
|
const auto hr = monitor_->GetDeskDupl()->GetFramePointerShape(
|
||||||
apiBufferSize_,
|
apiBufferSize_,
|
||||||
reinterpret_cast<void*>(apiBuffer_.get()),
|
apiBuffer_.get(),
|
||||||
&bufferSize,
|
&bufferSize,
|
||||||
&shapeInfo);
|
&shapeInfo);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
Debug::Error("Cursor::UpdateBuffer() => GetFramePointerShape() failed.");
|
Debug::Error("Cursor::UpdateBuffer() => GetFramePointerShape() failed.");
|
||||||
@@ -149,13 +154,12 @@ void Cursor::UpdateTexture()
|
|||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
desc.MiscFlags = 0;
|
desc.MiscFlags = 0;
|
||||||
|
|
||||||
ID3D11Texture2D* texture;
|
ComPtr<ID3D11Texture2D> texture;
|
||||||
if (FAILED(GetDevice()->CreateTexture2D(&desc, nullptr, &texture)))
|
if (FAILED(GetDevice()->CreateTexture2D(&desc, nullptr, &texture)))
|
||||||
{
|
{
|
||||||
Debug::Error("Cursor::UpdateTexture() => GetDevice()->CreateTexture2D() failed.");
|
Debug::Error("Cursor::UpdateTexture() => GetDevice()->CreateTexture2D() failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto textureReleaser = MakeUniqueWithReleaser(texture);
|
|
||||||
|
|
||||||
D3D11_BOX box;
|
D3D11_BOX box;
|
||||||
box.front = 0;
|
box.front = 0;
|
||||||
@@ -171,18 +175,18 @@ void Cursor::UpdateTexture()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11DeviceContext* context;
|
{
|
||||||
GetDevice()->GetImmediateContext(&context);
|
ComPtr<ID3D11DeviceContext> context;
|
||||||
context->CopySubresourceRegion(texture, 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
|
GetDevice()->GetImmediateContext(&context);
|
||||||
context->Release();
|
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
|
||||||
|
}
|
||||||
|
|
||||||
IDXGISurface* surface;
|
ComPtr<IDXGISurface> surface;
|
||||||
if (FAILED(texture->QueryInterface<IDXGISurface>(&surface)))
|
if (FAILED(texture.As(&surface)))
|
||||||
{
|
{
|
||||||
Debug::Error("Cursor::UpdateTexture() => texture->QueryInterface() failed.");
|
Debug::Error("Cursor::UpdateTexture() => texture->QueryInterface() failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto surfaceReleaser = MakeUniqueWithReleaser(surface);
|
|
||||||
|
|
||||||
DXGI_MAPPED_RECT mappedSurface;
|
DXGI_MAPPED_RECT mappedSurface;
|
||||||
if (FAILED(surface->Map(&mappedSurface, DXGI_MAP_READ)))
|
if (FAILED(surface->Map(&mappedSurface, DXGI_MAP_READ)))
|
||||||
@@ -282,10 +286,9 @@ void Cursor::GetTexture(ID3D11Texture2D* texture)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11DeviceContext* context;
|
ComPtr<ID3D11DeviceContext> context;
|
||||||
GetDevice()->GetImmediateContext(&context);
|
GetDevice()->GetImmediateContext(&context);
|
||||||
context->UpdateSubresource(texture, 0, nullptr, bgra32Buffer_.get(), GetWidth() * 4, 0);
|
context->UpdateSubresource(texture, 0, nullptr, bgra32Buffer_.get(), GetWidth() * 4, 0);
|
||||||
context->Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ Monitor::~Monitor()
|
|||||||
if (deskDupl_)
|
if (deskDupl_)
|
||||||
{
|
{
|
||||||
deskDupl_->Release();
|
deskDupl_->Release();
|
||||||
|
deskDupl_ = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +114,7 @@ void Monitor::Render(UINT timeout)
|
|||||||
{
|
{
|
||||||
if (!deskDupl_) return;
|
if (!deskDupl_) return;
|
||||||
|
|
||||||
IDXGIResource* resource;
|
ComPtr<IDXGIResource> resource;
|
||||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||||
|
|
||||||
const auto hr = deskDupl_->AcquireNextFrame(timeout, &frameInfo, &resource);
|
const auto hr = deskDupl_->AcquireNextFrame(timeout, &frameInfo, &resource);
|
||||||
@@ -181,10 +182,9 @@ void Monitor::Render(UINT timeout)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ID3D11DeviceContext* context;
|
ComPtr<ID3D11DeviceContext> context;
|
||||||
GetDevice()->GetImmediateContext(&context);
|
GetDevice()->GetImmediateContext(&context);
|
||||||
context->CopyResource(unityTexture_, texture);
|
context->CopyResource(unityTexture_, texture);
|
||||||
context->Release();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,8 @@ void MonitorManager::Initialize()
|
|||||||
{
|
{
|
||||||
Finalize();
|
Finalize();
|
||||||
|
|
||||||
ComPtr<IDXGIFactory1> factory;
|
|
||||||
ComPtr<IDXGIAdapter1> adapter;
|
|
||||||
ComPtr<IDXGIOutput> output;
|
|
||||||
|
|
||||||
// Get factory
|
// Get factory
|
||||||
|
ComPtr<IDXGIFactory1> factory;
|
||||||
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
||||||
{
|
{
|
||||||
Debug::Error("MonitorManager::Initialize() => CreateDXGIFactory1() failed.");
|
Debug::Error("MonitorManager::Initialize() => CreateDXGIFactory1() failed.");
|
||||||
@@ -46,9 +43,11 @@ void MonitorManager::Initialize()
|
|||||||
|
|
||||||
// Check all display adapters
|
// Check all display adapters
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
ComPtr<IDXGIAdapter1> adapter;
|
||||||
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
||||||
{
|
{
|
||||||
// Search the main monitor from all outputs
|
// Search the main monitor from all outputs
|
||||||
|
ComPtr<IDXGIOutput> output;
|
||||||
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
||||||
{
|
{
|
||||||
auto monitor = std::make_shared<Monitor>(id++);
|
auto monitor = std::make_shared<Monitor>(id++);
|
||||||
@@ -79,31 +78,27 @@ void MonitorManager::Reinitialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MonitorManager::CheckMonitorNumbers()
|
bool MonitorManager::HasMonitorCountChanged() const
|
||||||
{
|
{
|
||||||
ComPtr<IDXGIFactory1> factory;
|
ComPtr<IDXGIFactory1> factory;
|
||||||
ComPtr<IDXGIAdapter1> adapter;
|
|
||||||
ComPtr<IDXGIOutput> output;
|
|
||||||
|
|
||||||
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
|
||||||
{
|
{
|
||||||
Debug::Error("MonitorManager::CheckMonitorNumbers() => CreateDXGIFactory1() failed.");
|
Debug::Error("MonitorManager::CheckMonitorConnection() => CreateDXGIFactory1() failed.");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
ComPtr<IDXGIAdapter1> adapter;
|
||||||
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
|
||||||
{
|
{
|
||||||
|
ComPtr<IDXGIOutput> output;
|
||||||
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
|
||||||
{
|
{
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetMonitorCount() != id)
|
return monitors_.size() != id;
|
||||||
{
|
|
||||||
RequireReinitilization();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -119,8 +114,6 @@ std::shared_ptr<Monitor> MonitorManager::GetMonitor(int id) const
|
|||||||
|
|
||||||
void MonitorManager::Update()
|
void MonitorManager::Update()
|
||||||
{
|
{
|
||||||
CheckMonitorNumbers();
|
|
||||||
|
|
||||||
if (isReinitializationRequired_)
|
if (isReinitializationRequired_)
|
||||||
{
|
{
|
||||||
Reinitialize();
|
Reinitialize();
|
||||||
@@ -146,6 +139,7 @@ int MonitorManager::GetMonitorCount() const
|
|||||||
return static_cast<int>(monitors_.size());
|
return static_cast<int>(monitors_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int MonitorManager::GetTotalWidth() const
|
int MonitorManager::GetTotalWidth() const
|
||||||
{
|
{
|
||||||
std::vector<int> lefts, rights;
|
std::vector<int> lefts, rights;
|
||||||
@@ -159,6 +153,7 @@ int MonitorManager::GetTotalWidth() const
|
|||||||
return maxRight - minLeft;
|
return maxRight - minLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int MonitorManager::GetTotalHeight() const
|
int MonitorManager::GetTotalHeight() const
|
||||||
{
|
{
|
||||||
std::vector<int> tops, bottoms;
|
std::vector<int> tops, bottoms;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public:
|
|||||||
explicit MonitorManager();
|
explicit MonitorManager();
|
||||||
~MonitorManager();
|
~MonitorManager();
|
||||||
void Reinitialize();
|
void Reinitialize();
|
||||||
void CheckMonitorNumbers();
|
bool HasMonitorCountChanged() const;
|
||||||
void RequireReinitilization();
|
void RequireReinitilization();
|
||||||
void SetCursorMonitorId(int id) { cursorMonitorId_ = id; }
|
void SetCursorMonitorId(int id) { cursorMonitorId_ = id; }
|
||||||
int GetCursorMonitorId() const { return cursorMonitorId_; }
|
int GetCursorMonitorId() const { return cursorMonitorId_; }
|
||||||
|
|||||||
@@ -115,6 +115,12 @@ extern "C"
|
|||||||
return g_manager->GetMonitorCount();
|
return g_manager->GetMonitorCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API HasMonitorCountChanged()
|
||||||
|
{
|
||||||
|
if (!g_manager) return false;
|
||||||
|
return g_manager->HasMonitorCountChanged();
|
||||||
|
}
|
||||||
|
|
||||||
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorMonitorId()
|
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetCursorMonitorId()
|
||||||
{
|
{
|
||||||
if (!g_manager) return -1;
|
if (!g_manager) return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user