Compare commits

..

4 Commits

Author SHA1 Message Date
hecomi
9c62157c0c fix typo. 2016-11-16 02:27:57 +09:00
hecomi
be79e52135 fix cursor buffer bug. 2016-11-16 02:24:49 +09:00
hecomi
e9c8b4e571 modify component requirements. 2016-11-16 02:07:57 +09:00
hecomi
77c95ab1bb fix indent 2016-11-16 02:04:13 +09:00
12 changed files with 179 additions and 165 deletions

View File

@@ -19,7 +19,7 @@ public class MultipleMonitorCreator : MonoBehaviour
[SerializeField]
ScaleMode scaleMode = ScaleMode.Fixed;
[Tooltip("Use this sacle as width if scaleMode is Fixed.")]
[Tooltip("Use this scale as width if scaleMode is Fixed.")]
[SerializeField]
float scale = 0.5f;

View File

@@ -5,8 +5,7 @@ using System.Collections.Generic;
namespace uDesktopDuplication
{
[AddComponentMenu("uDesktopDuplication/Cursor"),
RequireComponent(typeof(Texture))]
[AddComponentMenu("uDesktopDuplication/Cursor"), RequireComponent(typeof(Texture))]
public class Cursor : MonoBehaviour
{
[SerializeField] Vector2 modelScale = Vector2.one;

View File

@@ -30,13 +30,13 @@ public enum MonitorRotation
public enum MonitorState
{
NotSet = -1,
Available = 0,
InvalidArg = 1,
AccessDenied = 2,
Unsupported = 3,
CurrentlyNotAvailable = 4,
SessionDisconnected = 5,
NotSet = -1,
Available = 0,
InvalidArg = 1,
AccessDenied = 2,
Unsupported = 3,
CurrentlyNotAvailable = 4,
SessionDisconnected = 5,
AccessLost = 6,
TextureSizeInconsistent = 7,
Unknown = 999,

View File

@@ -3,7 +3,7 @@
namespace uDesktopDuplication
{
[AddComponentMenu("uDesktopDuplication/Texture")]
[AddComponentMenu("uDesktopDuplication/Texture"), RequireComponent(typeof(Cursor))]
public class Texture : MonoBehaviour
{
private Monitor monitor_;
@@ -105,10 +105,7 @@ public class Texture : MonoBehaviour
void Awake()
{
if (!GetComponent<Cursor>())
{
gameObject.AddComponent<Cursor>();
}
AddCursorIfNotAttached();
}
void OnEnable()
@@ -130,6 +127,14 @@ public class Texture : MonoBehaviour
UpdateMaterial();
}
void AddCursorIfNotAttached()
{
if (!GetComponent<Cursor>())
{
gameObject.AddComponent<Cursor>();
}
}
void Reinitialize()
{
// Monitor instance is released here when initialized.

View File

@@ -33,7 +33,7 @@ enum class Message
{
None = -1,
Reinitialized = 0,
TextureSizeChanged = 1,
TextureSizeChanged = 1,
};
void SendMessageToUnity(Message message);

View File

@@ -54,25 +54,26 @@ void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
apiBuffer_ = std::make_unique<BYTE[]>(apiBufferSize_);
}
if (!apiBuffer_)
{
return;
}
if (!apiBuffer_)
{
return;
}
// Get mouse pointer information
UINT bufferSize;
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo;
const auto hr = monitor_->GetDeskDupl()->GetFramePointerShape(
apiBufferSize_,
apiBuffer_.get(),
&bufferSize,
&shapeInfo);
const auto hr = monitor_->GetDeskDupl()->GetFramePointerShape(
apiBufferSize_,
apiBuffer_.get(),
&bufferSize,
&shapeInfo);
if (FAILED(hr))
{
Debug::Error("Cursor::UpdateBuffer() => GetFramePointerShape() failed.");
apiBuffer_.reset();
apiBufferSize_ = 0;
return;
}
shapeInfo_ = shapeInfo;
@@ -104,7 +105,16 @@ void Cursor::UpdateTexture()
bgra32BufferSize_ = bgraBufferSize;
bgra32Buffer_ = std::make_unique<BYTE[]>(bgra32BufferSize_);
}
if (!bgra32Buffer_) return;
if (!bgra32Buffer_)
{
return;
}
if (!apiBuffer_)
{
return;
}
// If masked, copy the desktop image and merge it with masked image.
if (isMono || isColorMask)
@@ -175,11 +185,11 @@ void Cursor::UpdateTexture()
return;
}
{
ComPtr<ID3D11DeviceContext> context;
GetDevice()->GetImmediateContext(&context);
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
}
{
ComPtr<ID3D11DeviceContext> context;
GetDevice()->GetImmediateContext(&context);
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor_->GetUnityTexture(), 0, &box);
}
ComPtr<IDXGISurface> surface;
if (FAILED(texture.As(&surface)))

View File

@@ -28,6 +28,6 @@ void Debug::Finalize()
Debug::Log("Stop");
fs_.close();
}
Debug::SetLogFunc(nullptr);
Debug::SetErrorFunc(nullptr);
Debug::SetLogFunc(nullptr);
Debug::SetErrorFunc(nullptr);
}

