Author: tkreuzer
Date: Thu Dec 18 08:12:55 2014
New Revision: 65735
URL:
http://svn.reactos.org/svn/reactos?rev=65735&view=rev
Log:
[WIN32K]
- Rename xmemcheck to REGION_bGrowBufferSize
- Implement REGION_bEnsureBufferSize and REGION_vAddRect helper functions
- Replace MERGERECT macro with REGION_bMergeRect inline function
Modified:
trunk/reactos/win32ss/gdi/ntgdi/region.c
Modified: trunk/reactos/win32ss/gdi/ntgdi/region.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/region.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/region.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/region.c [iso-8859-1] Thu Dec 18 08:12:55 2014
@@ -405,43 +405,109 @@
#define LARGE_COORDINATE 0x7fffffff /* FIXME */
#define SMALL_COORDINATE 0x80000000
-/*
- * Check to see if there is enough memory in the present region.
- */
-static __inline INT xmemcheck(PREGION reg, PRECTL *rect, PRECTL *firstrect)
-{
- if ((reg->rdh.nCount+1) * sizeof(RECT) >= reg->rdh.nRgnSize)
- {
- PRECTL temp;
- DWORD NewSize = 2 * reg->rdh.nRgnSize;
-
- if (NewSize < (reg->rdh.nCount + 1) * sizeof(RECT))
- {
- NewSize = (reg->rdh.nCount + 1) * sizeof(RECT);
- }
-
- temp = ExAllocatePoolWithTag(PagedPool, NewSize, TAG_REGION);
- if (temp == NULL)
- {
- return 0;
- }
-
- /* Copy the rectangles */
- COPY_RECTS(temp, *firstrect, reg->rdh.nCount);
-
- reg->rdh.nRgnSize = NewSize;
- if (*firstrect != ®->rdh.rcBound)
- {
- ExFreePoolWithTag(*firstrect, TAG_REGION);
- }
-
- *firstrect = temp;
- *rect = (*firstrect) + reg->rdh.nCount;
- }
- return 1;
-}
-
-#define MEMCHECK(reg, rect, firstrect) xmemcheck(reg,&(rect),(PRECTL
*)&(firstrect))
+static
+BOOL
+REGION_bGrowBufferSize(
+ _Inout_ PREGION prgn,
+ _In_ UINT cRects)
+{
+ ULONG cjNewSize;
+ PVOID pvBuffer;
+ NT_ASSERT(cRects > 0);
+
+ /* Make sure we don't overflow */
+ if (cRects > MAXULONG / sizeof(RECTL))
+ {
+ return FALSE;
+ }
+
+ /* Calculate new buffer size */
+ cjNewSize = cRects * sizeof(RECTL);
+
+ /* Avoid allocating too often, by duplicating the old buffer size
+ Note: we don't do an overflow check, since the old size will never
+ get that large before running out of memory. */
+ if (2 * prgn->rdh.nRgnSize > cjNewSize)
+ {
+ cjNewSize = 2 * prgn->rdh.nRgnSize;
+ }
+
+ /* Allocate the new buffer */
+ pvBuffer = ExAllocatePoolWithTag(PagedPool, cjNewSize, TAG_REGION);
+ if (pvBuffer == NULL)
+ {
+ return FALSE;
+ }
+
+ /* Copy the rects into the new buffer */
+ COPY_RECTS(pvBuffer, prgn->Buffer, prgn->rdh.nCount);
+
+ /* Free the old buffer */
+ if (prgn->Buffer != &prgn->rdh.rcBound)
+ {
+ ExFreePoolWithTag(prgn->Buffer, TAG_REGION);
+ }
+
+ /* Set the new buffer */
+ prgn->Buffer = pvBuffer;
+ prgn->rdh.nRgnSize = cjNewSize;
+
+ return TRUE;
+}
+
+static __inline
+BOOL
+REGION_bEnsureBufferSize(
+ _Inout_ PREGION prgn,
+ _In_ UINT cRects)
+{
+ /* Check if the current region size is too small */
+ if (cRects > prgn->rdh.nRgnSize / sizeof(RECTL))
+ {
+ /* Allocate a new buffer */
+ return REGION_bGrowBufferSize(prgn, cRects);
+ }
+
+ return TRUE;
+}
+
+FORCEINLINE
+VOID
+REGION_vAddRect(
+ _Inout_ PREGION prgn,
+ _In_ LONG left,
+ _In_ LONG top,
+ _In_ LONG right,
+ _In_ LONG bottom)
+{
+ PRECTL prcl;
+ NT_ASSERT((prgn->rdh.nCount + 1) * sizeof(RECT) <= prgn->rdh.nRgnSize);
+
+ prcl = &prgn->Buffer[prgn->rdh.nCount];
+ prcl->left = left;
+ prcl->top = top;
+ prcl->right = right;
+ prcl->bottom = bottom;
+ prgn->rdh.nCount++;
+}
+
+static __inline
+BOOL
+REGION_bAddRect(
+ _Inout_ PREGION prgn,
+ _In_ LONG left,
+ _In_ LONG top,
+ _In_ LONG right,
+ _In_ LONG bottom)
+{
+ if (!REGION_bEnsureBufferSize(prgn, prgn->rdh.nCount + 1))
+ {
+ return FALSE;
+ }
+
+ REGION_vAddRect(prgn, left, top, right, bottom);
+ return TRUE;
+}
typedef VOID (FASTCALL *overlapProcp)(PREGION, PRECT, PRECT, PRECT, PRECT, INT, INT);
typedef VOID (FASTCALL *nonOverlapProcp)(PREGION, PRECT, PRECT, INT, INT);
@@ -1180,10 +1246,7 @@
INT top,
INT bottom)
{
- INT left, right;
- RECTL *pNextRect;
-
- pNextRect = pReg->Buffer + pReg->rdh.nCount;
+ INT left, right;
while ((r1 != r1End) && (r2 != r2End))
{
@@ -1197,13 +1260,10 @@
* right next to each other. Since that should never happen... */
if (left < right)
{
- MEMCHECK(pReg, pNextRect, pReg->Buffer);
- pNextRect->left = left;
- pNextRect->top = top;
- pNextRect->right = right;
- pNextRect->bottom = bottom;
- pReg->rdh.nCount += 1;
- pNextRect++;
+ if (!REGION_bAddRect(pReg, left, top, right, bottom))
+ {
+ return;
+ }
}
/* Need to advance the pointers. Shift the one that extends
@@ -1290,23 +1350,52 @@
INT top,
INT bottom)
{
- RECTL *pNextRect;
-
- pNextRect = pReg->Buffer + pReg->rdh.nCount;
-
- while (r != rEnd)
- {
- MEMCHECK(pReg, pNextRect, pReg->Buffer);
- pNextRect->left = r->left;
- pNextRect->top = top;
- pNextRect->right = r->right;
- pNextRect->bottom = bottom;
- pReg->rdh.nCount += 1;
- pNextRect++;
- r++;
+ if (r != rEnd)
+ {
+ if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (rEnd - r)))
+ {
+ return;
+ }
+
+ do
+ {
+ REGION_vAddRect(pReg, r->left, top, r->right, bottom);
+ r++;
+ }
+ while (r != rEnd);
}
return;
+}
+
+static __inline
+BOOL
+REGION_bMergeRect(
+ _Inout_ PREGION prgn,
+ _In_ LONG left,
+ _In_ LONG top,
+ _In_ LONG right,
+ _In_ LONG bottom)
+{
+ if ((prgn->rdh.nCount != 0) &&
+ (prgn->Buffer[prgn->rdh.nCount - 1].top == top) &&
+ (prgn->Buffer[prgn->rdh.nCount - 1].bottom == bottom) &&
+ (prgn->Buffer[prgn->rdh.nCount - 1].right >= left))
+ {
+ if (prgn->Buffer[prgn->rdh.nCount - 1].right < right)
+ {
+ prgn->Buffer[prgn->rdh.nCount - 1].right = right;
+ }
+ }
+ else
+ {
+ if (!REGION_bAddRect(prgn, left, top, right, bottom))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
}
/*!
@@ -1333,42 +1422,17 @@
INT top,
INT bottom)
{
- RECTL *pNextRect;
-
- pNextRect = pReg->Buffer + pReg->rdh.nCount;
-
-#define MERGERECT(r) \
- if ((pReg->rdh.nCount != 0) && \
- ((pNextRect-1)->top == top) && \
- ((pNextRect-1)->bottom == bottom) && \
- ((pNextRect-1)->right >= r->left)) \
- { \
- if ((pNextRect-1)->right < r->right) \
- { \
- (pNextRect-1)->right = r->right; \
- } \
- } \
- else \
- { \
- MEMCHECK(pReg, pNextRect, pReg->Buffer); \
- pNextRect->top = top; \
- pNextRect->bottom = bottom; \
- pNextRect->left = r->left; \
- pNextRect->right = r->right; \
- pReg->rdh.nCount += 1; \
- pNextRect += 1; \
- } \
- r++;
-
while ((r1 != r1End) && (r2 != r2End))
{
if (r1->left < r2->left)
{
- MERGERECT(r1);
+ REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom);
+ r1++;
}
else
{
- MERGERECT(r2);
+ REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom);
+ r2++;
}
}
@@ -1376,7 +1440,8 @@
{
do
{
- MERGERECT(r1);
+ REGION_bMergeRect(pReg, r1->left, top, r1->right, bottom);
+ r1++;
}
while (r1 != r1End);
}
@@ -1384,7 +1449,8 @@
{
while (r2 != r2End)
{
- MERGERECT(r2);
+ REGION_bMergeRect(pReg, r2->left, top, r2->right, bottom);
+ r2++;
}
}
@@ -1497,20 +1563,19 @@
INT top,
INT bottom)
{
- RECTL *pNextRect;
-
- pNextRect = pReg->Buffer + pReg->rdh.nCount;
-
- while (r != rEnd)
- {
- MEMCHECK(pReg, pNextRect, pReg->Buffer);
- pNextRect->left = r->left;
- pNextRect->top = top;
- pNextRect->right = r->right;
- pNextRect->bottom = bottom;
- pReg->rdh.nCount += 1;
- pNextRect++;
- r++;
+ if (r != rEnd)
+ {
+ if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (rEnd - r)))
+ {
+ return;
+ }
+
+ do
+ {
+ REGION_vAddRect(pReg, r->left, top, r->right, bottom);
+ r++;
+ }
+ while (r != rEnd);
}
return;
@@ -1540,11 +1605,9 @@
INT top,
INT bottom)
{
- RECTL *pNextRect;
INT left;
left = r1->left;
- pNextRect = pReg->Buffer + pReg->rdh.nCount;
while ((r1 != r1End) && (r2 != r2End))
{
@@ -1576,13 +1639,11 @@
{
/* Left part of subtrahend covers part of minuend: add uncovered
* part of minuend to region and skip to next subtrahend. */
- MEMCHECK(pReg, pNextRect, pReg->Buffer);
- pNextRect->left = left;
- pNextRect->top = top;
- pNextRect->right = r2->left;
- pNextRect->bottom = bottom;
- pReg->rdh.nCount += 1;
- pNextRect++;
+ if (!REGION_bAddRect(pReg, left, top, r2->left, bottom))
+ {
+ return;
+ }
+
left = r2->right;
if (left >= r1->right)
{
@@ -1602,13 +1663,10 @@
/* Minuend used up: add any remaining piece before advancing. */
if (r1->right > left)
{
- MEMCHECK(pReg, pNextRect, pReg->Buffer);
- pNextRect->left = left;
- pNextRect->top = top;
- pNextRect->right = r1->right;
- pNextRect->bottom = bottom;
- pReg->rdh.nCount += 1;
- pNextRect++;
+ if (!REGION_bAddRect(pReg, left, top, r1->right, bottom))
+ {
+ return;
+ }
}
r1++;
@@ -1617,21 +1675,25 @@
}
}
- /* Add remaining minuend rectangles to region. */
- while (r1 != r1End)
- {
- MEMCHECK(pReg, pNextRect, pReg->Buffer);
- pNextRect->left = left;
- pNextRect->top = top;
- pNextRect->right = r1->right;
- pNextRect->bottom = bottom;
- pReg->rdh.nCount += 1;
- pNextRect++;
- r1++;
- if (r1 != r1End)
- {
- left = r1->left;
- }
+ /* Make sure the buffer is large enough for all remaining operations */
+ if (r1 != r1End)
+ {
+ if (!REGION_bEnsureBufferSize(pReg, pReg->rdh.nCount + (r1End - r1)))
+ {
+ return;
+ }
+
+ /* Add remaining minuend rectangles to region. */
+ do
+ {
+ REGION_vAddRect(pReg, left, top, r1->right, bottom);
+ r1++;
+ if (r1 != r1End)
+ {
+ left = r1->left;
+ }
+ }
+ while (r1 != r1End);
}
return;