From af5014f4c8332d1f717f11690d12bcd739004bce Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Mon, 18 Jul 2016 11:32:27 +0100 Subject: [PATCH] gdi32: Add a small rectangle buffer to reduce memory allocation. Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/gdi_private.h | 2 ++ dlls/gdi32/region.c | 49 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index b4768640210..cbe66a8e770 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -355,12 +355,14 @@ extern BOOL add_rect_to_region( HRGN rgn, const RECT *rect ) DECLSPEC_HIDDEN; extern INT mirror_region( HRGN dst, HRGN src, INT width ) DECLSPEC_HIDDEN; extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y ) DECLSPEC_HIDDEN; +#define RGN_DEFAULT_RECTS 4 typedef struct { INT size; INT numRects; RECT *rects; RECT extents; + RECT rects_buf[RGN_DEFAULT_RECTS]; } WINEREGION; /* return the region data without making a copy */ diff --git a/dlls/gdi32/region.c b/dlls/gdi32/region.c index a5dc2ff546e..a4cf733a596 100644 --- a/dlls/gdi32/region.c +++ b/dlls/gdi32/region.c @@ -131,8 +131,17 @@ static BOOL grow_region( WINEREGION *rgn, int size ) if (size <= rgn->size) return TRUE; - new_rects = HeapReAlloc( GetProcessHeap(), 0, rgn->rects, size * sizeof(RECT) ); - if (!new_rects) return FALSE; + if (rgn->rects == rgn->rects_buf) + { + new_rects = HeapAlloc( GetProcessHeap(), 0, size * sizeof(RECT) ); + if (!new_rects) return FALSE; + memcpy( new_rects, rgn->rects, rgn->numRects * sizeof(RECT) ); + } + else + { + new_rects = HeapReAlloc( GetProcessHeap(), 0, rgn->rects, size * sizeof(RECT) ); + if (!new_rects) return FALSE; + } rgn->rects = new_rects; rgn->size = size; return TRUE; @@ -406,9 +415,6 @@ static BOOL REGION_SubtractRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2) static BOOL REGION_XorRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2); static BOOL REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn); -#define RGN_DEFAULT_RECTS 2 - - /*********************************************************************** * get_region_type */ @@ -445,7 +451,16 @@ static void REGION_DumpRegion(WINEREGION *pReg) */ static BOOL init_region( WINEREGION *pReg, INT n ) { - if (!(pReg->rects = HeapAlloc(GetProcessHeap(), 0, n * sizeof( RECT )))) return FALSE; + n = max( n, RGN_DEFAULT_RECTS ); + + if (n > RGN_DEFAULT_RECTS) + { + if (!(pReg->rects = HeapAlloc( GetProcessHeap(), 0, n * sizeof( RECT ) ))) + return FALSE; + } + else + pReg->rects = pReg->rects_buf; + pReg->size = n; empty_region(pReg); return TRUE; @@ -456,7 +471,8 @@ static BOOL init_region( WINEREGION *pReg, INT n ) */ static void destroy_region( WINEREGION *pReg ) { - HeapFree( GetProcessHeap(), 0, pReg->rects ); + if (pReg->rects != pReg->rects_buf) + HeapFree( GetProcessHeap(), 0, pReg->rects ); } /*********************************************************************** @@ -491,12 +507,16 @@ static WINEREGION *alloc_region( INT n ) static inline void move_rects( WINEREGION *dst, WINEREGION *src ) { destroy_region( dst ); - dst->rects = src->rects; + if (src->rects == src->rects_buf) + { + dst->rects = dst->rects_buf; + memcpy( dst->rects, src->rects, src->numRects * sizeof(RECT) ); + } + else + dst->rects = src->rects; dst->size = src->size; dst->numRects = src->numRects; - src->rects = NULL; - src->size = 0; - src->numRects = 0; + init_region( src, 0 ); } /*********************************************************************** @@ -1176,10 +1196,9 @@ static BOOL REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn) { WINEREGION region; - region.rects = ®ion.extents; + init_region( ®ion, 1 ); region.numRects = 1; - region.size = 1; - region.extents = *rect; + region.extents = *region.rects = *rect; return REGION_UnionRegion(rgn, rgn, ®ion); } @@ -1625,7 +1644,7 @@ static INT REGION_Coalesce ( */ static void REGION_compact( WINEREGION *reg ) { - if ((reg->numRects < reg->size / 2) && (reg->numRects > 2)) + if ((reg->numRects < reg->size / 2) && (reg->numRects > RGN_DEFAULT_RECTS)) { RECT *new_rects = HeapReAlloc( GetProcessHeap(), 0, reg->rects, reg->numRects * sizeof(RECT) ); if (new_rects) -- 2.11.4.GIT