Commit af5014f4 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

gdi32: Add a small rectangle buffer to reduce memory allocation.

parent 01c33fb9
...@@ -355,12 +355,14 @@ extern BOOL add_rect_to_region( HRGN rgn, const RECT *rect ) DECLSPEC_HIDDEN; ...@@ -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 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; extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y ) DECLSPEC_HIDDEN;
#define RGN_DEFAULT_RECTS 4
typedef struct typedef struct
{ {
INT size; INT size;
INT numRects; INT numRects;
RECT *rects; RECT *rects;
RECT extents; RECT extents;
RECT rects_buf[RGN_DEFAULT_RECTS];
} WINEREGION; } WINEREGION;
/* return the region data without making a copy */ /* return the region data without making a copy */
......
...@@ -131,8 +131,17 @@ static BOOL grow_region( WINEREGION *rgn, int size ) ...@@ -131,8 +131,17 @@ static BOOL grow_region( WINEREGION *rgn, int size )
if (size <= rgn->size) return TRUE; if (size <= rgn->size) return TRUE;
new_rects = HeapReAlloc( GetProcessHeap(), 0, rgn->rects, size * sizeof(RECT) ); if (rgn->rects == rgn->rects_buf)
if (!new_rects) return FALSE; {
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->rects = new_rects;
rgn->size = size; rgn->size = size;
return TRUE; return TRUE;
...@@ -406,9 +415,6 @@ static BOOL REGION_SubtractRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2) ...@@ -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_XorRegion(WINEREGION *d, WINEREGION *s1, WINEREGION *s2);
static BOOL REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn); static BOOL REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn);
#define RGN_DEFAULT_RECTS 2
/*********************************************************************** /***********************************************************************
* get_region_type * get_region_type
*/ */
...@@ -445,7 +451,16 @@ static void REGION_DumpRegion(WINEREGION *pReg) ...@@ -445,7 +451,16 @@ static void REGION_DumpRegion(WINEREGION *pReg)
*/ */
static BOOL init_region( WINEREGION *pReg, INT n ) 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; pReg->size = n;
empty_region(pReg); empty_region(pReg);
return TRUE; return TRUE;
...@@ -456,7 +471,8 @@ static BOOL init_region( WINEREGION *pReg, INT n ) ...@@ -456,7 +471,8 @@ static BOOL init_region( WINEREGION *pReg, INT n )
*/ */
static void destroy_region( WINEREGION *pReg ) 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 ) ...@@ -491,12 +507,16 @@ static WINEREGION *alloc_region( INT n )
static inline void move_rects( WINEREGION *dst, WINEREGION *src ) static inline void move_rects( WINEREGION *dst, WINEREGION *src )
{ {
destroy_region( dst ); 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->size = src->size;
dst->numRects = src->numRects; dst->numRects = src->numRects;
src->rects = NULL; init_region( src, 0 );
src->size = 0;
src->numRects = 0;
} }
/*********************************************************************** /***********************************************************************
...@@ -1176,10 +1196,9 @@ static BOOL REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn) ...@@ -1176,10 +1196,9 @@ static BOOL REGION_UnionRectWithRegion(const RECT *rect, WINEREGION *rgn)
{ {
WINEREGION region; WINEREGION region;
region.rects = &region.extents; init_region( &region, 1 );
region.numRects = 1; region.numRects = 1;
region.size = 1; region.extents = *region.rects = *rect;
region.extents = *rect;
return REGION_UnionRegion(rgn, rgn, &region); return REGION_UnionRegion(rgn, rgn, &region);
} }
...@@ -1625,7 +1644,7 @@ static INT REGION_Coalesce ( ...@@ -1625,7 +1644,7 @@ static INT REGION_Coalesce (
*/ */
static void REGION_compact( WINEREGION *reg ) 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) ); RECT *new_rects = HeapReAlloc( GetProcessHeap(), 0, reg->rects, reg->numRects * sizeof(RECT) );
if (new_rects) if (new_rects)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment