Module: wine Branch: master Commit: d1048914332e118c2ae107177f24910807471367 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d1048914332e118c2ae107177f...
Author: Alexandre Julliard julliard@winehq.org Date: Sat May 21 09:55:18 2016 +0900
user32: Only start reusing DCEs after the cache reached its limit.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/painting.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index ba1967c..30dabfe 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -56,6 +56,8 @@ struct dce
static struct list dce_list = LIST_INIT(dce_list);
+#define DCE_CACHE_SIZE 64 + static BOOL CALLBACK dc_hook( HDC hDC, WORD code, DWORD_PTR data, LPARAM lParam );
static const WCHAR displayW[] = { 'D','I','S','P','L','A','Y',0 }; @@ -429,10 +431,11 @@ void invalidate_dce( WND *win, const RECT *extra_rect )
LIST_FOR_EACH_ENTRY( dce, &dce_list, struct dce, entry ) { + if (!dce->hwnd) continue; + TRACE( "%p: hwnd %p dcx %08x %s %s\n", dce, dce->hwnd, dce->flags, (dce->flags & DCX_CACHE) ? "Cache" : "Owned", dce->count ? "InUse" : "" );
- if (!dce->hwnd) continue; if ((dce->hwnd == win->parent) && !(dce->flags & DCX_CLIPCHILDREN)) continue; /* child window positions don't bother us */
@@ -1001,7 +1004,8 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
if ((flags & DCX_CACHE) || !(dce = get_window_dce( hwnd ))) { - struct dce *dceEmpty = NULL, *dceUnused = NULL; + struct dce *dceEmpty = NULL, *dceUnused = NULL, *found = NULL; + unsigned int count = 0;
/* Strategy: First, we attempt to find a non-empty but unused DCE with * compatible flags. Next, we look for an empty entry. If the cache is @@ -1010,24 +1014,23 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) USER_Lock(); LIST_FOR_EACH_ENTRY( dce, &dce_list, struct dce, entry ) { - if ((dce->flags & DCX_CACHE) && !dce->count) + if (!(dce->flags & DCX_CACHE)) break; + count++; + if (dce->count) continue; + dceUnused = dce; + if (!dce->hwnd) dceEmpty = dce; + else if ((dce->hwnd == hwnd) && !((dce->flags ^ flags) & clip_flags)) { - dceUnused = dce; - - if (!dce->hwnd) dceEmpty = dce; - else if ((dce->hwnd == hwnd) && !((dce->flags ^ flags) & clip_flags)) - { - TRACE("\tfound valid %p dce [%p], flags %08x\n", - dce, hwnd, dce->flags ); - bUpdateVisRgn = FALSE; - break; - } + TRACE( "found valid %p dce [%p], flags %08x\n", dce, hwnd, dce->flags ); + found = dce; + bUpdateVisRgn = FALSE; + break; } } + if (!found) found = dceEmpty; + if (!found && count >= DCE_CACHE_SIZE) found = dceUnused;
- if (&dce->entry == &dce_list) /* nothing found */ - dce = dceEmpty ? dceEmpty : dceUnused; - + dce = found; if (dce) dce->count = 1;
USER_Unlock();