1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Update only the dirty rectangle on the real primary surface

This commit is contained in:
narzoul 2016-04-10 17:12:36 +02:00
parent 1a3cb2be4d
commit ac9dbc72de
4 changed files with 55 additions and 9 deletions

View File

@ -431,6 +431,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Blt(
if (This == s_compatPrimarySurface && SUCCEEDED(result))
{
RealPrimarySurface::invalidate(lpDestRect);
RealPrimarySurface::update();
}
@ -455,6 +456,23 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::BltFast(
HRESULT result = s_origVtable.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
if (This == s_compatPrimarySurface && SUCCEEDED(result))
{
const LONG x = dwX;
const LONG y = dwY;
RECT destRect = { x, y, x, y};
if (lpSrcRect)
{
destRect.right += lpSrcRect->right - lpSrcRect->left;
destRect.bottom += lpSrcRect->bottom - lpSrcRect->top;
}
else
{
TSurfaceDesc desc = {};
desc.dwSize = sizeof(desc);
s_origVtable.GetSurfaceDesc(lpDDSrcSurface, &desc);
destRect.right += desc.dwWidth;
destRect.bottom += desc.dwHeight;
}
RealPrimarySurface::invalidate(&destRect);
RealPrimarySurface::update();
}
return result;
@ -531,6 +549,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Lock(
HRESULT result = s_origVtable.Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
if (SUCCEEDED(result) && g_lockingPrimary && lpDDSurfaceDesc)
{
RealPrimarySurface::invalidate(lpDestRect);
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps);
}
else if (DDERR_SURFACELOST == result)
@ -574,6 +593,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::ReleaseDC(TSurface*
HRESULT result = s_origVtable.ReleaseDC(This, hDC);
if (This == s_compatPrimarySurface && SUCCEEDED(result))
{
RealPrimarySurface::invalidate(nullptr);
RealPrimarySurface::update();
}
return result;

View File

@ -117,6 +117,7 @@ namespace
GdiFlush();
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Unlock(
CompatPrimarySurface::surface, nullptr);
RealPrimarySurface::invalidate(nullptr);
RealPrimarySurface::update();
Compat::origProcs.ReleaseDDThreadLock();

View File

@ -24,6 +24,7 @@ namespace
HANDLE g_updateThread = nullptr;
HANDLE g_updateEvent = nullptr;
RECT g_updateRect = {};
bool g_isFlipEvent = false;
LARGE_INTEGER g_lastUpdateTime = {};
LARGE_INTEGER g_qpcFrequency = {};
@ -52,14 +53,14 @@ namespace
IDirectDrawSurface7* converterSurface = CompatPaletteConverter::lockSurface();
HDC converterDc = CompatPaletteConverter::lockDc();
origVtable.Blt(converterSurface, nullptr, CompatPrimarySurface::surface, nullptr,
DDBLT_WAIT, nullptr);
origVtable.Blt(converterSurface, &g_updateRect,
CompatPrimarySurface::surface, &g_updateRect, DDBLT_WAIT, nullptr);
HDC destDc = nullptr;
origVtable.GetDC(dest, &destDc);
result = TRUE == CALL_ORIG_FUNC(BitBlt)(destDc, 0, 0,
RealPrimarySurface::s_surfaceDesc.dwWidth, RealPrimarySurface::s_surfaceDesc.dwHeight,
converterDc, 0, 0, SRCCOPY);
result = TRUE == CALL_ORIG_FUNC(BitBlt)(destDc, g_updateRect.left, g_updateRect.top,
g_updateRect.right - g_updateRect.left, g_updateRect.bottom - g_updateRect.top,
converterDc, g_updateRect.left, g_updateRect.top, SRCCOPY);
origVtable.ReleaseDC(dest, destDc);
CompatPaletteConverter::unlockDc();
@ -75,8 +76,13 @@ namespace
}
else
{
result = SUCCEEDED(origVtable.Blt(
dest, nullptr, CompatPrimarySurface::surface, nullptr, DDBLT_WAIT, nullptr));
result = SUCCEEDED(origVtable.Blt(dest, &g_updateRect,
CompatPrimarySurface::surface, &g_updateRect, DDBLT_WAIT, nullptr));
}
if (result)
{
SetRectEmpty(&g_updateRect);
}
Compat::LogLeave("RealPrimarySurface::compatBlt", dest);
@ -232,6 +238,7 @@ HRESULT RealPrimarySurface::flip(DWORD flags)
return DDERR_NOTFLIPPABLE;
}
invalidate(nullptr);
compatBlt(g_backBuffer);
if (flags & DDFLIP_DONOTWAIT)
{
@ -253,6 +260,19 @@ IDirectDrawSurface7* RealPrimarySurface::getSurface()
return g_frontBuffer;
}
void RealPrimarySurface::invalidate(const RECT* rect)
{
if (rect)
{
UnionRect(&g_updateRect, &g_updateRect, rect);
}
else
{
SetRect(&g_updateRect, 0, 0,
CompatPrimarySurface::displayMode.width, CompatPrimarySurface::displayMode.height);
}
}
bool RealPrimarySurface::isFullScreen()
{
return g_isFullScreen;
@ -306,13 +326,17 @@ void RealPrimarySurface::setPalette()
void RealPrimarySurface::update()
{
g_isFlipEvent = false;
SetEvent(g_updateEvent);
if (!IsRectEmpty(&g_updateRect))
{
g_isFlipEvent = false;
SetEvent(g_updateEvent);
}
}
void RealPrimarySurface::updatePalette(DWORD startingEntry, DWORD count)
{
CompatPaletteConverter::setPrimaryPalette(startingEntry, count);
CompatGdi::updatePalette(startingEntry, count);
invalidate(nullptr);
updateNow();
}

View File

@ -12,6 +12,7 @@ public:
static HRESULT flip(DWORD flags);
static IDirectDrawSurface7* getSurface();
static void invalidate(const RECT* rect);
static bool isFullScreen();
static bool isLost();
static void release();