refactoring.
This commit is contained in:
Binary file not shown.
@@ -40,8 +40,8 @@ void Cursor::UpdateBuffer(Monitor* monitor, const DXGI_OUTDUPL_FRAME_INFO& frame
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
apiBuffer_.ExpandIfNeeded(frameInfo.PointerShapeBufferSize);
|
buffer_.ExpandIfNeeded(frameInfo.PointerShapeBufferSize);
|
||||||
if (!apiBuffer_)
|
if (!buffer_)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -50,15 +50,15 @@ void Cursor::UpdateBuffer(Monitor* monitor, const DXGI_OUTDUPL_FRAME_INFO& frame
|
|||||||
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(
|
||||||
apiBuffer_.Size(),
|
buffer_.Size(),
|
||||||
apiBuffer_.Get(),
|
buffer_.Get(),
|
||||||
&bufferSize,
|
&bufferSize,
|
||||||
&shapeInfo);
|
&shapeInfo);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
Debug::Error("Cursor::UpdateBuffer() => GetFramePointerShape() failed.");
|
Debug::Error("Cursor::UpdateBuffer() => GetFramePointerShape() failed.");
|
||||||
apiBuffer_.Reset();
|
buffer_.Reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,137 +76,143 @@ void Cursor::Draw(Monitor* monitor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cursor information
|
// Cursor information
|
||||||
const auto cursorImageWidth = GetWidth();
|
const auto cursorImageWidth = GetWidth();
|
||||||
const auto cursorImageHeight = GetHeight();
|
const auto cursorImageHeight = GetHeight();
|
||||||
const auto cursorImagePitch = GetPitch();
|
const auto cursorImagePitch = GetPitch();
|
||||||
|
|
||||||
// Captured size
|
// Monitor orientation
|
||||||
auto capturedImageWidth = cursorImageWidth;
|
const auto monitorRot = static_cast<DXGI_MODE_ROTATION>(monitor->GetRotation());
|
||||||
auto capturedImageHeight = cursorImageHeight;
|
const auto isMonitorPortrait =
|
||||||
|
monitorRot == DXGI_MODE_ROTATION_ROTATE90 ||
|
||||||
|
monitorRot == DXGI_MODE_ROTATION_ROTATE270;
|
||||||
|
|
||||||
|
// Captured size (desktop cooridinates).
|
||||||
|
auto capturedImageWidth = !isMonitorPortrait ? cursorImageWidth : cursorImageHeight;
|
||||||
|
auto capturedImageHeight = !isMonitorPortrait ? cursorImageHeight : cursorImageWidth;
|
||||||
|
|
||||||
// Convert the buffer given by API into BGRA32
|
// Convert the buffer given by API into BGRA32
|
||||||
const UINT bgraBufferSize = cursorImageWidth * cursorImageHeight * 4;
|
const UINT bgraBufferSize = cursorImageWidth * cursorImageHeight * 4;
|
||||||
bgraBuffer_.ExpandIfNeeded(bgraBufferSize);
|
bgraBuffer_.ExpandIfNeeded(bgraBufferSize);
|
||||||
|
|
||||||
// Check buffers
|
// Check buffers
|
||||||
if (!bgraBuffer_ || !apiBuffer_)
|
if (!bgraBuffer_ || !buffer_)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate information to capture desktop image under cursor.
|
// Desktop size
|
||||||
D3D11_BOX box;
|
const int monitorWidth = monitor->GetWidth();
|
||||||
const auto monitorRot = static_cast<DXGI_MODE_ROTATION>(monitor->GetRotation());
|
const int monitorHeight = monitor->GetHeight();
|
||||||
auto colMin = 0;
|
const int desktopImageWidth = !isMonitorPortrait ? monitorWidth : monitorHeight;
|
||||||
auto colMax = cursorImageWidth;
|
const int desktopImageHeight = !isMonitorPortrait ? monitorHeight : monitorWidth;
|
||||||
auto rowMin = 0;
|
|
||||||
auto rowMax = cursorImageHeight;
|
|
||||||
|
|
||||||
|
// x_, y_ are cooridinates in rotated monitor.
|
||||||
|
// desktopX, desktopY are coordinates in captured desktop image (always landscape).
|
||||||
|
int desktopX, desktopY;
|
||||||
|
switch (monitorRot)
|
||||||
{
|
{
|
||||||
const auto monitorWidth = monitor->GetWidth();
|
case DXGI_MODE_ROTATION_ROTATE90:
|
||||||
const auto monitorHeight = monitor->GetHeight();
|
|
||||||
const auto isVertical =
|
|
||||||
monitorRot == DXGI_MODE_ROTATION_ROTATE90 ||
|
|
||||||
monitorRot == DXGI_MODE_ROTATION_ROTATE270;
|
|
||||||
const auto desktopImageWidth = !isVertical ? monitorWidth : monitorHeight;
|
|
||||||
const auto desktopImageHeight = !isVertical ? monitorHeight : monitorWidth;
|
|
||||||
|
|
||||||
auto x = x_;
|
|
||||||
auto y = y_;
|
|
||||||
|
|
||||||
if (x < 0)
|
|
||||||
{
|
{
|
||||||
x = 0;
|
desktopX = y_;
|
||||||
capturedImageWidth = cursorImageWidth + x_;
|
desktopY = (desktopImageHeight - 1) - x_ - cursorImageWidth;
|
||||||
colMin = cursorImageWidth - capturedImageWidth;
|
break;
|
||||||
}
|
}
|
||||||
if (x + capturedImageWidth >= monitorWidth)
|
case DXGI_MODE_ROTATION_ROTATE180:
|
||||||
{
|
{
|
||||||
capturedImageWidth = monitorWidth - x_;
|
desktopX = (desktopImageWidth - 1) - x_ - cursorImageWidth;
|
||||||
colMax = capturedImageWidth;
|
desktopY = (desktopImageHeight - 1) - y_ - cursorImageHeight;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (y < 0)
|
case DXGI_MODE_ROTATION_ROTATE270:
|
||||||
{
|
{
|
||||||
y = 0;
|
desktopX = (desktopImageWidth - 1) - y_ - cursorImageHeight;
|
||||||
capturedImageHeight = cursorImageHeight + y_;
|
desktopY = x_;
|
||||||
rowMin = cursorImageHeight - capturedImageHeight;
|
break;
|
||||||
}
|
}
|
||||||
if (y + capturedImageHeight >= monitorHeight)
|
case DXGI_MODE_ROTATION_IDENTITY:
|
||||||
|
case DXGI_MODE_ROTATION_UNSPECIFIED:
|
||||||
|
default:
|
||||||
{
|
{
|
||||||
capturedImageHeight = monitorHeight - y_;
|
desktopX = x_;
|
||||||
rowMax = capturedImageHeight;
|
desktopY = y_;
|
||||||
}
|
break;
|
||||||
|
|
||||||
box.front = 0;
|
|
||||||
box.back = 1;
|
|
||||||
|
|
||||||
switch (monitorRot)
|
|
||||||
{
|
|
||||||
case DXGI_MODE_ROTATION_ROTATE90:
|
|
||||||
{
|
|
||||||
box.left = y;
|
|
||||||
box.top = monitorWidth - x - capturedImageWidth;
|
|
||||||
box.right = y + capturedImageWidth;
|
|
||||||
box.bottom = monitorWidth - x;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DXGI_MODE_ROTATION_ROTATE180:
|
|
||||||
{
|
|
||||||
box.left = monitorWidth - x - capturedImageWidth;
|
|
||||||
box.top = monitorHeight - y - capturedImageHeight;
|
|
||||||
box.right = monitorWidth - x;
|
|
||||||
box.bottom = monitorHeight - y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DXGI_MODE_ROTATION_ROTATE270:
|
|
||||||
{
|
|
||||||
box.left = monitorHeight - y - capturedImageHeight;
|
|
||||||
box.top = x;
|
|
||||||
box.right = monitorHeight - y;
|
|
||||||
box.bottom = x + capturedImageWidth;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DXGI_MODE_ROTATION_IDENTITY:
|
|
||||||
case DXGI_MODE_ROTATION_UNSPECIFIED:
|
|
||||||
{
|
|
||||||
box.left = x;
|
|
||||||
box.top = y;
|
|
||||||
box.right = x + capturedImageWidth;
|
|
||||||
box.bottom = y + capturedImageHeight;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (box.left < 0 ||
|
|
||||||
box.top < 0 ||
|
|
||||||
box.right > static_cast<UINT>(desktopImageWidth) ||
|
|
||||||
box.bottom > static_cast<UINT>(desktopImageHeight))
|
|
||||||
{
|
|
||||||
Debug::Error("Cursor::UpdateTexture() => box is out of area.");
|
|
||||||
Debug::Error(
|
|
||||||
" ",
|
|
||||||
"(", box.left, ", ", box.top, ")",
|
|
||||||
" ~ (", box.right, ", ", box.bottom, ") > ",
|
|
||||||
"(", desktopImageWidth, ", ", desktopImageHeight, ")");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create texture
|
// Calculate information to capture desktop image under cursor.
|
||||||
|
int cursorOffsetX = 0;
|
||||||
|
int cursorOffsetY = 0;
|
||||||
|
int capturedImageLeft = desktopX;
|
||||||
|
int capturedImageTop = desktopY;
|
||||||
|
int capturedImageRight = desktopX + capturedImageWidth;
|
||||||
|
int capturedImageBottom = desktopY + capturedImageHeight;
|
||||||
|
|
||||||
|
if (capturedImageLeft < 0)
|
||||||
|
{
|
||||||
|
capturedImageWidth -= -desktopX;
|
||||||
|
cursorOffsetX = -desktopX;
|
||||||
|
capturedImageLeft = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capturedImageRight >= desktopImageWidth)
|
||||||
|
{
|
||||||
|
capturedImageWidth -= capturedImageRight - desktopImageWidth;
|
||||||
|
capturedImageRight = desktopImageWidth - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capturedImageTop < 0)
|
||||||
|
{
|
||||||
|
capturedImageHeight -= -desktopY;
|
||||||
|
cursorOffsetY = -desktopY;
|
||||||
|
capturedImageTop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capturedImageBottom >= monitorHeight)
|
||||||
|
{
|
||||||
|
capturedImageHeight -= capturedImageBottom - desktopImageHeight;
|
||||||
|
capturedImageBottom = desktopImageHeight - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if box is inner desktop area
|
||||||
|
if (capturedImageLeft < 0 ||
|
||||||
|
capturedImageTop < 0 ||
|
||||||
|
capturedImageRight > desktopImageWidth ||
|
||||||
|
capturedImageBottom > desktopImageHeight)
|
||||||
|
{
|
||||||
|
Debug::Error("Cursor::UpdateTexture() => box is out of area.");
|
||||||
|
Debug::Error(
|
||||||
|
" ",
|
||||||
|
"(", capturedImageLeft, ", ", capturedImageTop, ")",
|
||||||
|
" ~ (", capturedImageRight, ", ", capturedImageBottom, ") > ",
|
||||||
|
"(", desktopImageWidth, ", ", desktopImageHeight, ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_BOX capturedImageArea
|
||||||
|
{
|
||||||
|
static_cast<UINT>(capturedImageLeft),
|
||||||
|
static_cast<UINT>(capturedImageTop),
|
||||||
|
0,
|
||||||
|
static_cast<UINT>(capturedImageRight),
|
||||||
|
static_cast<UINT>(capturedImageBottom),
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create texture for capturing desktop image
|
||||||
ComPtr<ID3D11Texture2D> texture;
|
ComPtr<ID3D11Texture2D> texture;
|
||||||
{
|
{
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
desc.Width = capturedImageWidth;
|
desc.Width = capturedImageWidth;
|
||||||
desc.Height = capturedImageHeight;
|
desc.Height = capturedImageHeight;
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
desc.ArraySize = 1;
|
desc.ArraySize = 1;
|
||||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
desc.SampleDesc.Count = 1;
|
desc.SampleDesc.Count = 1;
|
||||||
desc.SampleDesc.Quality = 0;
|
desc.SampleDesc.Quality = 0;
|
||||||
desc.Usage = D3D11_USAGE_STAGING;
|
desc.Usage = D3D11_USAGE_STAGING;
|
||||||
desc.BindFlags = 0;
|
desc.BindFlags = 0;
|
||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
desc.MiscFlags = 0;
|
desc.MiscFlags = 0;
|
||||||
|
|
||||||
if (FAILED(GetDevice()->CreateTexture2D(&desc, nullptr, &texture)))
|
if (FAILED(GetDevice()->CreateTexture2D(&desc, nullptr, &texture)))
|
||||||
{
|
{
|
||||||
@@ -219,14 +225,14 @@ void Cursor::Draw(Monitor* monitor)
|
|||||||
{
|
{
|
||||||
ComPtr<ID3D11DeviceContext> context;
|
ComPtr<ID3D11DeviceContext> context;
|
||||||
GetDevice()->GetImmediateContext(&context);
|
GetDevice()->GetImmediateContext(&context);
|
||||||
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor->GetUnityTexture(), 0, &box);
|
context->CopySubresourceRegion(texture.Get(), 0, 0, 0, 0, monitor->GetUnityTexture(), 0, &capturedImageArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get mapped surface
|
// Get mapped surface to access pixels in CPU
|
||||||
ComPtr<IDXGISurface> surface;
|
ComPtr<IDXGISurface> surface;
|
||||||
if (FAILED(texture.As(&surface)))
|
if (FAILED(texture.As(&surface)))
|
||||||
{
|
{
|
||||||
Debug::Error("Cursor::UpdateTexture() => texture->QueryInterface() failed.");
|
Debug::Error("Cursor::UpdateTexture() => texture.As() failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,135 +247,108 @@ void Cursor::Draw(Monitor* monitor)
|
|||||||
const auto desktop32 = reinterpret_cast<UINT*>(mappedSurface.pBits);
|
const auto desktop32 = reinterpret_cast<UINT*>(mappedSurface.pBits);
|
||||||
const UINT desktopPitch = mappedSurface.Pitch / sizeof(UINT);
|
const UINT desktopPitch = mappedSurface.Pitch / sizeof(UINT);
|
||||||
|
|
||||||
// Take the monitor orientation into consideration.
|
// Rotate cursor image to match the monitor orientation
|
||||||
const auto getDesktop32 = [&](int col, int row)
|
Buffer<BYTE> rotatedBuffer_;
|
||||||
|
rotatedBuffer_.ExpandIfNeeded(buffer_.Size());
|
||||||
|
|
||||||
|
for (int y = 0; y < capturedImageHeight; ++y)
|
||||||
{
|
{
|
||||||
switch (monitorRot)
|
for (int x = 0; x < capturedImageWidth; ++x)
|
||||||
{
|
{
|
||||||
case DXGI_MODE_ROTATION_ROTATE90:
|
// Cursor coordinates
|
||||||
return desktop32[(capturedImageWidth - 1 - col) * desktopPitch + row];
|
int cursorX, cursorY;
|
||||||
case DXGI_MODE_ROTATION_ROTATE180:
|
|
||||||
return desktop32[(capturedImageHeight - 1 - row) * desktopPitch + (capturedImageWidth - 1 - col)];
|
|
||||||
case DXGI_MODE_ROTATION_ROTATE270:
|
|
||||||
return desktop32[col * desktopPitch + (capturedImageHeight - 1 - row)];
|
|
||||||
case DXGI_MODE_ROTATION_IDENTITY:
|
|
||||||
case DXGI_MODE_ROTATION_UNSPECIFIED:
|
|
||||||
default:
|
|
||||||
return desktop32[row * desktopPitch + col];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Buffer<BYTE> output;
|
switch (monitorRot)
|
||||||
output.ExpandIfNeeded(bgraBuffer_.Size());
|
|
||||||
|
|
||||||
// Access RGBA values at the same time
|
|
||||||
auto output32 = output.As<UINT>();
|
|
||||||
|
|
||||||
switch (GetType())
|
|
||||||
{
|
|
||||||
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME:
|
|
||||||
{
|
|
||||||
for (int row = rowMin, y = 0; row < rowMax; ++row, ++y)
|
|
||||||
{
|
{
|
||||||
for (int col = colMin, x = 0; col < colMax; ++col, ++x)
|
case DXGI_MODE_ROTATION_ROTATE90:
|
||||||
{
|
{
|
||||||
const int i = col + row * cursorImageWidth;
|
cursorX = (cursorImageWidth - 1) - (y + cursorOffsetY);
|
||||||
|
cursorY = (x + cursorOffsetX);
|
||||||
BYTE mask = 0b10000000 >> (col % 8);
|
break;
|
||||||
const BYTE andMask = apiBuffer_[col / 8 + row * cursorImagePitch] & mask;
|
}
|
||||||
const BYTE xorMask = apiBuffer_[col / 8 + (row + cursorImageHeight) * cursorImagePitch] & mask;
|
case DXGI_MODE_ROTATION_ROTATE180:
|
||||||
const UINT andMask32 = andMask ? 0xFFFFFFFF : 0x00000000;
|
{
|
||||||
const UINT xorMask32 = xorMask ? 0xFFFFFFFF : 0x00000000;
|
cursorX = (cursorImageWidth - 1) - (x + cursorOffsetX);
|
||||||
|
cursorY = (cursorImageHeight - 1) - (y + cursorOffsetY);
|
||||||
output32[i] = (getDesktop32(x, y) & andMask32) ^ xorMask32;
|
break;
|
||||||
|
}
|
||||||
|
case DXGI_MODE_ROTATION_ROTATE270:
|
||||||
|
{
|
||||||
|
cursorX = (y + cursorOffsetY);
|
||||||
|
cursorY = (cursorImageHeight - 1) - (x + cursorOffsetX);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DXGI_MODE_ROTATION_IDENTITY:
|
||||||
|
case DXGI_MODE_ROTATION_UNSPECIFIED:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
cursorX = (x + cursorOffsetX);
|
||||||
|
cursorY = (y + cursorOffsetY);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR:
|
|
||||||
{
|
|
||||||
const auto buffer32 = apiBuffer_.As<UINT>();
|
|
||||||
|
|
||||||
for (int row = rowMin, y = 0; row < rowMax; ++row, ++y)
|
const auto outputIndex = y * capturedImageWidth + x;
|
||||||
|
const auto desktopIndex = y * desktopPitch + x;
|
||||||
|
const auto cursorIndex = cursorY * cursorImageWidth + cursorX;
|
||||||
|
const auto buffer32 = buffer_.As<UINT>();
|
||||||
|
auto output32 = bgraBuffer_.As<UINT>();
|
||||||
|
|
||||||
|
switch (GetType())
|
||||||
{
|
{
|
||||||
for (int col = colMin, x = 0; col < colMax; ++col, ++x)
|
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME:
|
||||||
{
|
{
|
||||||
const int i = col + row * cursorImageWidth;
|
BYTE mask = 0b10000000 >> (cursorX % 8);
|
||||||
const int j = col + row * cursorImagePitch / sizeof(UINT);
|
const BYTE andMask = buffer_[cursorX / 8 + cursorY * cursorImagePitch] & mask;
|
||||||
|
const BYTE xorMask = buffer_[cursorX / 8 + (cursorY + cursorImageHeight) * cursorImagePitch] & mask;
|
||||||
UINT mask = 0xFF000000 & buffer32[j];
|
const UINT andMask32 = andMask ? 0xFFFFFFFF : 0x00000000;
|
||||||
|
const UINT xorMask32 = xorMask ? 0xFFFFFFFF : 0x00000000;
|
||||||
|
output32[outputIndex] = (desktop32[desktopIndex] & andMask32) ^ xorMask32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR:
|
||||||
|
{
|
||||||
|
UINT mask = 0xFF000000 & buffer32[cursorIndex];
|
||||||
if (mask)
|
if (mask)
|
||||||
{
|
{
|
||||||
output32[i] = (getDesktop32(x, y) ^ buffer32[j]) | 0xFF000000;
|
output32[outputIndex] = (desktop32[desktopIndex] ^ buffer32[cursorIndex]) | 0xFF000000;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output32[i] = buffer32[j] | 0xFF000000;
|
output32[outputIndex] = buffer32[cursorIndex] | 0xFF000000;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR:
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR:
|
|
||||||
{
|
|
||||||
for (int row = rowMin, y = 0; row < rowMax; ++row, ++y)
|
|
||||||
{
|
|
||||||
for (int col = colMin, x = 0; col < colMax; ++col, ++x)
|
|
||||||
{
|
{
|
||||||
const int i = 4 * (col + row * cursorImageWidth);
|
const auto desktop = reinterpret_cast<BYTE*>(&desktop32[desktopIndex]);
|
||||||
|
|
||||||
const auto desktop32 = getDesktop32(x, y);
|
|
||||||
const auto desktop = (BYTE*)(&desktop32);
|
|
||||||
const auto desktopB = desktop[0];
|
const auto desktopB = desktop[0];
|
||||||
const auto desktopG = desktop[1];
|
const auto desktopG = desktop[1];
|
||||||
const auto desktopR = desktop[2];
|
const auto desktopR = desktop[2];
|
||||||
const auto desktopA = desktop[3];
|
const auto desktopA = desktop[3];
|
||||||
|
|
||||||
const auto cursorB = apiBuffer_[i + 0];
|
const auto cursor = buffer_.Get(cursorIndex * 4);
|
||||||
const auto cursorG = apiBuffer_[i + 1];
|
const auto cursorB = cursor[0];
|
||||||
const auto cursorR = apiBuffer_[i + 2];
|
const auto cursorG = cursor[1];
|
||||||
const auto cursorA = apiBuffer_[i + 3];
|
const auto cursorR = cursor[2];
|
||||||
|
const auto cursorA = cursor[3];
|
||||||
|
|
||||||
const auto a0 = cursorA / 255.f;
|
const auto a0 = cursorA / 255.f;
|
||||||
const auto a1 = 1.f - a0;
|
const auto a1 = 1.f - a0;
|
||||||
|
|
||||||
output[i + 0] = static_cast<BYTE>(cursorB * a0 + desktopB * a1);
|
auto output = reinterpret_cast<BYTE*>(&output32[outputIndex]);
|
||||||
output[i + 1] = static_cast<BYTE>(cursorG * a0 + desktopG * a1);
|
output[0] = static_cast<BYTE>(cursorB * a0 + desktopB * a1);
|
||||||
output[i + 2] = static_cast<BYTE>(cursorR * a0 + desktopR * a1);
|
output[1] = static_cast<BYTE>(cursorG * a0 + desktopG * a1);
|
||||||
output[i + 3] = desktopA;
|
output[2] = static_cast<BYTE>(cursorR * a0 + desktopR * a1);
|
||||||
}
|
output[3] = desktopA;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
Debug::Error("Cursor::UpdateTexture() => Unknown cursor type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotation
|
|
||||||
auto bgraBuffer32 = bgraBuffer_.As<UINT>();
|
|
||||||
for (int row = rowMin, y = 0; row < rowMax; ++row, ++y)
|
|
||||||
{
|
|
||||||
for (int col = colMin, x = 0; col < colMax; ++col, ++x)
|
|
||||||
{
|
|
||||||
const auto i = col + row * cursorImageWidth;
|
|
||||||
switch (monitorRot)
|
|
||||||
{
|
|
||||||
case DXGI_MODE_ROTATION_ROTATE90:
|
|
||||||
bgraBuffer32[i] = output32[col * cursorImageHeight + (cursorImageHeight - 1 - row)];
|
|
||||||
break;
|
|
||||||
case DXGI_MODE_ROTATION_ROTATE180:
|
|
||||||
bgraBuffer32[i] = output32[(cursorImageHeight - 1 - row) * cursorImageWidth + (cursorImageWidth - 1 - col)];
|
|
||||||
break;
|
|
||||||
case DXGI_MODE_ROTATION_ROTATE270:
|
|
||||||
bgraBuffer32[i] = output32[(cursorImageWidth - 1 - col) * cursorImageHeight + row];
|
|
||||||
break;
|
|
||||||
case DXGI_MODE_ROTATION_IDENTITY:
|
|
||||||
case DXGI_MODE_ROTATION_UNSPECIFIED:
|
|
||||||
bgraBuffer32[i] = output32[i];
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Debug::Error("Cursor::UpdateTexture() => Unknown cursor type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -377,7 +356,7 @@ void Cursor::Draw(Monitor* monitor)
|
|||||||
{
|
{
|
||||||
ComPtr<ID3D11DeviceContext> context;
|
ComPtr<ID3D11DeviceContext> context;
|
||||||
GetDevice()->GetImmediateContext(&context);
|
GetDevice()->GetImmediateContext(&context);
|
||||||
context->UpdateSubresource(monitor->GetUnityTexture(), 0, &box, bgraBuffer_.Get(), GetWidth() * 4, 0);
|
context->UpdateSubresource(monitor->GetUnityTexture(), 0, &capturedImageArea, bgraBuffer_.Get(), capturedImageWidth * 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(surface->Unmap()))
|
if (FAILED(surface->Unmap()))
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ private:
|
|||||||
bool isVisible_ = false;
|
bool isVisible_ = false;
|
||||||
int x_ = -1;
|
int x_ = -1;
|
||||||
int y_ = -1;
|
int y_ = -1;
|
||||||
Buffer<BYTE> apiBuffer_;
|
Buffer<BYTE> buffer_;
|
||||||
Buffer<BYTE> bgraBuffer_;
|
Buffer<BYTE> bgraBuffer_;
|
||||||
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo_;
|
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo_;
|
||||||
LARGE_INTEGER timestamp_;
|
LARGE_INTEGER timestamp_;
|
||||||
|
|||||||
Reference in New Issue
Block a user