From 4a83a15d785fef3cbd9668989773526ea1109573 Mon Sep 17 00:00:00 2001 From: narzoul Date: Sun, 14 Feb 2016 17:11:34 +0100 Subject: [PATCH] Invalidate GDI content when palette changes --- DDrawCompat/CompatGdi.cpp | 25 +++++++++++++++++++++++++ DDrawCompat/CompatGdiDcCache.cpp | 12 +++++++++++- DDrawCompat/CompatGdiDcCache.h | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/DDrawCompat/CompatGdi.cpp b/DDrawCompat/CompatGdi.cpp index 8d2c040..52b2f04 100644 --- a/DDrawCompat/CompatGdi.cpp +++ b/DDrawCompat/CompatGdi.cpp @@ -17,6 +17,9 @@ namespace HANDLE g_ddUnlockEndEvent = nullptr; bool g_isDelayedUnlockPending = false; + bool g_isPaletteUsed = false; + PALETTEENTRY g_usedPaletteEntries[256] = {}; + FARPROC getProcAddress(HMODULE module, const char* procName) { if (!module || !procName) @@ -142,6 +145,14 @@ namespace CompatGdi ++g_ddLockThreadRenderingRefCount; } + if (!g_isPaletteUsed && CompatPrimarySurface::palette) + { + g_isPaletteUsed = true; + ZeroMemory(g_usedPaletteEntries, sizeof(g_usedPaletteEntries)); + CompatPrimarySurface::palette->lpVtbl->GetEntries( + CompatPrimarySurface::palette, 0, 0, 256, g_usedPaletteEntries); + } + ++g_renderingRefCount; return true; } @@ -235,5 +246,19 @@ namespace CompatGdi { GdiScopedThreadLock gdiLock; CompatGdiDcCache::clear(); + + if (g_isPaletteUsed && CompatPrimarySurface::palette) + { + g_isPaletteUsed = false; + + PALETTEENTRY usedPaletteEntries[256] = {}; + CompatPrimarySurface::palette->lpVtbl->GetEntries( + CompatPrimarySurface::palette, 0, 0, 256, usedPaletteEntries); + + if (0 != memcmp(usedPaletteEntries, g_usedPaletteEntries, sizeof(usedPaletteEntries))) + { + invalidate(); + } + } } } diff --git a/DDrawCompat/CompatGdiDcCache.cpp b/DDrawCompat/CompatGdiDcCache.cpp index 5a8479b..7f64934 100644 --- a/DDrawCompat/CompatGdiDcCache.cpp +++ b/DDrawCompat/CompatGdiDcCache.cpp @@ -14,6 +14,7 @@ namespace std::vector g_cache; DWORD g_cacheSize = 0; + DWORD g_cacheId = 0; DWORD g_maxUsedCacheSize = 0; DWORD g_ddLockThreadId = 0; @@ -67,6 +68,7 @@ namespace cachedDc.surface = surface; cachedDc.dc = dc; + cachedDc.cacheId = g_cacheId; return cachedDc; } @@ -150,6 +152,7 @@ namespace CompatGdiDcCache } g_cache.clear(); g_cacheSize = 0; + ++g_cacheId; } CachedDc getDc() @@ -189,7 +192,14 @@ namespace CompatGdiDcCache void releaseDc(const CachedDc& cachedDc) { - g_cache.push_back(cachedDc); + if (cachedDc.cacheId == g_cacheId) + { + g_cache.push_back(cachedDc); + } + else + { + releaseCachedDc(cachedDc); + } } void setDdLockThreadId(DWORD ddLockThreadId) diff --git a/DDrawCompat/CompatGdiDcCache.h b/DDrawCompat/CompatGdiDcCache.h index 28aec75..b0517a3 100644 --- a/DDrawCompat/CompatGdiDcCache.h +++ b/DDrawCompat/CompatGdiDcCache.h @@ -12,6 +12,7 @@ namespace CompatGdiDcCache { IDirectDrawSurface7* surface; HDC dc; + DWORD cacheId; }; void clear();