Alexandre Julliard : gdi32: Only create the DC visible region when necessary.
Alexandre Julliard
julliard at winehq.org
Wed Dec 7 13:57:12 CST 2011
Module: wine
Branch: master
Commit: ddfe35867d2f6b98465e0e84bcf01fbeaa3b9142
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ddfe35867d2f6b98465e0e84bcf01fbeaa3b9142
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Dec 7 16:50:57 2011 +0100
gdi32: Only create the DC visible region when necessary.
Most DCs can simply use the visible rectangle instead.
---
dlls/gdi32/bitmap.c | 1 -
dlls/gdi32/clipping.c | 58 +++++++++++++++++++++++++++++++++---------------
dlls/gdi32/dc.c | 25 ++++++--------------
3 files changed, 48 insertions(+), 36 deletions(-)
diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index 45c3011..4f0b173 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -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 );
diff --git a/dlls/gdi32/clipping.c b/dlls/gdi32/clipping.c
index 7f69950..41590bd 100644
--- a/dlls/gdi32/clipping.c
+++ b/dlls/gdi32/clipping.c
@@ -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;
}
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 2519a28..4e819d6 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -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 );
More information about the wine-cvs
mailing list