Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8434d803bb | ||
|
|
1c332ebca7 | ||
|
|
340e2d5194 | ||
|
|
e397f5eb84 | ||
|
|
c20c09e275 | ||
|
|
a0ca46630e | ||
|
|
5b5995d7d0 | ||
|
|
808a71ed6d | ||
|
|
da072aa9f3 | ||
|
|
7237d283ef | ||
|
|
4a28b5f341 | ||
|
|
10091be4b3 | ||
|
|
c41fe42aa3 | ||
|
|
c0e1967e2e | ||
|
|
f5a8a83c7e | ||
|
|
c251de3a30 | ||
|
|
b0877a49ed |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,41 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(MultipleMonitorCreator))]
|
||||
public class MultipleMonitorAnalyzer : MonoBehaviour
|
||||
{
|
||||
MultipleMonitorCreator creator_;
|
||||
Vector3 gazePoint_ = Vector3.zero;
|
||||
public Vector3 gazePoint
|
||||
{
|
||||
get { return gazePoint_; }
|
||||
private set
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(MultipleMonitorCreator))]
|
||||
public class MultipleMonitorAnalyzer : MonoBehaviour
|
||||
{
|
||||
MultipleMonitorCreator creator_;
|
||||
Vector3 gazePoint_ = Vector3.zero;
|
||||
public Vector3 gazePoint
|
||||
{
|
||||
get { return gazePoint_; }
|
||||
private set
|
||||
{
|
||||
gazePoint_ += (value - gazePoint) * (gazePointFilter / (1f / 60 / Time.deltaTime));
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Filters")]
|
||||
[Range(0f, 1f)] public float gazePointFilter = 0.1f;
|
||||
[Range(0f, 1f)] public float moveRectFilter = 0.05f;
|
||||
[Range(0f, 1f)] public float mouseFilter = 0.05f;
|
||||
[Range(0f, 1f)] public float dirtyRectFilter = 0.01f;
|
||||
[Range(0f, 1f)] public float noEventFilter = 0.01f;
|
||||
[Range(0f, 1f)] public float velocityFilter = 0.1f;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] bool drawGazePoint;
|
||||
[SerializeField] bool drawAveragePos;
|
||||
[SerializeField] bool drawMoveRects;
|
||||
[SerializeField] bool drawDirtyRects;
|
||||
|
||||
void Start()
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Filters")]
|
||||
[Range(0f, 1f)] public float gazePointFilter = 0.1f;
|
||||
[Range(0f, 1f)] public float moveRectFilter = 0.05f;
|
||||
[Range(0f, 1f)] public float mouseFilter = 0.05f;
|
||||
[Range(0f, 1f)] public float dirtyRectFilter = 0.01f;
|
||||
[Range(0f, 1f)] public float noEventFilter = 0.01f;
|
||||
[Range(0f, 1f)] public float velocityFilter = 0.1f;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] bool drawGazePoint;
|
||||
[SerializeField] bool drawAveragePos;
|
||||
[SerializeField] bool drawMoveRects;
|
||||
[SerializeField] bool drawDirtyRects;
|
||||
|
||||
void Start()
|
||||
{
|
||||
creator_ = GetComponent<MultipleMonitorCreator>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
var cursorMonitorId = uDesktopDuplication.Manager.cursorMonitorId;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
var cursorMonitorId = uDesktopDuplication.Manager.cursorMonitorId;
|
||||
for (int i = 0; i < creator_.monitors.Count; ++i) {
|
||||
var info = creator_.monitors[i];
|
||||
var analyzer =
|
||||
@@ -44,18 +44,18 @@ public class MultipleMonitorAnalyzer : MonoBehaviour
|
||||
UpdateAnalyzer(analyzer);
|
||||
if (info.uddTexture.monitorId == cursorMonitorId) {
|
||||
gazePoint = analyzer.averagePos;
|
||||
}
|
||||
}
|
||||
|
||||
if (drawGazePoint) DrawGazePoint();
|
||||
}
|
||||
|
||||
void DrawGazePoint()
|
||||
}
|
||||
}
|
||||
|
||||
if (drawGazePoint) DrawGazePoint();
|
||||
}
|
||||
|
||||
void DrawGazePoint()
|
||||
{
|
||||
Debug.DrawLine(transform.position, gazePoint, Color.magenta);
|
||||
}
|
||||
|
||||
void UpdateAnalyzer(GazePointAnalyzer analyzer)
|
||||
}
|
||||
|
||||
void UpdateAnalyzer(GazePointAnalyzer analyzer)
|
||||
{
|
||||
analyzer.moveRectFilter = moveRectFilter;
|
||||
analyzer.mouseFilter = mouseFilter;
|
||||
@@ -65,5 +65,5 @@ public class MultipleMonitorAnalyzer : MonoBehaviour
|
||||
analyzer.drawAveragePos = drawAveragePos;
|
||||
analyzer.drawMoveRects = drawMoveRects;
|
||||
analyzer.drawDirtyRects = drawDirtyRects;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,53 +1,122 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19d4c78204afead44b6de11427d7f2f6
|
||||
timeCreated: 1480693943
|
||||
guid: d3ab0ac3a3d6bb643af0a464a93be957
|
||||
timeCreated: 1503496900
|
||||
licenseType: Pro
|
||||
PluginImporter:
|
||||
serializedVersion: 1
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
Any:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
Editor:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
DefaultValueInitialized: true
|
||||
Linux:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86
|
||||
Linux64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
LinuxUniversal:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86
|
||||
OSXIntel:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXIntel64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
OSXUniversal:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
Win:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Win64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 0
|
||||
Exclude Editor: 0
|
||||
Exclude Linux: 0
|
||||
Exclude Linux64: 0
|
||||
Exclude LinuxUniversal: 0
|
||||
Exclude OSXIntel: 0
|
||||
Exclude OSXIntel64: 0
|
||||
Exclude OSXUniversal: 0
|
||||
Exclude Win: 0
|
||||
Exclude Win64: 1
|
||||
data:
|
||||
first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
data:
|
||||
first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
data:
|
||||
first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86
|
||||
DefaultValueInitialized: true
|
||||
OS: Windows
|
||||
data:
|
||||
first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86
|
||||
data:
|
||||
first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXIntel
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXIntel64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
Binary file not shown.
@@ -1,54 +1,98 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02fc121822cf2ea4e82e16c4a28bf711
|
||||
timeCreated: 1477546714
|
||||
guid: 7cb91c9ae744dc5429005b20e11f4f37
|
||||
timeCreated: 1503505907
|
||||
licenseType: Pro
|
||||
PluginImporter:
|
||||
serializedVersion: 1
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
Any:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
Editor:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
Linux:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
Linux64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86_64
|
||||
LinuxUniversal:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
OSXIntel:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXIntel64:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
OSXUniversal:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
Win:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
Win64:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
data:
|
||||
first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86_64
|
||||
DefaultValueInitialized: true
|
||||
data:
|
||||
first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
data:
|
||||
first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXIntel
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXIntel64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
data:
|
||||
first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86_64
|
||||
data:
|
||||
first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
data:
|
||||
first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -271,7 +271,10 @@ public class Texture : MonoBehaviour
|
||||
|
||||
void RequireUpdate()
|
||||
{
|
||||
monitor.shouldBeUpdated = true;
|
||||
if (monitor != null)
|
||||
{
|
||||
monitor.shouldBeUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Reinitialize()
|
||||
@@ -283,7 +286,9 @@ public class Texture : MonoBehaviour
|
||||
void UpdateMaterial()
|
||||
{
|
||||
width = transform.localScale.x;
|
||||
rotation = monitor.rotation;
|
||||
if (monitor != null) {
|
||||
rotation = monitor.rotation;
|
||||
}
|
||||
material.SetVector("_ClipPositionScale", new Vector4(clipPos.x, clipPos.y, clipScale.x, clipScale.y));
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ DsOutput domain(
|
||||
float disp = length(_DispTex.SampleLevel(sampler_DispTex, o.f2TexCoord, 0)) * _DispFactor;
|
||||
f3Position.xyz += f3Normal * disp;
|
||||
|
||||
o.f4Position = mul(UNITY_MATRIX_MVP, float4(f3Position.xyz, 1.0));
|
||||
o.f4Position = UnityObjectToClipPos(float4(f3Position.xyz, 1.0));
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
5
Plugins/uDesktopDuplication/uDesktopDuplication.def
Normal file
5
Plugins/uDesktopDuplication/uDesktopDuplication.def
Normal file
@@ -0,0 +1,5 @@
|
||||
LIBRARY
|
||||
|
||||
EXPORTS
|
||||
UnityPluginLoad
|
||||
UnityPluginUnload
|
||||
@@ -62,16 +62,16 @@ void Cursor::UpdateBuffer(Duplicator* duplicator, const DXGI_OUTDUPL_FRAME_INFO&
|
||||
}
|
||||
|
||||
|
||||
void Cursor::Draw(
|
||||
void Cursor::UpdateTexture(
|
||||
Duplicator* duplicator,
|
||||
const ComPtr<ID3D11Texture2D>& targetTexture)
|
||||
const ComPtr<ID3D11Texture2D>& desktopTexture)
|
||||
{
|
||||
auto monitor = duplicator->GetMonitor();
|
||||
|
||||
// Check desktop texure
|
||||
if (targetTexture == nullptr)
|
||||
if (desktopTexture == nullptr)
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => target texture is null.");
|
||||
Debug::Error("Cursor::UpdateTexture() => Desktop texture is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ void Cursor::Draw(
|
||||
// Check buffers
|
||||
if (!bgraBuffer_ || !buffer_)
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => no buffer.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -193,7 +194,7 @@ void Cursor::Draw(
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_BOX capturedImageArea
|
||||
capturedImageArea_ = D3D11_BOX
|
||||
{
|
||||
static_cast<UINT>(capturedImageLeft),
|
||||
static_cast<UINT>(capturedImageTop),
|
||||
@@ -230,7 +231,7 @@ void Cursor::Draw(
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
duplicator->GetDevice()->GetImmediateContext(&context);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, targetTexture.Get(), 0, &capturedImageArea);
|
||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, desktopTexture.Get(), 0, &capturedImageArea_);
|
||||
}
|
||||
|
||||
// Get mapped surface to access pixels in CPU
|
||||
@@ -358,12 +359,6 @@ void Cursor::Draw(
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
duplicator->GetDevice()->GetImmediateContext(&context);
|
||||
context->UpdateSubresource(targetTexture.Get(), 0, &capturedImageArea, bgraBuffer_.Get(), capturedImageWidth * 4, 0);
|
||||
}
|
||||
|
||||
if (FAILED(surface->Unmap()))
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => surface->Unmap() failed.");
|
||||
@@ -372,6 +367,21 @@ void Cursor::Draw(
|
||||
}
|
||||
|
||||
|
||||
void Cursor::Draw(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture)
|
||||
{
|
||||
if (texture == nullptr)
|
||||
{
|
||||
Debug::Error("Cursor::UpdateTexture() => Desktop texture is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto capturedImageWidth = capturedImageArea_.right - capturedImageArea_.left;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->UpdateSubresource(texture.Get(), 0, &capturedImageArea_, bgraBuffer_.Get(), capturedImageWidth * 4, 0);
|
||||
}
|
||||
|
||||
|
||||
void Cursor::GetTexture(ID3D11Texture2D* texture)
|
||||
{
|
||||
if (!bgraBuffer_)
|
||||
|
||||
@@ -17,9 +17,10 @@ public:
|
||||
void UpdateBuffer(
|
||||
Duplicator* duplicator,
|
||||
const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
|
||||
void Draw(
|
||||
Duplicator* duplicator,
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& targetTexture);
|
||||
void UpdateTexture(
|
||||
Duplicator* duplicator,
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& desktopTexture);
|
||||
void Draw(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture);
|
||||
void GetTexture(ID3D11Texture2D* texture);
|
||||
|
||||
bool IsVisible() const;
|
||||
@@ -38,4 +39,5 @@ private:
|
||||
Buffer<BYTE> bgraBuffer_;
|
||||
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo_;
|
||||
LARGE_INTEGER timestamp_;
|
||||
D3D11_BOX capturedImageArea_;
|
||||
};
|
||||
@@ -1,10 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
|
||||
#include "Common.h"
|
||||
#include "IUnityInterface.h"
|
||||
|
||||
|
||||
// Debug flag
|
||||
#define UDD_DEBUG_ON
|
||||
|
||||
|
||||
// Logging
|
||||
class Debug
|
||||
{
|
||||
@@ -133,4 +141,21 @@ private:
|
||||
static DebugLogFuncPtr logFunc_;
|
||||
static DebugLogFuncPtr errFunc_;
|
||||
static std::mutex mutex_;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#ifdef UDD_DEBUG_ON
|
||||
#define UDD_FUNCTION_SCOPE_TIMER \
|
||||
ScopedTimer _timer_##__COUNTER__([](std::chrono::microseconds us) \
|
||||
{ \
|
||||
Debug::Log(__FUNCTION__, "@", __FILE__, ":", __LINE__, " => ", us.count(), " [us]"); \
|
||||
});
|
||||
#define UDD_SCOPE_TIMER(Name) \
|
||||
ScopedTimer _timer_##__COUNTER__([](std::chrono::microseconds us) \
|
||||
{ \
|
||||
Debug::Log(#Name, " => ", us.count(), " [us]"); \
|
||||
});
|
||||
#else
|
||||
#define UDD_FUNCTION_SCOPE_TIMER
|
||||
#define UDD_SCOPE_TIMER(Name)
|
||||
#endif
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "IUnityGraphicsD3D11.h"
|
||||
#include "Device.h"
|
||||
#include "Debug.h"
|
||||
#include "Common.h"
|
||||
|
||||
#pragma comment(lib, "d3d11.lib")
|
||||
|
||||
@@ -14,8 +15,7 @@ using namespace Microsoft::WRL;
|
||||
|
||||
|
||||
|
||||
IsolatedD3D11Device::IsolatedD3D11Device(UINT cachedTextureNum)
|
||||
: cachedTextures_(cachedTextureNum)
|
||||
IsolatedD3D11Device::IsolatedD3D11Device()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,42 +65,33 @@ ComPtr<ID3D11Device> IsolatedD3D11Device::GetDevice()
|
||||
}
|
||||
|
||||
|
||||
ComPtr<ID3D11Texture2D> IsolatedD3D11Device::GetCompatibleSharedTexture(
|
||||
const ComPtr<ID3D11Texture2D>& src,
|
||||
UINT index)
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> IsolatedD3D11Device::GetCompatibleSharedTexture(
|
||||
const ComPtr<ID3D11Texture2D>& src)
|
||||
{
|
||||
if (index < 0 || index >= cachedTextures_.size())
|
||||
{
|
||||
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => ", index, " is out of cachedTextures range.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto& cachedTexture = cachedTextures_.at(index);
|
||||
|
||||
D3D11_TEXTURE2D_DESC srcDesc;
|
||||
src->GetDesc(&srcDesc);
|
||||
|
||||
// check if the format and size of the current texture are same as the source one
|
||||
if (cachedTexture)
|
||||
if (cachedSharedTexture_)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC targetDesc;
|
||||
cachedTexture->GetDesc(&targetDesc);
|
||||
cachedSharedTexture_->GetDesc(&targetDesc);
|
||||
if (targetDesc.Format == srcDesc.Format &&
|
||||
targetDesc.Width == srcDesc.Width &&
|
||||
targetDesc.Height == srcDesc.Height)
|
||||
{
|
||||
return cachedTexture;
|
||||
return cachedSharedTexture_;
|
||||
}
|
||||
}
|
||||
|
||||
// for sharing this texture with unity device
|
||||
srcDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &cachedTexture)))
|
||||
if (FAILED(device_->CreateTexture2D(&srcDesc, nullptr, &cachedSharedTexture_)))
|
||||
{
|
||||
Debug::Error("IsolatedD3D11Device::GetCompatibleSharedTexture() => Creating shared texture failed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return cachedTexture;
|
||||
return cachedSharedTexture_;
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <d3d11.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
@@ -9,16 +11,15 @@
|
||||
class IsolatedD3D11Device
|
||||
{
|
||||
public:
|
||||
explicit IsolatedD3D11Device(UINT cachedTextureNum);
|
||||
IsolatedD3D11Device();
|
||||
~IsolatedD3D11Device();
|
||||
|
||||
HRESULT Create(const Microsoft::WRL::ComPtr<IDXGIAdapter>& adapter);
|
||||
Microsoft::WRL::ComPtr<ID3D11Device> GetDevice();
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> GetCompatibleSharedTexture(
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src,
|
||||
UINT index);
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& src);
|
||||
|
||||
private:
|
||||
Microsoft::WRL::ComPtr<ID3D11Device> device_;
|
||||
std::vector<Microsoft::WRL::ComPtr<ID3D11Texture2D>> cachedTextures_;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> cachedSharedTexture_;
|
||||
};
|
||||
|
||||
@@ -33,8 +33,7 @@ Duplicator::~Duplicator()
|
||||
|
||||
void Duplicator::InitializeDevice()
|
||||
{
|
||||
const UINT cachedTextureNum = 2;
|
||||
device_ = std::make_shared<IsolatedD3D11Device>(cachedTextureNum);
|
||||
device_ = std::make_shared<IsolatedD3D11Device>();
|
||||
|
||||
if (FAILED(device_->Create(monitor_->GetAdapter())))
|
||||
{
|
||||
@@ -162,7 +161,12 @@ void Duplicator::Start()
|
||||
});
|
||||
|
||||
const auto timeout = static_cast<UINT>(frameMilliSeconds);
|
||||
if (!Duplicate(timeout)) break;
|
||||
Duplicate(timeout);
|
||||
|
||||
if (state_ != State::Running)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (state_ == State::Running)
|
||||
@@ -229,9 +233,9 @@ const Duplicator::Frame& Duplicator::GetLastFrame() const
|
||||
}
|
||||
|
||||
|
||||
bool Duplicator::Duplicate(UINT timeout)
|
||||
void Duplicator::Duplicate(UINT timeout)
|
||||
{
|
||||
if (!dupl_ || !device_) return false;
|
||||
if (!dupl_ || !device_) return;
|
||||
|
||||
ComPtr<IDXGIResource> resource;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
@@ -247,31 +251,32 @@ bool Duplicator::Duplicate(UINT timeout)
|
||||
// it is necessary to re-initialize monitors.
|
||||
Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST.");
|
||||
state_ = State::AccessLost;
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case DXGI_ERROR_WAIT_TIMEOUT:
|
||||
{
|
||||
// This often occurs when timeout value is small and it is not problem.
|
||||
// Debug::Log("Duplicator::Duplicate() => DXGI_ERROR_WAIT_TIMEOUT.");
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case DXGI_ERROR_INVALID_CALL:
|
||||
{
|
||||
Debug::Error("Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL.");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case E_INVALIDARG:
|
||||
{
|
||||
Debug::Error("Duplicator::Duplicate() => E_INVALIDARG.");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
state_ = State::Unknown;
|
||||
Debug::Error("Duplicator::Duplicate() => Unknown Error.");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ScopedReleaser releaser([this]
|
||||
@@ -305,31 +310,36 @@ bool Duplicator::Duplicate(UINT timeout)
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
if (FAILED(resource.As(&texture)))
|
||||
{
|
||||
return false;
|
||||
Debug::Error("Duplicator::Duplicate() => IDXGIResource could not be converted to ID3D11Texture2D.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto sharedTexture = device_->GetCompatibleSharedTexture(texture, frame % 2);
|
||||
auto sharedTexture = device_->GetCompatibleSharedTexture(texture);
|
||||
if (!sharedTexture)
|
||||
{
|
||||
return false;
|
||||
Debug::Error("Duplicator::Duplicate() => Shared texture is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
device_->GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(sharedTexture.Get(), texture.Get());
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
device_->GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(sharedTexture.Get(), texture.Get());
|
||||
}
|
||||
|
||||
UpdateCursor(sharedTexture, frameInfo);
|
||||
UpdateMetadata(frameInfo.TotalMetadataBufferSize);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
lastFrame_.frame = frame++;
|
||||
lastFrame_.texture = sharedTexture;
|
||||
lastFrame_.info = frameInfo;
|
||||
lastFrame_.metaData = metaData_;
|
||||
lastFrame_ = Frame
|
||||
{
|
||||
lastFrameId_++,
|
||||
sharedTexture,
|
||||
frameInfo,
|
||||
metaData_
|
||||
};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -348,7 +358,7 @@ void Duplicator::UpdateCursor(
|
||||
{
|
||||
auto cursor = manager->GetCursor();
|
||||
cursor->UpdateBuffer(this, frameInfo);
|
||||
cursor->Draw(this, texture);
|
||||
cursor->UpdateTexture(this, texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
struct Frame
|
||||
{
|
||||
UINT frame = 0;
|
||||
UINT id;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
|
||||
DXGI_OUTDUPL_FRAME_INFO info;
|
||||
Metadata metaData;
|
||||
@@ -67,7 +67,7 @@ private:
|
||||
void InitializeDuplication();
|
||||
void CheckUnityAdapter();
|
||||
|
||||
bool Duplicate(UINT timeout);
|
||||
void Duplicate(UINT timeout);
|
||||
|
||||
void UpdateCursor(
|
||||
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture,
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
std::shared_ptr<class IsolatedD3D11Device> device_;
|
||||
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> dupl_;
|
||||
Frame lastFrame_;
|
||||
UINT frame = 0;
|
||||
UINT lastFrameId_ = 0;
|
||||
|
||||
volatile bool shouldRun_ = false;
|
||||
std::thread thread_;
|
||||
|
||||
@@ -71,15 +71,14 @@ void Monitor::Finalize()
|
||||
void Monitor::Render()
|
||||
{
|
||||
const auto& frame = duplicator_->GetLastFrame();
|
||||
const auto& texture = frame.texture;
|
||||
|
||||
if (!texture) return;
|
||||
if (frame.id == lastFrameId_) return;
|
||||
lastFrameId_ = frame.id;
|
||||
|
||||
// Get texture
|
||||
if (unityTexture_)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC srcDesc, dstDesc;
|
||||
texture->GetDesc(&srcDesc);
|
||||
frame.texture->GetDesc(&srcDesc);
|
||||
unityTexture_->GetDesc(&dstDesc);
|
||||
if (srcDesc.Width != dstDesc.Width ||
|
||||
srcDesc.Height != dstDesc.Height)
|
||||
@@ -93,7 +92,13 @@ void Monitor::Render()
|
||||
{
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
GetDevice()->GetImmediateContext(&context);
|
||||
context->CopyResource(unityTexture_, texture.Get());
|
||||
context->CopyResource(unityTexture_, frame.texture.Get());
|
||||
|
||||
auto& manager = GetMonitorManager();
|
||||
if (id_ == manager->GetCursorMonitorId())
|
||||
{
|
||||
manager->GetCursor()->Draw(unityTexture_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ private:
|
||||
MONITORINFOEX monitorInfo_;
|
||||
|
||||
std::shared_ptr<class Duplicator> duplicator_;
|
||||
UINT lastFrameId_ = -1;
|
||||
|
||||
ID3D11Texture2D* unityTexture_ = nullptr;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> textureForGetPixels_;
|
||||
|
||||
@@ -84,6 +84,7 @@ void MonitorManager::Update()
|
||||
|
||||
void MonitorManager::RequireReinitilization()
|
||||
{
|
||||
Debug::Log("MonitorManager::Reinitialize() was required.");
|
||||
isReinitializationRequired_ = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);include</IncludePath>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -92,6 +94,10 @@
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86_64"</Command>
|
||||
</PostBuildEvent>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -100,8 +106,11 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86_64"</Command>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86"</Command>
|
||||
</PostBuildEvent>
|
||||
<Link>
|
||||
<ModuleDefinitionFile>$(SolutionDir)$(ProjectName).def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -115,6 +124,8 @@
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86_64"</Command>
|
||||
@@ -132,6 +143,7 @@
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>$(SolutionDir)$(ProjectName).def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)$(Platform)\$(Configuration)\$(TargetFileName)" "$(SolutionDir)..\..\Assets\$(ProjectName)\Plugins\x86"</Command>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
m_EditorVersion: 5.5.0f3
|
||||
m_EditorVersion: 2017.1.0b5
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,7 +2,6 @@ uDesktopDuplication
|
||||
===================
|
||||
|
||||

|
||||

|
||||
|
||||
**uDesktopDuplication** is an Unity asset to use the realtime screen capture as `Texture2D` using Desktop Duplication API.
|
||||
|
||||
@@ -28,7 +27,7 @@ Usage
|
||||
Attach `uDesktopDuplication/Texture` component to the target object, then its main texture will be replaced with the captured screen. Please see example scenes for more details.
|
||||
|
||||
|
||||
Lisence
|
||||
License
|
||||
-------
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user