Most regions (> 95% in testing) consist of only 1 rectangle. Add a single

rectangle buffer to ROSRGNDATA to avoid dynamic memory allocation

svn path=/trunk/; revision=8960
This commit is contained in:
Gé van Geldorp 2004-04-03 20:36:56 +00:00
parent 87ea1d498e
commit 06ed71caec
2 changed files with 46 additions and 27 deletions

View file

@ -8,6 +8,9 @@
typedef struct _ROSRGNDATA { typedef struct _ROSRGNDATA {
RGNDATAHEADER rdh; RGNDATAHEADER rdh;
char* Buffer; char* Buffer;
RECT BuiltInRect; /* Testing shows that > 95% of all regions have only 1 rect.
Including that here saves us from having to do another
allocation */
} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA; } ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: region.c,v 1.45 2004/03/23 17:07:41 gvg Exp $ */ /* $Id: region.c,v 1.46 2004/04/03 20:36:56 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
@ -78,6 +78,7 @@ static inline int xmemcheck(ROSRGNDATA *reg, LPRECT *rect, LPRECT *firstrect ) {
return 0; return 0;
RtlCopyMemory( temp, *firstrect, reg->rdh.nRgnSize ); RtlCopyMemory( temp, *firstrect, reg->rdh.nRgnSize );
reg->rdh.nRgnSize *= 2; reg->rdh.nRgnSize *= 2;
if (*firstrect != &reg->BuiltInRect)
ExFreePool( *firstrect ); ExFreePool( *firstrect );
*firstrect = temp; *firstrect = temp;
*rect = (*firstrect)+reg->rdh.nCount; *rect = (*firstrect)+reg->rdh.nCount;
@ -141,7 +142,7 @@ static BOOL FASTCALL REGION_CopyRegion(PROSRGNDATA dst, PROSRGNDATA src)
if( !temp ) if( !temp )
return FALSE; return FALSE;
if( dst->Buffer ) if( dst->Buffer && dst->Buffer != (char *) &dst->BuiltInRect )
ExFreePool( dst->Buffer ); //free the old buffer ExFreePool( dst->Buffer ); //free the old buffer
dst->Buffer = temp; dst->Buffer = temp;
dst->rdh.nRgnSize = src->rdh.nCount * sizeof(RECT); //size of region buffer dst->rdh.nRgnSize = src->rdh.nCount * sizeof(RECT); //size of region buffer
@ -216,7 +217,7 @@ static BOOL FASTCALL REGION_CropAndOffsetRegion(const PPOINT off, const PRECT re
} }
else{ else{
xrect = ExAllocatePoolWithTag(PagedPool, rgnSrc->rdh.nCount * sizeof(RECT), TAG_REGION); xrect = ExAllocatePoolWithTag(PagedPool, rgnSrc->rdh.nCount * sizeof(RECT), TAG_REGION);
if( rgnDst->Buffer ) if( rgnDst->Buffer && rgnDst->Buffer != (char *) &rgnDst->BuiltInRect )
ExFreePool( rgnDst->Buffer ); //free the old buffer. will be assigned to xrect below. ExFreePool( rgnDst->Buffer ); //free the old buffer. will be assigned to xrect below.
} }
@ -279,7 +280,7 @@ static BOOL FASTCALL REGION_CropAndOffsetRegion(const PPOINT off, const PRECT re
if(!temp) if(!temp)
return FALSE; return FALSE;
if( rgnDst->Buffer ) if( rgnDst->Buffer && rgnDst->Buffer != (char *) &rgnDst->BuiltInRect )
ExFreePool( rgnDst->Buffer ); //free the old buffer ExFreePool( rgnDst->Buffer ); //free the old buffer
(PRECT)rgnDst->Buffer = temp; (PRECT)rgnDst->Buffer = temp;
rgnDst->rdh.nCount = i; rgnDst->rdh.nCount = i;
@ -817,6 +818,7 @@ REGION_RegionOp(
else{ else{
newReg->rdh.nRgnSize = newReg->rdh.nCount*sizeof(RECT); newReg->rdh.nRgnSize = newReg->rdh.nCount*sizeof(RECT);
RtlCopyMemory( newReg->Buffer, prev_rects, newReg->rdh.nRgnSize ); RtlCopyMemory( newReg->Buffer, prev_rects, newReg->rdh.nRgnSize );
if (prev_rects != &newReg->BuiltInRect)
ExFreePool( prev_rects ); ExFreePool( prev_rects );
} }
} }
@ -827,6 +829,7 @@ REGION_RegionOp(
* the region is empty * the region is empty
*/ */
newReg->rdh.nRgnSize = sizeof(RECT); newReg->rdh.nRgnSize = sizeof(RECT);
if (newReg->Buffer != (char *) &newReg->BuiltInRect)
ExFreePool( newReg->Buffer ); ExFreePool( newReg->Buffer );
newReg->Buffer = ExAllocatePoolWithTag( PagedPool, sizeof(RECT), TAG_REGION ); newReg->Buffer = ExAllocatePoolWithTag( PagedPool, sizeof(RECT), TAG_REGION );
ASSERT( newReg->Buffer ); ASSERT( newReg->Buffer );
@ -838,6 +841,7 @@ REGION_RegionOp(
else else
newReg->rdh.iType = (newReg->rdh.nCount > 1)? COMPLEXREGION : SIMPLEREGION; newReg->rdh.iType = (newReg->rdh.nCount > 1)? COMPLEXREGION : SIMPLEREGION;
if (oldRects != &newReg->BuiltInRect)
ExFreePool( oldRects ); ExFreePool( oldRects );
return; return;
} }
@ -1474,10 +1478,20 @@ HRGN FASTCALL RGNDATA_AllocRgn(INT n)
BOOL bRet; BOOL bRet;
if ((hReg = (HRGN) GDIOBJ_AllocObj(sizeof(ROSRGNDATA), GDI_OBJECT_TYPE_REGION, if ((hReg = (HRGN) GDIOBJ_AllocObj(sizeof(ROSRGNDATA), GDI_OBJECT_TYPE_REGION,
(GDICLEANUPPROC) RGNDATA_InternalDelete))){ (GDICLEANUPPROC) RGNDATA_InternalDelete)))
if( (pReg = RGNDATA_LockRgn(hReg)) ){ {
if (NULL != (pReg = RGNDATA_LockRgn(hReg)))
if ((pReg->Buffer = ExAllocatePoolWithTag(PagedPool, n * sizeof(RECT), TAG_REGION))){ {
if (1 == n)
{
pReg->Buffer = (char *) &pReg->BuiltInRect;
}
else
{
pReg->Buffer = ExAllocatePoolWithTag(PagedPool, n * sizeof(RECT), TAG_REGION);
}
if (NULL != pReg->Buffer)
{
EMPTY_REGION(pReg); EMPTY_REGION(pReg);
pReg->rdh.dwSize = sizeof(RGNDATAHEADER); pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
pReg->rdh.nCount = n; pReg->rdh.nCount = n;
@ -1488,18 +1502,20 @@ HRGN FASTCALL RGNDATA_AllocRgn(INT n)
return hReg; return hReg;
} }
} }
else else
{
RGNDATA_FreeRgn(hReg); RGNDATA_FreeRgn(hReg);
} }
}
return NULL; return NULL;
} }
BOOL FASTCALL RGNDATA_InternalDelete( PROSRGNDATA pRgn ) BOOL FASTCALL RGNDATA_InternalDelete( PROSRGNDATA pRgn )
{ {
ASSERT(pRgn); ASSERT(pRgn);
if(pRgn->Buffer) if(pRgn->Buffer && pRgn->Buffer != (char *) &pRgn->BuiltInRect)
ExFreePool(pRgn->Buffer); ExFreePool(pRgn->Buffer);
return TRUE; return TRUE;
} }