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)) if (This == s_compatPrimarySurface && SUCCEEDED(result))
{ {
RealPrimarySurface::invalidate(lpDestRect);
RealPrimarySurface::update(); RealPrimarySurface::update();
} }
@ -455,6 +456,23 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::BltFast(
HRESULT result = s_origVtable.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans); HRESULT result = s_origVtable.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
if (This == s_compatPrimarySurface && SUCCEEDED(result)) 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(); RealPrimarySurface::update();
} }
return result; return result;
@ -531,6 +549,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Lock(
HRESULT result = s_origVtable.Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent); HRESULT result = s_origVtable.Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
if (SUCCEEDED(result) && g_lockingPrimary && lpDDSurfaceDesc) if (SUCCEEDED(result) && g_lockingPrimary && lpDDSurfaceDesc)
{ {
RealPrimarySurface::invalidate(lpDestRect);
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps); restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps);
} }
else if (DDERR_SURFACELOST == result) else if (DDERR_SURFACELOST == result)
@ -574,6 +593,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::ReleaseDC(TSurface*
HRESULT result = s_origVtable.ReleaseDC(This, hDC); HRESULT result = s_origVtable.ReleaseDC(This, hDC);
if (This == s_compatPrimarySurface && SUCCEEDED(result)) if (This == s_compatPrimarySurface && SUCCEEDED(result))
{ {
RealPrimarySurface::invalidate(nullptr);
RealPrimarySurface::update(); RealPrimarySurface::update();
} }
return result; return result;

View File

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

View File

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

View File

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