View File

@@ -87,34 +87,34 @@ private:
Flush(level);
}
static void OutputTime()
{
auto t = time(nullptr);
tm tm;
localtime_s(&tm, &t);
char buf[64];
strftime(buf, 64, "%F %T", &tm);
static void OutputTime()
{
auto t = time(nullptr);
tm tm;
localtime_s(&tm, &t);
char buf[64];
strftime(buf, 64, "%F %T", &tm);
Output("[");;
Output(buf);
Output("]");
}
}
public:
template <class Arg, class... RestArgs>
static void Log(Arg&& arg, RestArgs&&... restArgs)
{
Output("[uDD::Log]");
OutputTime();
Output(" ");
Output("[uDD::Log]");
OutputTime();
Output(" ");
_Log(Level::Log, std::forward<Arg>(arg), std::forward<RestArgs>(restArgs)...);
}
template <class Arg, class... RestArgs>
static void Error(Arg&& arg, RestArgs&&... restArgs)
{
Output("[uDD::Err]");
OutputTime();
Output(" ");
Output("[uDD::Err]");
OutputTime();
Output(" ");
_Log(Level::Error, std::forward<Arg>(arg), std::forward<RestArgs>(restArgs)...);
}

View File

@@ -18,94 +18,94 @@ Monitor::Monitor(int id)
Monitor::~Monitor()
{
if (deskDupl_)
{
deskDupl_->Release();
deskDupl_ = nullptr;
}
if (deskDupl_)
{
deskDupl_->Release();
deskDupl_ = nullptr;
}
}
void Monitor::Initialize(IDXGIOutput* output)
{
if (FAILED(output->GetDesc(&outputDesc_)))
{
Debug::Error("Monitor::Initialize() => IDXGIOutput::GetDesc() failed.");
return;
}
if (FAILED(output->GetDesc(&outputDesc_)))
{
Debug::Error("Monitor::Initialize() => IDXGIOutput::GetDesc() failed.");
return;
}
monitorInfo_.cbSize = sizeof(MONITORINFOEX);
if (!GetMonitorInfo(outputDesc_.Monitor, &monitorInfo_))
{
Debug::Error("Monitor::Initialize() => GetMonitorInfo() failed.");
return;
}
else
{
const auto rect = monitorInfo_.rcMonitor;
width_ = rect.right - rect.left;
height_ = rect.bottom - rect.top;
}
if (!GetMonitorInfo(outputDesc_.Monitor, &monitorInfo_))
{
Debug::Error("Monitor::Initialize() => GetMonitorInfo() failed.");
return;
}
else
{
const auto rect = monitorInfo_.rcMonitor;
width_ = rect.right - rect.left;
height_ = rect.bottom - rect.top;
}
if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_)))
{
Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed.");
return;
}
if (FAILED(GetDpiForMonitor(outputDesc_.Monitor, MDT_RAW_DPI, &dpiX_, &dpiY_)))
{
Debug::Error("Monitor::Initialize() => GetDpiForMonitor() failed.");
return;
}
auto output1 = reinterpret_cast<IDXGIOutput1*>(output);
switch (output1->DuplicateOutput(GetDevice().Get(), &deskDupl_))
{
case S_OK:
{
state_ = State::Available;
Debug::Log("Monitor::Initialize() => OK.");
Debug::Log(" ID : ", GetId());
Debug::Log(" Size : (", GetWidth(), ", ", GetHeight(), ")");
Debug::Log(" DPI : (", GetDpiX(), ", ", GetDpiY(), ")");
break;
}
{
state_ = State::Available;
Debug::Log("Monitor::Initialize() => OK.");
Debug::Log(" ID : ", GetId());
Debug::Log(" Size : (", GetWidth(), ", ", GetHeight(), ")");
Debug::Log(" DPI : (", GetDpiX(), ", ", GetDpiY(), ")");
break;
}
case E_INVALIDARG:
{
state_ = State::InvalidArg;
Debug::Error("Monitor::Initialize() => Invalid arguments.");
break;
}
{
state_ = State::InvalidArg;
Debug::Error("Monitor::Initialize() => Invalid arguments.");
break;
}
case E_ACCESSDENIED:
{
// For example, when the user presses Ctrl + Alt + Delete and the screen
// switches to admin screen, this error occurs.
state_ = State::AccessDenied;
Debug::Error("Monitor::Initialize() => Access denied.");
break;
}
{
// For example, when the user presses Ctrl + Alt + Delete and the screen
// switches to admin screen, this error occurs.
state_ = State::AccessDenied;
Debug::Error("Monitor::Initialize() => Access denied.");
break;
}
case DXGI_ERROR_UNSUPPORTED:
{
// If the display adapter on the computer is running under the Microsoft Hybrid system,
// this error occurs.
state_ = State::Unsupported;
Debug::Error("Monitor::Initialize() => Unsupported display.");
break;
}
{
// If the display adapter on the computer is running under the Microsoft Hybrid system,
// this error occurs.
state_ = State::Unsupported;
Debug::Error("Monitor::Initialize() => Unsupported display.");
break;
}
case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
{
// When other application use Desktop Duplication API, this error occurs.
state_ = State::CurrentlyNotAvailable;
Debug::Error("Monitor::Initialize() => Currently not available.");
break;
}
{
// When other application use Desktop Duplication API, this error occurs.
state_ = State::CurrentlyNotAvailable;
Debug::Error("Monitor::Initialize() => Currently not available.");
break;
}
case DXGI_ERROR_SESSION_DISCONNECTED:
{
{
state_ = State::SessionDisconnected;
Debug::Error("Monitor::Initialize() => Session disconnected.");
break;
}
break;
}
default:
{
state_ = State::Unknown;
Debug::Error("Monitor::Render() => Unknown Error.");
break;
}
{
state_ = State::Unknown;
Debug::Error("Monitor::Render() => Unknown Error.");
break;
}
}
}
@@ -123,35 +123,35 @@ void Monitor::Render(UINT timeout)
switch (hr)
{
case DXGI_ERROR_ACCESS_LOST:
{
// If any monitor setting has changed (e.g. monitor size has changed),
// it is necessary to re-initialize monitors.
Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST.");
state_ = State::AccessLost;
break;
}
{
// If any monitor setting has changed (e.g. monitor size has changed),
// it is necessary to re-initialize monitors.
Debug::Log("Monitor::Render() => DXGI_ERROR_ACCESS_LOST.");
state_ = State::AccessLost;
break;
}
case DXGI_ERROR_WAIT_TIMEOUT:
{
// This often occurs when timeout value is small and it is not problem.
// Debug::Log("Monitor::Render() => DXGI_ERROR_WAIT_TIMEOUT.");
break;
}
{
// This often occurs when timeout value is small and it is not problem.
// Debug::Log("Monitor::Render() => DXGI_ERROR_WAIT_TIMEOUT.");
break;
}
case DXGI_ERROR_INVALID_CALL:
{
Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL.");
break;
}
{
Debug::Error("Monitor::Render() => DXGI_ERROR_INVALID_CALL.");
break;
}
case E_INVALIDARG:
{
Debug::Error("Monitor::Render() => E_INVALIDARG.");
break;
}
{
Debug::Error("Monitor::Render() => E_INVALIDARG.");
break;
}
default:
{
state_ = State::Unknown;
Debug::Error("Monitor::Render() => Unknown Error.");
break;
}
{
state_ = State::Unknown;
Debug::Error("Monitor::Render() => Unknown Error.");
break;
}
}
return;
}
@@ -159,11 +159,11 @@ void Monitor::Render(UINT timeout)
if (unityTexture_)
{
ID3D11Texture2D* texture;
if (FAILED(resource.CopyTo(&texture)))
{
Debug::Error("Monitor::Render() => resource.As() failed.");
return;
}
if (FAILED(resource.CopyTo(&texture)))
{
Debug::Error("Monitor::Render() => resource.As() failed.");
return;
}
D3D11_TEXTURE2D_DESC srcDesc, dstDesc;
texture->GetDesc(&srcDesc);
@@ -175,10 +175,10 @@ void Monitor::Render(UINT timeout)
Debug::Error(" Source : (", srcDesc.Width, ", ", srcDesc.Height, ")");
Debug::Error(" Dest : (", dstDesc.Width, ", ", dstDesc.Height, ")");
//Debug::Log(" => Try modifying width/height using reported value from DDA.");
//width_ = srcDesc.Width;
//height_ = srcDesc.Height;
state_ = MonitorState::TextureSizeInconsistent;
//SendMessageToUnity(Message::TextureSizeChanged);
//width_ = srcDesc.Width;
//height_ = srcDesc.Height;
state_ = MonitorState::TextureSizeInconsistent;
//SendMessageToUnity(Message::TextureSizeChanged);
}
else
{
@@ -296,11 +296,11 @@ int Monitor::GetDpiY() const
int Monitor::GetWidth() const
{
return width_;
return width_;
}
int Monitor::GetHeight() const
{
return height_;
return height_;
}

View File

@@ -17,7 +17,7 @@ enum class MonitorState
CurrentlyNotAvailable = 4,
SessionDisconnected = 5,
AccessLost = 6,
TextureSizeInconsistent = 7,
TextureSizeInconsistent = 7,
Unknown = 999,
};
@@ -54,7 +54,7 @@ public:
private:
int id_ = -1;
UINT dpiX_ = -1, dpiY_ = -1;
int width_ = -1, height_ = -1;
int width_ = -1, height_ = -1;
State state_ = State::NotSet;
std::unique_ptr<Cursor> cursor_;
IDXGIOutputDuplication* deskDupl_ = nullptr;

