user32: Only start reusing DCEs after the cache reached its limit.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Alexandre Julliard 2016-05-21 09:55:18 +09:00
parent d341b0c381
commit d104891433
1 changed files with 19 additions and 16 deletions

View File

@ -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();