gdi32: Only create the DC visible region when necessary.

Most DCs can simply use the visible rectangle instead.
This commit is contained in:
Alexandre Julliard 2011-12-07 16:50:57 +01:00
parent 1f15ffa1e6
commit ddfe35867d
3 changed files with 48 additions and 36 deletions

View File

@ -639,7 +639,6 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
dc->vis_rect.top = 0;
dc->vis_rect.right = bitmap->bitmap.bmWidth;
dc->vis_rect.bottom = bitmap->bitmap.bmHeight;
SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
GDI_ReleaseObj( handle );
DC_InitDC( dc );
GDI_dec_ref_count( ret );

View File

@ -29,6 +29,16 @@
WINE_DEFAULT_DEBUG_CHANNEL(clipping);
/* return the DC visible rectangle if not empty */
static inline BOOL get_dc_visrect( DC *dc, RECT *rect )
{
rect->left = 0;
rect->top = 0;
rect->right = dc->vis_rect.right - dc->vis_rect.left;
rect->bottom = dc->vis_rect.bottom - dc->vis_rect.top;
return !is_rect_empty( rect );
}
/***********************************************************************
* get_clip_rect
*
@ -77,6 +87,7 @@ BOOL clip_visrect( DC *dc, RECT *dst, const RECT *src )
void CLIPPING_UpdateGCRegion( DC * dc )
{
HRGN clip_rgn;
RECT visrect;
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDeviceClipping );
/* update the intersection of meta and clip regions */
@ -91,11 +102,17 @@ void CLIPPING_UpdateGCRegion( DC * dc )
dc->hMetaClipRgn = 0;
}
clip_rgn = get_clip_region( dc );
if (clip_rgn || dc->hVisRgn)
if (dc->hVisRgn)
{
if (!dc->region) dc->region = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( dc->region, dc->hVisRgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
}
else if (get_dc_visrect( dc, &visrect ))
{
if (!dc->region) dc->region = CreateRectRgn( 0, 0, 0, 0 );
SetRectRgn( dc->region, visrect.left, visrect.top, visrect.right, visrect.bottom );
if (clip_rgn) CombineRgn( dc->region, dc->region, clip_rgn, RGN_AND );
}
else
{
if (dc->region) DeleteObject( dc->region );
@ -272,7 +289,7 @@ void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect )
/* map region to DC coordinates */
OffsetRgn( hrgn, -vis_rect->left, -vis_rect->top );
DeleteObject( dc->hVisRgn );
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
dc->dirty = 0;
dc->vis_rect = *vis_rect;
dc->hVisRgn = hrgn;
@ -476,7 +493,8 @@ INT WINAPI GetMetaRgn( HDC hdc, HRGN hRgn )
*/
INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
{
HRGN rgn;
INT ret = 1;
RECT visrect;
DC *dc = get_dc_ptr( hDC );
if (!dc) return -1;
@ -484,33 +502,37 @@ INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
switch (iCode)
{
case 1:
rgn = dc->hClipRgn;
if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY );
else ret = 0;
break;
case 2:
rgn = dc->hMetaRgn;
if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY );
else ret = 0;
break;
case 3:
rgn = dc->hMetaClipRgn;
if(!rgn) rgn = dc->hClipRgn;
if(!rgn) rgn = dc->hMetaRgn;
if (dc->hMetaClipRgn) CombineRgn( hRgn, dc->hMetaClipRgn, 0, RGN_COPY );
else if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY );
else if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY );
else ret = 0;
break;
case SYSRGN: /* == 4 */
update_dc( dc );
rgn = dc->hVisRgn;
if (dc->hVisRgn)
CombineRgn( hRgn, dc->hVisRgn, 0, RGN_COPY );
else if (get_dc_visrect( dc, &visrect ))
SetRectRgn( hRgn, visrect.left, visrect.top, visrect.right, visrect.bottom );
else
ret = 0;
/* On Windows NT/2000, the SYSRGN returned is in screen coordinates */
if (ret && !(GetVersion() & 0x80000000)) OffsetRgn( hRgn, dc->vis_rect.left, dc->vis_rect.top );
break;
default:
WARN("Unknown code %d\n", iCode);
release_dc_ptr( dc );
return -1;
ret = -1;
break;
}
if (rgn) CombineRgn( hRgn, rgn, 0, RGN_COPY );
release_dc_ptr( dc );
/* On Windows NT/2000, the SYSRGN returned is in screen coordinates */
if (iCode == SYSRGN && !(GetVersion() & 0x80000000))
OffsetRgn( hRgn, dc->vis_rect.left, dc->vis_rect.top );
return (rgn != 0);
return ret;
}

View File

@ -585,11 +585,10 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
ERR( "no driver found for %s\n", debugstr_w(buf) );
return 0;
}
if (!(dc = alloc_dc_ptr( OBJ_DC ))) goto error;
if (!(dc = alloc_dc_ptr( OBJ_DC ))) return 0;
hdc = dc->hSelf;
dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP ));
if (!(dc->hVisRgn = CreateRectRgn( 0, 0, 1, 1 ))) goto error;
TRACE("(driver=%s, device=%s, output=%s): returning %p\n",
debugstr_w(driver), debugstr_w(device), debugstr_w(output), dc->hSelf );
@ -599,7 +598,8 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
if (!funcs->pCreateDC( &dc->physDev, buf, device, output, initData ))
{
WARN("creation aborted by device\n" );
goto error;
free_dc_ptr( dc );
return 0;
}
}
@ -607,15 +607,10 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
dc->vis_rect.top = 0;
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
dc->vis_rect.bottom = GetDeviceCaps( hdc, DESKTOPVERTRES );
SetRectRgn(dc->hVisRgn, dc->vis_rect.left, dc->vis_rect.top, dc->vis_rect.right, dc->vis_rect.bottom);
DC_InitDC( dc );
release_dc_ptr( dc );
return hdc;
error:
if (dc) free_dc_ptr( dc );
return 0;
}
@ -698,7 +693,7 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
release_dc_ptr( origDC );
}
if (!(dc = alloc_dc_ptr( OBJ_MEMDC ))) goto error;
if (!(dc = alloc_dc_ptr( OBJ_MEMDC ))) return 0;
TRACE("(%p): returning %p\n", hdc, dc->hSelf );
@ -707,22 +702,18 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
dc->vis_rect.top = 0;
dc->vis_rect.right = 1;
dc->vis_rect.bottom = 1;
if (!(dc->hVisRgn = CreateRectRgn( 0, 0, 1, 1 ))) goto error; /* default bitmap is 1x1 */
ret = dc->hSelf;
if (!funcs->pCreateCompatibleDC( physDev, &dc->physDev ))
{
WARN("creation aborted by device\n");
goto error;
free_dc_ptr( dc );
return 0;
}
DC_InitDC( dc );
release_dc_ptr( dc );
return ret;
error:
if (dc) free_dc_ptr( dc );
return 0;
}
@ -790,8 +781,8 @@ HDC WINAPI ResetDCW( HDC hdc, const DEVMODEW *devmode )
dc->vis_rect.top = 0;
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
dc->vis_rect.bottom = GetDeviceCaps( hdc, DESKTOPVERTRES );
SetRectRgn( dc->hVisRgn, dc->vis_rect.left, dc->vis_rect.top,
dc->vis_rect.right, dc->vis_rect.bottom );
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
dc->hVisRgn = 0;
CLIPPING_UpdateGCRegion( dc );
}
release_dc_ptr( dc );