[host] Numerous performance improvements and minor bug fixes

This commit is contained in:
Geoffrey McRae
2017-12-05 20:39:54 +11:00
parent c1a82e853d
commit 0b290d83d3
8 changed files with 156 additions and 72 deletions

View File

@@ -19,6 +19,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "DXGI.h"
using namespace Capture;
#include "Util.h"
#include "common\debug.h"
#include "common\memcpySSE.h"
@@ -360,68 +361,46 @@ bool DXGI::GrabFrame(FrameInfo & frame)
{
m_pointerVisible = frameInfo.PointerPosition.Visible;
m_pointerPos = frameInfo.PointerPosition.Position;
}
// if the pointer is to be drawn
if (m_pointerVisible)
{
const int maxHeight = min(m_shapeInfo.Height, desc.Height - m_pointerPos.y);
const int maxWidth = min(m_shapeInfo.Width , desc.Width - m_pointerPos.x);
switch (m_shapeInfo.Type)
{
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR:
{
for(int y = abs(min(0, m_pointerPos.y)); y < maxHeight; ++y)
for (int x = abs(min(0, m_pointerPos.x)); x < maxWidth; ++x)
{
BYTE *src = (BYTE *)m_pointer + (m_shapeInfo.Pitch * y) + (x * 4);
BYTE *dst = (BYTE *)rect.pBits + (rect.Pitch * (y + m_pointerPos.y)) + ((x + m_pointerPos.x) * 4);
const unsigned int alpha = src[3] + 1;
const unsigned int inv = 256 - alpha;
dst[0] = (BYTE)((alpha * src[0] + inv * dst[0]) >> 8);
dst[1] = (BYTE)((alpha * src[1] + inv * dst[1]) >> 8);
dst[2] = (BYTE)((alpha * src[2] + inv * dst[2]) >> 8);
}
break;
}
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR:
{
for (int y = abs(min(0, m_pointerPos.y)); y < maxHeight; ++y)
for (int x = abs(min(0, m_pointerPos.x)); x < maxWidth; ++x)
{
UINT32 *src = (UINT32 *)m_pointer + ((m_shapeInfo.Pitch/4) * y) + x;
UINT32 *dst = (UINT32 *)rect.pBits + (frame.stride * (y + m_pointerPos.y)) + (x + m_pointerPos.x);
if (*src & 0xff000000)
*dst = 0xff000000 | (*dst ^ *src);
else *dst = 0xff000000 | *src;
}
break;
}
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME:
{
for (int y = abs(min(0, m_pointerPos.y)); y < maxHeight / 2; ++y)
for (int x = abs(min(0, m_pointerPos.x)); x < maxWidth; ++x)
{
UINT8 *srcAnd = (UINT8 *)m_pointer + (m_shapeInfo.Pitch * y) + (x/8);
UINT8 *srcXor = srcAnd + m_shapeInfo.Pitch * (m_shapeInfo.Height / 2);
UINT32 *dst = (UINT32 *)rect.pBits + (frame.stride * (y + m_pointerPos.y)) + (x + m_pointerPos.x);
const BYTE mask = 0x80 >> (x % 8);
const UINT32 andMask = (*srcAnd & mask) ? 0xFFFFFFFF : 0xFF000000;
const UINT32 xorMask = (*srcXor & mask) ? 0x00FFFFFF : 0x00000000;
*dst = (*dst & andMask) ^ xorMask;
}
break;
}
}
frame.hasMousePos = true;
frame.mouseX = m_pointerPos.x;
frame.mouseY = m_pointerPos.y;
}
memcpySSE(frame.buffer, rect.pBits, frame.outSize);
status = surface->Unmap();
// if the pointer is to be drawn
if (m_pointerVisible)
{
enum CursorType type;
switch (m_shapeInfo.Type)
{
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR : type = CURSOR_TYPE_COLOR ; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR: type = CURSOR_TYPE_MASKED_COLOR; break;
case DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME : type = CURSOR_TYPE_MONOCHROME ; break;
default:
DEBUG_ERROR("Invalid cursor type");
return false;
}
POINT cursorPos;
POINT cursorRect;
cursorPos.x = m_pointerPos.x - m_shapeInfo.HotSpot.x;
cursorPos.y = m_pointerPos.y - m_shapeInfo.HotSpot.y;
cursorRect.x = m_shapeInfo.Width;
cursorRect.y = m_shapeInfo.Height;
Util::DrawCursor(
type,
m_pointer,
cursorRect,
m_shapeInfo.Pitch,
cursorPos,
frame
);
}
if (FAILED(status))
{
DEBUG_ERROR("Failed to unmap surface: %08x", status);