implement dirty rects and move rects.
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aac40d1b58f3f8940be815779d89b5a4
|
||||||
|
timeCreated: 1479544409
|
||||||
|
licenseType: Pro
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using MeshForwardDirection = uDesktopDuplication.Texture.MeshForwardDirection;
|
||||||
|
|
||||||
|
public class MetadataVisualizer : MonoBehaviour
|
||||||
|
{
|
||||||
|
uDesktopDuplication.Texture uddTexture_;
|
||||||
|
|
||||||
|
[SerializeField] bool drawMoveRectDest;
|
||||||
|
[SerializeField] bool drawMoveRectSource;
|
||||||
|
[SerializeField] bool drawDirtyRect;
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
uddTexture_ = GetComponent<uDesktopDuplication.Texture>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 GetWorldPositionFromCoord(int u, int v)
|
||||||
|
{
|
||||||
|
var monitor = uddTexture_.monitor;
|
||||||
|
|
||||||
|
// mesh & scale information
|
||||||
|
var mesh = GetComponent<MeshFilter>().sharedMesh;
|
||||||
|
var width = transform.localScale.x * (mesh.bounds.extents.x * 2f);
|
||||||
|
var height = transform.localScale.y * (mesh.bounds.extents.y * 2f);
|
||||||
|
|
||||||
|
// local position (scale included).
|
||||||
|
var x = (float)(u - monitor.width / 2) / monitor.width;
|
||||||
|
var y = -(float)(v - monitor.height / 2) / monitor.height;
|
||||||
|
var localPos = new Vector3(width * x, height * y, 0f);
|
||||||
|
|
||||||
|
// bend
|
||||||
|
if (uddTexture_.bend) {
|
||||||
|
var radius = uddTexture_.radius;
|
||||||
|
var angle = localPos.x / radius;
|
||||||
|
if (uddTexture_.meshForwardDirection == MeshForwardDirection.Y) {
|
||||||
|
localPos.y -= radius * (1f - Mathf.Cos(angle));
|
||||||
|
} else {
|
||||||
|
localPos.z -= radius * (1f - Mathf.Cos(angle));
|
||||||
|
}
|
||||||
|
localPos.x = radius * Mathf.Sin(angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// to world position
|
||||||
|
return transform.position + (transform.rotation * localPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
UpdateMoveRects();
|
||||||
|
UpdateDirtyRects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawRect(uDesktopDuplication.RECT rect, Color color)
|
||||||
|
{
|
||||||
|
var p0 = GetWorldPositionFromCoord(rect.left, rect.top);
|
||||||
|
var p1 = GetWorldPositionFromCoord(rect.right, rect.top);
|
||||||
|
var p2 = GetWorldPositionFromCoord(rect.right, rect.bottom);
|
||||||
|
var p3 = GetWorldPositionFromCoord(rect.left, rect.bottom);
|
||||||
|
|
||||||
|
Debug.DrawLine(p0, p1, color);
|
||||||
|
Debug.DrawLine(p1, p2, color);
|
||||||
|
Debug.DrawLine(p2, p3, color);
|
||||||
|
Debug.DrawLine(p3, p0, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateMoveRects()
|
||||||
|
{
|
||||||
|
if (drawMoveRectSource) {
|
||||||
|
foreach (var rect in uddTexture_.monitor.moveRects) {
|
||||||
|
DrawRect(rect.source, Color.blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (drawMoveRectDest) {
|
||||||
|
foreach (var rect in uddTexture_.monitor.moveRects) {
|
||||||
|
DrawRect(rect.destination, Color.green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDirtyRects()
|
||||||
|
{
|
||||||
|
if (drawDirtyRect) {
|
||||||
|
foreach (var rect in uddTexture_.monitor.dirtyRects) {
|
||||||
|
DrawRect(rect, Color.red);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 52d402bdca823cc42925c9d65993ee59
|
||||||
|
timeCreated: 1479546123
|
||||||
|
licenseType: Pro
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using MeshForwardDirection = uDesktopDuplication.Texture.MeshForwardDirection;
|
||||||
|
|
||||||
public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
|
public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
|
||||||
{
|
{
|
||||||
@@ -20,7 +21,11 @@ public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
|
|||||||
// keep the local scale z of monitors as 1 to bend them correctly.
|
// keep the local scale z of monitors as 1 to bend them correctly.
|
||||||
foreach (var info in monitors) {
|
foreach (var info in monitors) {
|
||||||
var scale = info.gameObject.transform.localScale;
|
var scale = info.gameObject.transform.localScale;
|
||||||
scale.z = 1f;
|
if (creator_.meshForwardDirection == MeshForwardDirection.Y) {
|
||||||
|
scale.y = 1f;
|
||||||
|
} else {
|
||||||
|
scale.z = 1f;
|
||||||
|
}
|
||||||
info.gameObject.transform.localScale = scale;
|
info.gameObject.transform.localScale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ public class ToggleMonitors : MonoBehaviour
|
|||||||
{
|
{
|
||||||
if (Input.GetKeyDown(KeyCode.Tab)) {
|
if (Input.GetKeyDown(KeyCode.Tab)) {
|
||||||
var texture = GetComponent<uDesktopDuplication.Texture>();
|
var texture = GetComponent<uDesktopDuplication.Texture>();
|
||||||
|
var id = texture.monitorId;
|
||||||
|
var n = uDesktopDuplication.Manager.monitorCount;
|
||||||
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) {
|
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) {
|
||||||
texture.monitorId--;
|
texture.monitorId = (id - 1 < 0) ? 0 : (id - 1);
|
||||||
} else {
|
} else {
|
||||||
texture.monitorId++;
|
texture.monitorId = (id + 1 >= n) ? (n - 1) : (id + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -50,6 +50,26 @@ public enum DebugMode
|
|||||||
UnityLog = 2, /* currently has bug when app exits. */
|
UnityLog = 2, /* currently has bug when app exits. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RECT
|
||||||
|
{
|
||||||
|
[MarshalAs(UnmanagedType.I4)]
|
||||||
|
public int left;
|
||||||
|
[MarshalAs(UnmanagedType.I4)]
|
||||||
|
public int top;
|
||||||
|
[MarshalAs(UnmanagedType.I4)]
|
||||||
|
public int right;
|
||||||
|
[MarshalAs(UnmanagedType.I4)]
|
||||||
|
public int bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct DXGI_OUTDUPL_MOVE_RECT
|
||||||
|
{
|
||||||
|
public RECT source;
|
||||||
|
public RECT destination;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Lib
|
public static class Lib
|
||||||
{
|
{
|
||||||
public delegate void MessageHandler(Message message);
|
public delegate void MessageHandler(Message message);
|
||||||
@@ -134,6 +154,14 @@ public static class Lib
|
|||||||
public static extern void GetCursorTexture(int id, System.IntPtr ptr);
|
public static extern void GetCursorTexture(int id, System.IntPtr ptr);
|
||||||
[DllImport("uDesktopDuplication")]
|
[DllImport("uDesktopDuplication")]
|
||||||
public static extern int SetTexturePtr(int id, IntPtr ptr);
|
public static extern int SetTexturePtr(int id, IntPtr ptr);
|
||||||
|
[DllImport("uDesktopDuplication")]
|
||||||
|
public static extern int GetMoveRectCount(int id);
|
||||||
|
[DllImport("uDesktopDuplication", EntryPoint = "GetMoveRects")]
|
||||||
|
private static extern IntPtr GetMoveRects_Internal(int id);
|
||||||
|
[DllImport("uDesktopDuplication")]
|
||||||
|
public static extern int GetDirtyRectCount(int id);
|
||||||
|
[DllImport("uDesktopDuplication", EntryPoint = "GetDirtyRects")]
|
||||||
|
private static extern IntPtr GetDirtyRects_Internal(int id);
|
||||||
|
|
||||||
public static string GetName(int id)
|
public static string GetName(int id)
|
||||||
{
|
{
|
||||||
@@ -141,6 +169,32 @@ public static class Lib
|
|||||||
GetName(id, buf, buf.Capacity);
|
GetName(id, buf, buf.Capacity);
|
||||||
return buf.ToString();
|
return buf.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DXGI_OUTDUPL_MOVE_RECT[] GetMoveRects(int id)
|
||||||
|
{
|
||||||
|
var count = GetMoveRectCount(id);
|
||||||
|
var rects = new DXGI_OUTDUPL_MOVE_RECT[count];
|
||||||
|
var ptr = GetMoveRects_Internal(id);
|
||||||
|
var size = Marshal.SizeOf(typeof(DXGI_OUTDUPL_MOVE_RECT));
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
var data = new IntPtr(ptr.ToInt64() + size * i);
|
||||||
|
rects[i] = (DXGI_OUTDUPL_MOVE_RECT)Marshal.PtrToStructure(data, typeof(DXGI_OUTDUPL_MOVE_RECT));
|
||||||
|
}
|
||||||
|
return rects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RECT[] GetDirtyRects(int id)
|
||||||
|
{
|
||||||
|
var count = GetDirtyRectCount(id);
|
||||||
|
var rects = new RECT[count];
|
||||||
|
var ptr = GetDirtyRects_Internal(id);
|
||||||
|
var size = Marshal.SizeOf(typeof(RECT));
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
var data = new IntPtr(ptr.ToInt64() + size * i);
|
||||||
|
rects[i] = (RECT)Marshal.PtrToStructure(data, typeof(RECT));
|
||||||
|
}
|
||||||
|
return rects;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -202,6 +202,26 @@ public class Monitor
|
|||||||
get { return Lib.GetCursorShapeType(id); }
|
get { return Lib.GetCursorShapeType(id); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int moveRectCount
|
||||||
|
{
|
||||||
|
get { return Lib.GetMoveRectCount(id); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public DXGI_OUTDUPL_MOVE_RECT[] moveRects
|
||||||
|
{
|
||||||
|
get { return Lib.GetMoveRects(id); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int dirtyRectCount
|
||||||
|
{
|
||||||
|
get { return Lib.GetDirtyRectCount(id); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public RECT[] dirtyRects
|
||||||
|
{
|
||||||
|
get { return Lib.GetDirtyRects(id); }
|
||||||
|
}
|
||||||
|
|
||||||
public bool shouldBeUpdated
|
public bool shouldBeUpdated
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|||||||
@@ -69,13 +69,13 @@ public class Texture : MonoBehaviour
|
|||||||
switch (value) {
|
switch (value) {
|
||||||
case MeshForwardDirection.Y:
|
case MeshForwardDirection.Y:
|
||||||
material.SetInt("_Forward", 0);
|
material.SetInt("_Forward", 0);
|
||||||
material.EnableKeyword("_BEND_Y");
|
material.EnableKeyword("_FORWARD_Y");
|
||||||
material.DisableKeyword("_BEND_Z");
|
material.DisableKeyword("_FORWARD_Z");
|
||||||
break;
|
break;
|
||||||
case MeshForwardDirection.Z:
|
case MeshForwardDirection.Z:
|
||||||
material.SetInt("_Forward", 1);
|
material.SetInt("_Forward", 1);
|
||||||
material.DisableKeyword("_BEND_Y");
|
material.DisableKeyword("_FORWARD_Y");
|
||||||
material.EnableKeyword("_BEND_Z");
|
material.EnableKeyword("_FORWARD_Z");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ inline void uddBendVertex(inout float4 v, half radius, half width, half thicknes
|
|||||||
#ifdef BEND_ON
|
#ifdef BEND_ON
|
||||||
half angle = width * v.x / radius;
|
half angle = width * v.x / radius;
|
||||||
#ifdef _FORWARD_Z
|
#ifdef _FORWARD_Z
|
||||||
|
v.z *= thickness;
|
||||||
|
radius -= v.z;
|
||||||
|
v.z -= radius * (1 - cos(angle));
|
||||||
|
#elif _FORWARD_Y
|
||||||
v.y *= thickness;
|
v.y *= thickness;
|
||||||
radius -= v.y;
|
radius -= v.y;
|
||||||
v.y += radius * (1 - cos(angle));
|
v.y += radius * (1 - cos(angle));
|
||||||
#elif _FORWARD_Y
|
|
||||||
v.z *= thickness;
|
|
||||||
radius -= v.z;
|
|
||||||
v.z += radius * (1 - cos(angle));
|
|
||||||
#endif
|
#endif
|
||||||
v.x = radius * sin(angle) / width;
|
v.x = radius * sin(angle) / width;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -33,50 +33,67 @@ template <class T>
|
|||||||
class Buffer
|
class Buffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Buffer() {}
|
Buffer() {}
|
||||||
~Buffer() {}
|
~Buffer() {}
|
||||||
|
|
||||||
void ExpandIfNeeded(UINT size)
|
void ExpandIfNeeded(UINT size)
|
||||||
{
|
{
|
||||||
if (size > size_)
|
if (size > size_)
|
||||||
{
|
{
|
||||||
size_ = size;
|
size_ = size;
|
||||||
value_ = std::make_unique<T[]>(size);
|
value_ = std::make_unique<T[]>(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
value_.reset();
|
value_.reset();
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT Size() const
|
UINT Size() const
|
||||||
{
|
{
|
||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* Get() const
|
T* Get() const
|
||||||
{
|
{
|
||||||
return value_.get();
|
return value_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const
|
T* Get(UINT offset) const
|
||||||
{
|
{
|
||||||
return value_ != nullptr;
|
return (value_.get() + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator [](UINT index) const
|
template <class U>
|
||||||
{
|
U* As() const
|
||||||
if (index >= size_)
|
{
|
||||||
{
|
return reinterpret_cast<U*>(Get());
|
||||||
Debug::Error("Array index out of range: ", index, size_);
|
}
|
||||||
return T(0);
|
|
||||||
}
|
template <class U>
|
||||||
return value_[index];
|
U* As(UINT offset) const
|
||||||
}
|
{
|
||||||
|
return reinterpret_cast<U*>(Get(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return value_ != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T operator [](UINT index) const
|
||||||
|
{
|
||||||
|
if (index >= size_)
|
||||||
|
{
|
||||||
|
Debug::Error("Array index out of range: ", index, size_);
|
||||||
|
return T(0);
|
||||||
|
}
|
||||||
|
return value_[index];
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<T[]> value_;
|
std::unique_ptr<T[]> value_;
|
||||||
UINT size_ = 0;
|
UINT size_ = 0;
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <ShellScalingAPI.h>
|
#include <ShellScalingAPI.h>
|
||||||
#include "Common.h"
|
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "Cursor.h"
|
#include "Cursor.h"
|
||||||
#include "MonitorManager.h"
|
#include "MonitorManager.h"
|
||||||
@@ -50,7 +49,7 @@ void Monitor::Initialize(IDXGIOutput* output)
|
|||||||
if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_)))
|
if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_)))
|
||||||
{
|
{
|
||||||
Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed.");
|
Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed.");
|
||||||
// DPI is set as -1, so the application has to use the appropriate value.
|
// DPI is set as -1, so the application has to use the appropriate value.
|
||||||
}
|
}
|
||||||
|
|
||||||
auto output1 = reinterpret_cast<IDXGIOutput1*>(output);
|
auto output1 = reinterpret_cast<IDXGIOutput1*>(output);
|
||||||
@@ -156,7 +155,7 @@ void Monitor::Render(UINT timeout)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get texture
|
// Get texture
|
||||||
if (unityTexture_)
|
if (unityTexture_)
|
||||||
{
|
{
|
||||||
ID3D11Texture2D* texture;
|
ID3D11Texture2D* texture;
|
||||||
@@ -189,8 +188,8 @@ void Monitor::Render(UINT timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor_->UpdateBuffer(frameInfo);
|
UpdateMetadata(frameInfo);
|
||||||
cursor_->UpdateTexture();
|
UpdateCursor(frameInfo);
|
||||||
|
|
||||||
if (FAILED(deskDupl_->ReleaseFrame()))
|
if (FAILED(deskDupl_->ReleaseFrame()))
|
||||||
{
|
{
|
||||||
@@ -199,6 +198,109 @@ void Monitor::Render(UINT timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Monitor::UpdateCursor(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||||
|
{
|
||||||
|
cursor_->UpdateBuffer(frameInfo);
|
||||||
|
cursor_->UpdateTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Monitor::UpdateMetadata(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||||
|
{
|
||||||
|
metaData_.ExpandIfNeeded(frameInfo.TotalMetadataBufferSize);
|
||||||
|
UpdateMoveRects(frameInfo);
|
||||||
|
UpdateDirtyRects(frameInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Monitor::UpdateMoveRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||||
|
{
|
||||||
|
moveRectSize_ = metaData_.Size();
|
||||||
|
|
||||||
|
const auto hr = deskDupl_->GetFrameMoveRects(
|
||||||
|
moveRectSize_,
|
||||||
|
metaData_.As<DXGI_OUTDUPL_MOVE_RECT>(),
|
||||||
|
&moveRectSize_);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
switch (hr)
|
||||||
|
{
|
||||||
|
case DXGI_ERROR_ACCESS_LOST:
|
||||||
|
{
|
||||||
|
Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST (GetFrameMoveRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DXGI_ERROR_MORE_DATA:
|
||||||
|
{
|
||||||
|
Debug::Error("Monitor::Render() => DXGI_ERROR_MORE_DATA (GetFrameMoveRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DXGI_ERROR_INVALID_CALL:
|
||||||
|
{
|
||||||
|
Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL (GetFrameMoveRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case E_INVALIDARG:
|
||||||
|
{
|
||||||
|
Debug::Error("Monitor::Render() => E_INVALIDARG (GetFrameMoveRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Debug::Error("Monitor::Render() => Unknown Error (GetFrameMoveRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Monitor::UpdateDirtyRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
|
||||||
|
{
|
||||||
|
dirtyRectSize_ = metaData_.Size() - moveRectSize_;
|
||||||
|
|
||||||
|
const auto hr = deskDupl_->GetFrameDirtyRects(
|
||||||
|
dirtyRectSize_,
|
||||||
|
metaData_.As<RECT>(moveRectSize_ /* offset */),
|
||||||
|
&dirtyRectSize_);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
switch (hr)
|
||||||
|
{
|
||||||
|
case DXGI_ERROR_ACCESS_LOST:
|
||||||
|
{
|
||||||
|
Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST (GetFrameDirtyRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DXGI_ERROR_MORE_DATA:
|
||||||
|
{
|
||||||
|
Debug::Error("Monitor::Render() => DXGI_ERROR_MORE_DATA (GetFrameDirtyRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DXGI_ERROR_INVALID_CALL:
|
||||||
|
{
|
||||||
|
Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL (GetFrameDirtyRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case E_INVALIDARG:
|
||||||
|
{
|
||||||
|
Debug::Error("Monitor::Render() => E_INVALIDARG (GetFrameDirtyRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Debug::Error("Monitor::Render() => Unknown Error (GetFrameDirtyRects()).");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Monitor::GetId() const
|
int Monitor::GetId() const
|
||||||
{
|
{
|
||||||
return id_;
|
return id_;
|
||||||
@@ -304,4 +406,28 @@ int Monitor::GetWidth() const
|
|||||||
int Monitor::GetHeight() const
|
int Monitor::GetHeight() const
|
||||||
{
|
{
|
||||||
return height_;
|
return height_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Monitor::GetMoveRectCount() const
|
||||||
|
{
|
||||||
|
return moveRectSize_ / sizeof(DXGI_OUTDUPL_MOVE_RECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DXGI_OUTDUPL_MOVE_RECT* Monitor::GetMoveRects() const
|
||||||
|
{
|
||||||
|
return metaData_.As<DXGI_OUTDUPL_MOVE_RECT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Monitor::GetDirtyRectCount() const
|
||||||
|
{
|
||||||
|
return dirtyRectSize_ / sizeof(RECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RECT* Monitor::GetDirtyRects() const
|
||||||
|
{
|
||||||
|
return metaData_.As<RECT>(moveRectSize_);
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <dxgi1_2.h>
|
#include <dxgi1_2.h>
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
class Cursor;
|
class Cursor;
|
||||||
|
|
||||||
@@ -50,8 +51,17 @@ public:
|
|||||||
int GetDpiY() const;
|
int GetDpiY() const;
|
||||||
IDXGIOutputDuplication* GetDeskDupl();
|
IDXGIOutputDuplication* GetDeskDupl();
|
||||||
const std::unique_ptr<Cursor>& GetCursor();
|
const std::unique_ptr<Cursor>& GetCursor();
|
||||||
|
int GetMoveRectCount() const;
|
||||||
|
DXGI_OUTDUPL_MOVE_RECT* GetMoveRects() const;
|
||||||
|
int GetDirtyRectCount() const;
|
||||||
|
RECT* GetDirtyRects() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void UpdateCursor(const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
|
||||||
|
void UpdateMetadata(const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
|
||||||
|
void UpdateMoveRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
|
||||||
|
void UpdateDirtyRects(const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
|
||||||
|
|
||||||
int id_ = -1;
|
int id_ = -1;
|
||||||
UINT dpiX_ = -1, dpiY_ = -1;
|
UINT dpiX_ = -1, dpiY_ = -1;
|
||||||
int width_ = -1, height_ = -1;
|
int width_ = -1, height_ = -1;
|
||||||
@@ -61,4 +71,7 @@ private:
|
|||||||
ID3D11Texture2D* unityTexture_ = nullptr;
|
ID3D11Texture2D* unityTexture_ = nullptr;
|
||||||
DXGI_OUTPUT_DESC outputDesc_;
|
DXGI_OUTPUT_DESC outputDesc_;
|
||||||
MONITORINFOEX monitorInfo_;
|
MONITORINFOEX monitorInfo_;
|
||||||
|
Buffer<BYTE> metaData_;
|
||||||
|
UINT moveRectSize_ = 0;
|
||||||
|
UINT dirtyRectSize_ = 0;;
|
||||||
};
|
};
|
||||||
@@ -383,4 +383,40 @@ extern "C"
|
|||||||
monitor->SetUnityTexture(d3d11Texture);
|
monitor->SetUnityTexture(d3d11Texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetMoveRectCount(int id)
|
||||||
|
{
|
||||||
|
if (!g_manager) return -1;
|
||||||
|
if (auto monitor = g_manager->GetMonitor(id))
|
||||||
|
{
|
||||||
|
return monitor->GetMoveRectCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UNITY_INTERFACE_EXPORT void* UNITY_INTERFACE_API GetMoveRects(int id)
|
||||||
|
{
|
||||||
|
if (!g_manager) return nullptr;
|
||||||
|
if (auto monitor = g_manager->GetMonitor(id))
|
||||||
|
{
|
||||||
|
return monitor->GetMoveRects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API GetDirtyRectCount(int id)
|
||||||
|
{
|
||||||
|
if (!g_manager) return -1;
|
||||||
|
if (auto monitor = g_manager->GetMonitor(id))
|
||||||
|
{
|
||||||
|
return monitor->GetDirtyRectCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UNITY_INTERFACE_EXPORT void* UNITY_INTERFACE_API GetDirtyRects(int id)
|
||||||
|
{
|
||||||
|
if (!g_manager) return nullptr;
|
||||||
|
if (auto monitor = g_manager->GetMonitor(id))
|
||||||
|
{
|
||||||
|
return monitor->GetDirtyRects();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user