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