View File

@@ -35,11 +35,11 @@ void MonitorManager::Initialize()
// Get factory
ComPtr<IDXGIFactory1> factory;
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
{
Debug::Error("MonitorManager::Initialize() => CreateDXGIFactory1() failed.");
return;
}
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
{
Debug::Error("MonitorManager::Initialize() => CreateDXGIFactory1() failed.");
return;
}
// Check all display adapters
int id = 0;
@@ -47,7 +47,7 @@ void MonitorManager::Initialize()
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
{
// Search the main monitor from all outputs
ComPtr<IDXGIOutput> output;
ComPtr<IDXGIOutput> output;
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
{
auto monitor = std::make_shared<Monitor>(id++);
@@ -81,24 +81,24 @@ void MonitorManager::Reinitialize()
bool MonitorManager::HasMonitorCountChanged() const
{
ComPtr<IDXGIFactory1> factory;
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
{
Debug::Error("MonitorManager::CheckMonitorConnection() => CreateDXGIFactory1() failed.");
return false;
}
if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
{
Debug::Error("MonitorManager::CheckMonitorConnection() => CreateDXGIFactory1() failed.");
return false;
}
int id = 0;
ComPtr<IDXGIAdapter1> adapter;
for (int i = 0; (factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND); ++i)
{
ComPtr<IDXGIOutput> output;
ComPtr<IDXGIOutput> output;
for (int j = 0; (adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND); ++j)
{
id++;
}
}
return monitors_.size() != id;
return monitors_.size() != id;
}