Author: tkreuzer
Date: Sun Mar 29 04:26:30 2009
New Revision: 40277
URL:
http://svn.reactos.org/svn/reactos?rev=40277&view=rev
Log:
BltMask:
by me: optimize by replacing the maskbit table with a byte containing the maskbit and
rotating using _rotr8. Also move the comparison out of the loop, making 2 loops, one with
pattern, one without.
By Evgeniy Boltik: Optimize by using function pointers. Fix calculation of brush position.
By me again: optimize the fix by moving the calculation out of the outer loop.
Modified:
trunk/reactos/subsystems/win32/win32k/eng/bitblt.c
Modified: trunk/reactos/subsystems/win32/win32k/eng/bitblt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/bitblt.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/bitblt.c [iso-8859-1] Sun Mar 29 04:26:30
2009
@@ -77,40 +77,39 @@
}
static BOOLEAN APIENTRY
-BltMask(SURFOBJ* Dest,
- SURFOBJ* Source,
- SURFOBJ* Mask,
+BltMask(SURFOBJ* psoDest,
+ SURFOBJ* psoSource, // FIXME: why isn't this used?
+ SURFOBJ* psoMask,
XLATEOBJ* ColorTranslation,
RECTL* DestRect,
POINTL* SourcePoint,
- POINTL* MaskPoint,
+ POINTL* MaskPoint, // FIXME: why isn't this used?
BRUSHOBJ* pbo,
POINTL* BrushPoint,
ROP4 Rop4)
{
- LONG i, j, dx, dy, c8;
- BYTE *tMask, *lMask;
- static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+ LONG x, y;
+ BYTE *pjMskLine, *pjMskCurrent;
+ BYTE fjMaskBit0, fjMaskBit;
/* Pattern brushes */
PEBRUSHOBJ pebo = NULL;
SURFOBJ *psoPattern = NULL;
PSURFACE psurfPattern;
- ULONG PatternWidth = 0, PatternHeight = 0, PatternY = 0;
-
- if (Mask == NULL)
+ ULONG PatternWidth = 0, PatternHeight = 0;
+ LONG PatternX0 = 0, PatternX = 0, PatternY = 0;
+ PFN_DIB_PutPixel fnDest_PutPixel = NULL;
+ PFN_DIB_GetPixel fnPattern_GetPixel = NULL;
+ XLATEOBJ *XlateObj;
+ ULONG Pattern = 0;
+
+ if (psoMask == NULL)
{
return FALSE;
}
- dx = DestRect->right - DestRect->left;
- dy = DestRect->bottom - DestRect->top;
-
if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
{
- pebo = CONTAINING_RECORD(
- pbo,
- EBRUSHOBJ,
- BrushObject);
+ pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
psurfPattern = SURFACE_LockSurface(pebo->pbrush->hbmPattern);
if (psurfPattern != NULL)
@@ -119,46 +118,75 @@
PatternWidth = psoPattern->sizlBitmap.cx;
PatternHeight = psoPattern->sizlBitmap.cy;
}
+ fnPattern_GetPixel =
DibFunctionsForBitmapFormat[psoPattern->iBitmapFormat].DIB_GetPixel;
}
else
psurfPattern = NULL;
- tMask = (PBYTE)Mask->pvScan0 + SourcePoint->y * Mask->lDelta +
(SourcePoint->x >> 3);
- for (j = 0; j < dy; j++)
- {
- lMask = tMask;
- c8 = SourcePoint->x & 0x07;
-
- if (psurfPattern != NULL)
- PatternY = (DestRect->top + j) % PatternHeight;
-
- for (i = 0; i < dx; i++)
- {
- if (0 != (*lMask & maskbit[c8]))
+ pjMskLine = (PBYTE)psoMask->pvScan0 + SourcePoint->y * psoMask->lDelta +
(SourcePoint->x >> 3);
+ fjMaskBit0 = 0x80 >> (SourcePoint->x & 0x07);
+
+ fnDest_PutPixel =
DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel;
+ if (psurfPattern)
+ {
+ XlateObj = pebo ? pebo->XlateObject : NULL;
+ PatternY = (DestRect->top - BrushPoint->y) % PatternHeight;
+ if (PatternY < 0)
+ {
+ PatternY += PatternHeight;
+ }
+ PatternX0 = (DestRect->left - BrushPoint->x) % PatternWidth;
+ if (PatternX0 < 0)
+ {
+ PatternX0 += PatternWidth;
+ }
+
+ for (y = DestRect->top; y < DestRect->bottom; y++)
+ {
+ pjMskCurrent = pjMskLine;
+ fjMaskBit = fjMaskBit0;
+ PatternX = PatternX0;
+
+ for (x = DestRect->left; x < DestRect->right; x++)
{
- if (psurfPattern == NULL)
+ if (*pjMskCurrent & fjMaskBit)
{
- DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
- Dest, DestRect->left + i, DestRect->top + j, pbo ?
pbo->iSolidColor : 0);
+ fnDest_PutPixel(psoDest, x, y,
+ XLATEOBJ_iXlate(XlateObj,
+ fnPattern_GetPixel(psoPattern, PatternX, PatternY)));
}
- else
+ fjMaskBit = _rotr8(fjMaskBit, 1);
+ pjMskCurrent += (fjMaskBit >> 7);
+ PatternX++;
+ PatternX %= PatternWidth;
+ }
+ pjMskLine += psoMask->lDelta;
+ PatternY++;
+ PatternY %= PatternHeight;
+ }
+ }
+ else
+ {
+ Pattern = pbo ? pbo->iSolidColor : 0;
+ for (y = DestRect->top; y < DestRect->bottom; y++)
+ {
+ pjMskCurrent = pjMskLine;
+ fjMaskBit = fjMaskBit0;
+
+ for (x = DestRect->left; x < DestRect->right; x++)
+ {
+ if (*pjMskCurrent & fjMaskBit)
{
- DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel(
- Dest, DestRect->left + i, DestRect->top + j,
- DIB_GetSource(psoPattern, (DestRect->left + i) % PatternWidth,
PatternY, pebo ? pebo->XlateObject : NULL));
+ fnDest_PutPixel(psoDest, x, y, Pattern);
}
+ fjMaskBit = _rotr8(fjMaskBit, 1);
+ pjMskCurrent += (fjMaskBit >> 7);
}
- c8++;
- if (8 == c8)
- {
- lMask++;
- c8 = 0;
- }
- }
- tMask += Mask->lDelta;
- }
-
- if (psurfPattern != NULL)
+ pjMskLine += psoMask->lDelta;
+ }
+ }
+
+ if (psurfPattern)
SURFACE_UnlockSurface(psurfPattern);
return TRUE;