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.

svn path=/trunk/; revision=40277
This commit is contained in:
Timo Kreuzer 2009-03-29 00:26:30 +00:00
parent 77b12d6d18
commit d32f5cf257

View file

@ -77,40 +77,39 @@ BOOL APIENTRY EngIntersectRect(RECTL* prcDst, RECTL* prcSrc1, RECTL* prcSrc2)
} }
static BOOLEAN APIENTRY static BOOLEAN APIENTRY
BltMask(SURFOBJ* Dest, BltMask(SURFOBJ* psoDest,
SURFOBJ* Source, SURFOBJ* psoSource, // FIXME: why isn't this used?
SURFOBJ* Mask, SURFOBJ* psoMask,
XLATEOBJ* ColorTranslation, XLATEOBJ* ColorTranslation,
RECTL* DestRect, RECTL* DestRect,
POINTL* SourcePoint, POINTL* SourcePoint,
POINTL* MaskPoint, POINTL* MaskPoint, // FIXME: why isn't this used?
BRUSHOBJ* pbo, BRUSHOBJ* pbo,
POINTL* BrushPoint, POINTL* BrushPoint,
ROP4 Rop4) ROP4 Rop4)
{ {
LONG i, j, dx, dy, c8; LONG x, y;
BYTE *tMask, *lMask; BYTE *pjMskLine, *pjMskCurrent;
static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; BYTE fjMaskBit0, fjMaskBit;
/* Pattern brushes */ /* Pattern brushes */
PEBRUSHOBJ pebo = NULL; PEBRUSHOBJ pebo = NULL;
SURFOBJ *psoPattern = NULL; SURFOBJ *psoPattern = NULL;
PSURFACE psurfPattern; PSURFACE psurfPattern;
ULONG PatternWidth = 0, PatternHeight = 0, PatternY = 0; 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 (Mask == NULL) if (psoMask == NULL)
{ {
return FALSE; return FALSE;
} }
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
if (pbo && pbo->iSolidColor == 0xFFFFFFFF) if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
{ {
pebo = CONTAINING_RECORD( pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
pbo,
EBRUSHOBJ,
BrushObject);
psurfPattern = SURFACE_LockSurface(pebo->pbrush->hbmPattern); psurfPattern = SURFACE_LockSurface(pebo->pbrush->hbmPattern);
if (psurfPattern != NULL) if (psurfPattern != NULL)
@ -119,46 +118,75 @@ BltMask(SURFOBJ* Dest,
PatternWidth = psoPattern->sizlBitmap.cx; PatternWidth = psoPattern->sizlBitmap.cx;
PatternHeight = psoPattern->sizlBitmap.cy; PatternHeight = psoPattern->sizlBitmap.cy;
} }
fnPattern_GetPixel = DibFunctionsForBitmapFormat[psoPattern->iBitmapFormat].DIB_GetPixel;
} }
else else
psurfPattern = NULL; psurfPattern = NULL;
tMask = (PBYTE)Mask->pvScan0 + SourcePoint->y * Mask->lDelta + (SourcePoint->x >> 3); pjMskLine = (PBYTE)psoMask->pvScan0 + SourcePoint->y * psoMask->lDelta + (SourcePoint->x >> 3);
for (j = 0; j < dy; j++) fjMaskBit0 = 0x80 >> (SourcePoint->x & 0x07);
fnDest_PutPixel = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel;
if (psurfPattern)
{ {
lMask = tMask; XlateObj = pebo ? pebo->XlateObject : NULL;
c8 = SourcePoint->x & 0x07; PatternY = (DestRect->top - BrushPoint->y) % PatternHeight;
if (PatternY < 0)
if (psurfPattern != NULL)
PatternY = (DestRect->top + j) % PatternHeight;
for (i = 0; i < dx; i++)
{ {
if (0 != (*lMask & maskbit[c8])) PatternY += PatternHeight;
{ }
if (psurfPattern == NULL) PatternX0 = (DestRect->left - BrushPoint->x) % PatternWidth;
{ if (PatternX0 < 0)
DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel( {
Dest, DestRect->left + i, DestRect->top + j, pbo ? pbo->iSolidColor : 0); PatternX0 += PatternWidth;
} }
else
{ for (y = DestRect->top; y < DestRect->bottom; y++)
DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel( {
Dest, DestRect->left + i, DestRect->top + j, pjMskCurrent = pjMskLine;
DIB_GetSource(psoPattern, (DestRect->left + i) % PatternWidth, PatternY, pebo ? pebo->XlateObject : NULL)); fjMaskBit = fjMaskBit0;
} PatternX = PatternX0;
}
c8++; for (x = DestRect->left; x < DestRect->right; x++)
if (8 == c8) {
{ if (*pjMskCurrent & fjMaskBit)
lMask++; {
c8 = 0; fnDest_PutPixel(psoDest, x, y,
} XLATEOBJ_iXlate(XlateObj,
fnPattern_GetPixel(psoPattern, PatternX, PatternY)));
}
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)
{
fnDest_PutPixel(psoDest, x, y, Pattern);
}
fjMaskBit = _rotr8(fjMaskBit, 1);
pjMskCurrent += (fjMaskBit >> 7);
}
pjMskLine += psoMask->lDelta;
} }
tMask += Mask->lDelta;
} }
if (psurfPattern != NULL) if (psurfPattern)
SURFACE_UnlockSurface(psurfPattern); SURFACE_UnlockSurface(psurfPattern);
return TRUE; return TRUE;