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;