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

Minimize invalidation on window position changes

This commit is contained in:
narzoul 2016-02-21 12:03:31 +01:00
parent 0244c8c022
commit 1ab496cbf5
4 changed files with 69 additions and 8 deletions

View File

@ -602,7 +602,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Restore(TSurface* T
result = RealPrimarySurface::restore();
if (wasLost)
{
CompatGdi::invalidate();
CompatGdi::invalidate(nullptr);
}
}
}

View File

@ -58,14 +58,33 @@ namespace
return nullptr;
}
BOOL CALLBACK invalidateWindow(HWND hwnd, LPARAM /*lParam*/)
BOOL CALLBACK invalidateWindow(HWND hwnd, LPARAM lParam)
{
if (!IsWindowVisible(hwnd))
{
return TRUE;
}
DWORD processId = 0;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == GetCurrentProcessId())
if (processId != GetCurrentProcessId())
{
return TRUE;
}
if (lParam)
{
POINT origin = {};
ClientToScreen(hwnd, &origin);
RECT rect = *reinterpret_cast<const RECT*>(lParam);
OffsetRect(&rect, -origin.x, -origin.y);
RedrawWindow(hwnd, &rect, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
else
{
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
return TRUE;
}
@ -237,9 +256,9 @@ namespace CompatGdi
}
}
void invalidate()
void invalidate(const RECT* rect)
{
EnumWindows(&invalidateWindow, 0);
EnumWindows(&invalidateWindow, reinterpret_cast<LPARAM>(rect));
}
void updatePalette()
@ -257,7 +276,7 @@ namespace CompatGdi
if (0 != memcmp(usedPaletteEntries, g_usedPaletteEntries, sizeof(usedPaletteEntries)))
{
invalidate();
invalidate(nullptr);
}
}
}

View File

@ -45,6 +45,6 @@ namespace CompatGdi
}
void installHooks();
void invalidate();
void invalidate(const RECT* rect);
void updatePalette();
};

View File

@ -1,5 +1,7 @@
#define WIN32_LEAN_AND_MEAN
#include <unordered_map>
#include <dwmapi.h>
#include <Windows.h>
@ -12,9 +14,13 @@
namespace
{
std::unordered_map<HWND, RECT> g_prevWindowRect;
void disableDwmAttributes(HWND hwnd);
void eraseBackground(HWND hwnd, HDC dc);
void ncPaint(HWND hwnd);
void onWindowPosChanged(HWND hwnd);
void removeDropShadow(HWND hwnd);
void updateScrolledWindow(HWND hwnd);
LRESULT CALLBACK callWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
@ -25,6 +31,12 @@ namespace
if (WM_CREATE == ret->message)
{
disableDwmAttributes(ret->hwnd);
removeDropShadow(ret->hwnd);
}
else if (WM_DESTROY == ret->message)
{
CompatGdi::GdiScopedThreadLock lock;
g_prevWindowRect.erase(ret->hwnd);
}
else if (WM_ERASEBKGND == ret->message)
{
@ -42,7 +54,7 @@ namespace
}
else if (WM_WINDOWPOSCHANGED == ret->message)
{
CompatGdi::invalidate();
onWindowPosChanged(ret->hwnd);
}
else if (WM_VSCROLL == ret->message || WM_HSCROLL == ret->message)
{
@ -201,6 +213,36 @@ namespace
}
}
void onWindowPosChanged(HWND hwnd)
{
CompatGdi::GdiScopedThreadLock lock;
const auto it = g_prevWindowRect.find(hwnd);
if (it != g_prevWindowRect.end())
{
CompatGdi::invalidate(&it->second);
}
if (IsWindowVisible(hwnd))
{
GetWindowRect(hwnd, it != g_prevWindowRect.end() ? &it->second : &g_prevWindowRect[hwnd]);
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
else if (it != g_prevWindowRect.end())
{
g_prevWindowRect.erase(it);
}
}
void removeDropShadow(HWND hwnd)
{
const auto style = GetClassLongPtr(hwnd, GCL_STYLE);
if (style & CS_DROPSHADOW)
{
SetClassLongPtr(hwnd, GCL_STYLE, style ^ CS_DROPSHADOW);
}
}
void updateScrolledWindow(HWND hwnd)
{
RedrawWindow(hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE);