Author: tkreuzer
Date: Sat Mar 24 16:24:46 2012
New Revision: 56219
URL:
http://svn.reactos.org/svn/reactos?rev=56219&view=rev
Log:
[WIN32K]
- Add support for pattern brushes and bottom-to-top blt in new EngBitblt
- implement a new much simpler EngCopyBits
- improve clip enumeration code
The code now generally works very well now, only has a few bugs left
Modified:
trunk/reactos/subsystems/win32/win32k/eng/bitblt_new.c
Modified: trunk/reactos/subsystems/win32/win32k/eng/bitblt_new.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/bitblt_new.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/bitblt_new.c [iso-8859-1] Sat Mar 24
16:24:46 2012
@@ -23,22 +23,26 @@
{
ULONG cx, cy;
- /* Copy the target start point */
- pbltdata->siDst.ptOrig.x = prclClipped->left;
- pbltdata->siDst.ptOrig.y = prclClipped->top;
-
/* Calculate width and height of this rect */
pbltdata->ulWidth = prclClipped->right - prclClipped->left;
pbltdata->ulHeight = prclClipped->bottom - prclClipped->top;
+
+ /* Calculate the offset to the origin coordinates */
+ cx = (prclClipped->left - prclOrg->left);
+ if (pbltdata->dy < 0)
+ cy = (prclClipped->bottom - 1 - prclOrg->top);
+ else
+ cy = (prclClipped->top - prclOrg->top);
+
+ /* Calculate the target start point */
+ pbltdata->siDst.ptOrig.x = prclOrg->left + cx;
+ pbltdata->siDst.ptOrig.y = prclOrg->top + cy;
/* Calculate start position for target */
pbltdata->siDst.pjBase = pbltdata->siDst.pvScan0;
pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.y *
pbltdata->siDst.lDelta;
pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.x * pbltdata->siDst.jBpp /
8;
- /* Calculate the offset from the original coordinates */
- cx = (prclClipped->left - prclOrg->left);
- cy = (prclClipped->top - prclOrg->top);
if (pptlSrc)
{
@@ -97,8 +101,12 @@
BOOL bEnumMore;
RECT_ENUM rcenum;
PSIZEL psizlPat;
-
-
+ SURFOBJ *psoPattern;
+
+//static int count = 0;
+//if (++count >= 1230) __debugbreak();
+
+ /* Sanity checks */
ASSERT(psoTrg);
ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP);
ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP);
@@ -110,14 +118,13 @@
rcTrg = *prclTrg;
+ bltdata.dy = 1;
bltdata.rop4 = rop4;
+ bltdata.apfnDoRop[0] = gapfnRop[ROP4_BKGND(rop4)];
+ bltdata.apfnDoRop[1] = gapfnRop[ROP4_FGND(rop4)];
if (!pxlo) pxlo = &gexloTrivial.xlo;
bltdata.pxlo = pxlo;
bltdata.pfnXlate = XLATEOBJ_pfnXlate(pxlo);
-
- bltdata.siDst.pvScan0 = psoTrg->pvScan0;
- bltdata.siDst.lDelta = psoTrg->lDelta;
- bltdata.siDst.jBpp = gajBitsPerFormat[psoTrg->iBitmapFormat];
/* Check if the ROP uses a source */
if (ROP4_USES_SOURCE(rop4))
@@ -132,18 +139,18 @@
ASSERT(pptlSrc->x <= psoSrc->sizlBitmap.cx);
ASSERT(pptlSrc->y <= psoSrc->sizlBitmap.cy);
- bltdata.siSrc.pvScan0 = psoSrc->pvScan0;
- bltdata.siSrc.lDelta = psoSrc->lDelta;
- bltdata.siSrc.jBpp = gajBitsPerFormat[psoSrc->iBitmapFormat];
-
/* Check if source and target are equal */
if (psoSrc == psoTrg)
{
/* Analyze the copying direction */
- if (rcTrg.top < pptlSrc->y)
+ if (rcTrg.top > pptlSrc->y)
+ {
+ /* Need to copy from bottom to top */
+ iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTUP : CD_LEFTUP;
+ bltdata.dy = -1;
+ }
+ else
iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTDOWN : CD_LEFTDOWN;
- else
- iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTUP : CD_LEFTUP;
/* Check for special right to left case */
if ((rcTrg.top == pptlSrc->y) && (rcTrg.left > pptlSrc->x))
@@ -151,6 +158,7 @@
/* Use 0 as target format to get special right to left versions */
bltdata.siDst.iFormat = 0;
bltdata.siSrc.iFormat = psoSrc->iBitmapFormat;
+ __debugbreak();
}
else
{
@@ -164,11 +172,23 @@
bltdata.siDst.iFormat = psoTrg->iBitmapFormat;
bltdata.siSrc.iFormat = psoSrc->iBitmapFormat;
}
+
+ /* Set the source format info */
+ bltdata.siSrc.pvScan0 = psoSrc->pvScan0;
+ bltdata.siSrc.lDelta = psoSrc->lDelta;
+ bltdata.siSrc.cjAdvanceY = bltdata.dy * psoSrc->lDelta;
+ bltdata.siSrc.jBpp = gajBitsPerFormat[psoSrc->iBitmapFormat];
}
else
{
bltdata.siDst.iFormat = psoTrg->iBitmapFormat;
}
+
+ /* Set the destination format info */
+ bltdata.siDst.pvScan0 = psoTrg->pvScan0;
+ bltdata.siDst.lDelta = psoTrg->lDelta;
+ bltdata.siDst.cjAdvanceY = bltdata.dy * psoTrg->lDelta;
+ bltdata.siDst.jBpp = gajBitsPerFormat[psoTrg->iBitmapFormat];
/* Check if the ROP uses a pattern / brush */
if (ROP4_USES_PATTERN(rop4))
@@ -182,17 +202,25 @@
/* Check if this is a pattern brush */
if (pbo->iSolidColor == 0xFFFFFFFF)
{
- __debugbreak();
-
- // FIXME
- bltdata.siPat.iFormat = 0;//psoPat->iBitmapFormat;
- bltdata.siPat.pvScan0 = 0;//psoPat->pvScan0;
- bltdata.siPat.lDelta = 0;//psoPat->lDelta;
-
- bltdata.ulPatWidth = 0;
- bltdata.ulPatHeight = 0;
-
- psizlPat = 0;// fixme
+ /* Get the realized pattern bitmap */
+ psoPattern = BRUSHOBJ_psoPattern(pbo);
+ if (!psoPattern)
+ {
+ __debugbreak();
+ return FALSE;
+ }
+
+ /* Set the pattern format info */
+ bltdata.siPat.iFormat = psoPattern->iBitmapFormat;
+ bltdata.siPat.pvScan0 = psoPattern->pvScan0;
+ bltdata.siPat.lDelta = psoPattern->lDelta;
+ bltdata.siPat.cjAdvanceY = bltdata.dy * psoPattern->lDelta;
+ bltdata.siPat.jBpp = gajBitsPerFormat[psoPattern->iBitmapFormat];
+
+ bltdata.ulPatWidth = psoPattern->sizlBitmap.cx;
+ bltdata.ulPatHeight = psoPattern->sizlBitmap.cy;
+
+ psizlPat = &psoPattern->sizlBitmap;
}
else
{
@@ -218,9 +246,8 @@
bltdata.siMsk.iFormat = psoMask->iBitmapFormat;
bltdata.siMsk.pvScan0 = psoMask->pvScan0;
bltdata.siMsk.lDelta = psoMask->lDelta;
-
- bltdata.apfnDoRop[0] = gapfnRop[ROP4_BKGND(rop4)];
- bltdata.apfnDoRop[1] = gapfnRop[ROP4_FGND(rop4)];
+ bltdata.siMsk.cjAdvanceY = bltdata.dy * psoMask->lDelta;
+ bltdata.siMsk.jBpp = 1;
/* Calculate the masking function index */
iFunctionIndex = ROP4_USES_PATTERN(rop4) ? 1 : 0;
@@ -247,56 +274,54 @@
{
/* Start the enumeration of the clip object */
CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, iDirection, 0);
- do
- {
- /* Enumerate a set of rectangles */
- bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum);
-
- /* Loop all rectangles we got */
- for (i = 0; i < rcenum.c; i++)
+ bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum);
+ }
+ else if (pco->iDComplexity == DC_RECT)
+ {
+ /* Use the clip bounds */
+ rcenum.arcl[0] = pco->rclBounds;
+ rcenum.c = 1;
+ bEnumMore = FALSE;
+ }
+ else
+ {
+ /* Use the target rect */
+ rcenum.arcl[0] = rcTrg;
+ rcenum.c = 1;
+ bEnumMore = FALSE;
+ }
+
+ /* Enter enumeration loop */
+ while (TRUE)
+ {
+ /* Loop all rectangles we got */
+ for (i = 0; i < rcenum.c; i++)
+ {
+ /* Intersect this rect with the target rect */
+ if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i],
&rcTrg))
{
- /* Intersect this rect with the target rect */
- if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i],
&rcTrg))
- {
- /* This rect is outside the bounds, continue */
- continue;
- }
-
- /* Calculate the coordinates */
- CalculateCoordinates(&bltdata,
- &rcenum.arcl[i],
- prclTrg,
- pptlSrc,
- pptlMask,
- pptlBrush,
- psizlPat);
-
- /* Call the dib function */
- pfnBitBlt(&bltdata);
+ /* This rect is outside the bounds, continue */
+ continue;
}
- }
- while (bEnumMore);
- }
- else
- {
- /* Check if there is something to clip */
- if (pco->iDComplexity == DC_RECT)
- {
- /* Clip the target rect to the bounds of the clipping region */
- RECTL_bIntersectRect(&rcTrg, &rcTrg, &pco->rclBounds);
- }
-
- /* Calculate the coordinates */
- CalculateCoordinates(&bltdata,
- &rcTrg,
- prclTrg,
- pptlSrc,
- pptlMask,
- pptlBrush,
- psizlPat);
-
- /* Call the dib function */
- pfnBitBlt(&bltdata);
+
+ /* Calculate coordinates and pointers */
+ CalculateCoordinates(&bltdata,
+ &rcenum.arcl[i],
+ prclTrg,
+ pptlSrc,
+ pptlMask,
+ pptlBrush,
+ psizlPat);
+
+ /* Call the dib function */
+ pfnBitBlt(&bltdata);
+ }
+
+ /* Bail out, when there's nothing more to do */
+ if(!bEnumMore) break;
+
+ /* Enumerate more rectangles */
+ bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum);
}
return TRUE;
@@ -563,4 +588,43 @@
return bResult;
}
-
+BOOL
+APIENTRY
+EngCopyBits(
+ SURFOBJ *psoTrg,
+ SURFOBJ *psoSrc,
+ CLIPOBJ *pco,
+ XLATEOBJ *pxlo,
+ RECTL *prclTrg,
+ POINTL *pptlSrc)
+{
+ PFN_DrvCopyBits pfnCopyBits;
+
+ /* Is the target surface device managed? */
+ if (SURFOBJ_flags(psoTrg) & HOOK_COPYBITS)
+ {
+ pfnCopyBits = GDIDEVFUNCS(psoTrg).CopyBits;
+ }
+ if (SURFOBJ_flags(psoSrc) & HOOK_COPYBITS)
+ {
+ pfnCopyBits = GDIDEVFUNCS(psoSrc).CopyBits;
+ }
+ else
+ {
+ /* Use SRCCOPY for 2 bitmaps */
+ return EngBitBlt(psoTrg,
+ psoSrc,
+ NULL,
+ pco,
+ pxlo,
+ prclTrg,
+ pptlSrc,
+ NULL,
+ NULL,
+ NULL,
+ ROP4_SRCCOPY);
+ }
+
+ /* Forward to the driver */
+ return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc);
+}