Alexandre Julliard : user32: Only start reusing DCEs after the cache reached its limit.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon May 23 10:27:44 CDT 2016
Module: wine
Branch: master
Commit: d1048914332e118c2ae107177f24910807471367
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d1048914332e118c2ae107177f24910807471367
Author: Alexandre Julliard <julliard at 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 at 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();
More information about the wine-cvs
mailing list