Module: wine Branch: master Commit: ddfe35867d2f6b98465e0e84bcf01fbeaa3b9142 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ddfe35867d2f6b98465e0e84bc...
Author: Alexandre Julliard julliard@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 );