Author: tkreuzer
Date: Tue Apr 14 06:47:15 2009
New Revision: 40495
URL:
http://svn.reactos.org/svn/reactos?rev=40495&view=rev
Log:
EngBitBlt provides bitblt capabilities between standard-format bitmap surfaces. It does
not provide transfer between different opaque device managed surfaces. So get rid of
IntEngEnter/Leave in EngBitBlt. Also GDI should call the drivers function if *any* of the
surfaces is managed by the driver, and only in the case that the other surface is an
opaque surface managed by a different driver, GDI needs to provide an intermediate surface
using DrvCopyBits, and in this case only for the source surface, never for the target
surface. This situation can currently not occur on reactos, as we do not support more than
one display driver. This fixes the problem incredible recursive call chains and excessive
copying. Improves mouse pointer performance. Other Eng functions are tbd. DrvBitBlt is
never called with a single clipping rectangle, so set pco to NULL if it's complexity
is DC_RECT, as we clipped the bounding rect already and EngBitBlt is not called when
DrvBitBlt fails.
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] Tue Apr 14 06:47:15
2009
@@ -4,6 +4,7 @@
* PURPOSE: GDI BitBlt Functions
* FILE: subsys/win32k/eng/bitblt.c
* PROGRAMER: Jason Filby
+ * Timo Kreuzer
* REVISION HISTORY:
* 2/10/1999: Created
*/
@@ -285,7 +286,7 @@
POINTL *MaskOrigin,
BRUSHOBJ *pbo,
POINTL *BrushOrigin,
- ROP4 Rop4)
+ ROP4 rop4)
{
BYTE clippingType;
RECTL CombinedRect;
@@ -294,10 +295,7 @@
POINTL InputPoint;
RECTL InputRect;
RECTL OutputRect;
- POINTL Translate;
- INTENG_ENTER_LEAVE EnterLeaveSource;
- INTENG_ENTER_LEAVE EnterLeaveDest;
- SURFOBJ* InputObj;
+ SURFOBJ* InputObj = 0;
SURFOBJ* OutputObj;
PBLTRECTFUNC BltRectFunc;
BOOLEAN Ret = TRUE;
@@ -309,9 +307,9 @@
BOOL UsesPattern;
POINTL AdjustedBrushOrigin;
- UsesSource = ROP4_USES_SOURCE(Rop4);
- UsesPattern = ROP4_USES_PATTERN(Rop4);
- if (R4_NOOP == Rop4)
+ UsesSource = ROP4_USES_SOURCE(rop4);
+ UsesPattern = ROP4_USES_PATTERN(rop4);
+ if (R4_NOOP == rop4)
{
/* Copy destination onto itself: nop */
return TRUE;
@@ -367,14 +365,7 @@
InputRect.top = InputPoint.y;
InputRect.bottom = InputPoint.y + (OutputRect.bottom - OutputRect.top);
- if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE,
- &Translate, &InputObj))
- {
- return FALSE;
- }
-
- InputPoint.x += Translate.x;
- InputPoint.y += Translate.y;
+ InputObj = SourceObj;
}
else
{
@@ -415,36 +406,20 @@
if (OutputRect.right <= OutputRect.left ||
OutputRect.bottom <= OutputRect.top)
{
- if (UsesSource)
- {
- IntEngLeave(&EnterLeaveSource);
- }
return TRUE;
}
- if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE,
&Translate,
- &OutputObj))
- {
- if (UsesSource)
- {
- IntEngLeave(&EnterLeaveSource);
- }
- return FALSE;
- }
-
- OutputRect.left += Translate.x;
- OutputRect.right += Translate.x;
- OutputRect.top += Translate.y;
- OutputRect.bottom += Translate.y;
+ OutputObj = DestObj;
if (BrushOrigin)
{
- AdjustedBrushOrigin.x = BrushOrigin->x + Translate.x;
- AdjustedBrushOrigin.y = BrushOrigin->y + Translate.y;
- }
- else
- {
- AdjustedBrushOrigin = Translate;
+ AdjustedBrushOrigin.x = BrushOrigin->x;
+ AdjustedBrushOrigin.y = BrushOrigin->y;
+ }
+ else
+ {
+ AdjustedBrushOrigin.x = 0;
+ AdjustedBrushOrigin.y = 0;
}
/* Determine clipping type */
@@ -457,11 +432,11 @@
clippingType = ClipRegion->iDComplexity;
}
- if (R4_MASK == Rop4)
+ if (R4_MASK == rop4)
{
BltRectFunc = BltMask;
}
- else if (ROP3_TO_ROP4(PATCOPY) == Rop4)
+ else if (ROP3_TO_ROP4(PATCOPY) == rop4)
{
if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
BltRectFunc = CallDibBitBlt;
@@ -479,21 +454,21 @@
case DC_TRIVIAL:
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
&OutputRect, &InputPoint, MaskOrigin, pbo,
- &AdjustedBrushOrigin, Rop4);
+ &AdjustedBrushOrigin, rop4);
break;
case DC_RECT:
/* Clip the blt to the clip rectangle */
- ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
- ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
- ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
- ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
+ ClipRect.left = ClipRegion->rclBounds.left;
+ ClipRect.right = ClipRegion->rclBounds.right;
+ ClipRect.top = ClipRegion->rclBounds.top;
+ ClipRect.bottom = ClipRegion->rclBounds.bottom;
if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
{
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
&CombinedRect, &Pt, MaskOrigin, pbo,
- &AdjustedBrushOrigin, Rop4);
+ &AdjustedBrushOrigin, rop4);
}
break;
case DC_COMPLEX:
@@ -523,10 +498,10 @@
for (i = 0; i < RectEnum.c; i++)
{
- ClipRect.left = RectEnum.arcl[i].left + Translate.x;
- ClipRect.right = RectEnum.arcl[i].right + Translate.x;
- ClipRect.top = RectEnum.arcl[i].top + Translate.y;
- ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
+ ClipRect.left = RectEnum.arcl[i].left;
+ ClipRect.right = RectEnum.arcl[i].right;
+ ClipRect.top = RectEnum.arcl[i].top;
+ ClipRect.bottom = RectEnum.arcl[i].bottom;
if (RECTL_bIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
{
Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left;
@@ -534,7 +509,7 @@
Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
ColorTranslation, &CombinedRect,
&Pt,
MaskOrigin, pbo, &AdjustedBrushOrigin,
- Rop4) && Ret;
+ rop4) && Ret;
}
}
}
@@ -542,170 +517,141 @@
break;
}
-
- IntEngLeave(&EnterLeaveDest);
- if (UsesSource)
- {
- IntEngLeave(&EnterLeaveSource);
- }
-
return Ret;
}
BOOL APIENTRY
-IntEngBitBltEx(SURFOBJ *psoDest,
- SURFOBJ *psoSource,
- SURFOBJ *MaskSurf,
- CLIPOBJ *ClipRegion,
- XLATEOBJ *ColorTranslation,
- RECTL *DestRect,
- POINTL *SourcePoint,
- POINTL *MaskOrigin,
- BRUSHOBJ *pbo,
- POINTL *BrushOrigin,
- ROP4 Rop4,
- BOOL RemoveMouse)
+IntEngBitBltEx(
+ SURFOBJ *psoTrg,
+ SURFOBJ *psoSrc,
+ SURFOBJ *psoMask,
+ CLIPOBJ *pco,
+ XLATEOBJ *pxlo,
+ RECTL *prclTrg,
+ POINTL *pptlSrc,
+ POINTL *pptlMask,
+ BRUSHOBJ *pbo,
+ POINTL *pptlBrush,
+ ROP4 rop4,
+ BOOL bRemoveMouse)
{
- BOOLEAN ret;
- RECTL InputClippedRect;
- RECTL OutputRect;
- POINTL InputPoint;
- BOOLEAN UsesSource;
- SURFACE *psurfDest;
- SURFACE *psurfSource = NULL;
-
- if (psoDest == NULL)
- return FALSE;
-
- psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
- ASSERT(psurfDest);
-
- InputClippedRect = *DestRect;
- if (InputClippedRect.right < InputClippedRect.left)
- {
- InputClippedRect.left = DestRect->right;
- InputClippedRect.right = DestRect->left;
- }
- if (InputClippedRect.bottom < InputClippedRect.top)
- {
- InputClippedRect.top = DestRect->bottom;
- InputClippedRect.bottom = DestRect->top;
- }
- UsesSource = ROP4_USES_SOURCE(Rop4);
- if (UsesSource)
- {
- if (NULL == SourcePoint || NULL == psoSource)
- {
- return FALSE;
- }
- InputPoint = *SourcePoint;
-
- /* Make sure we don't try to copy anything outside the valid source
- region */
- if (InputPoint.x < 0)
- {
- InputClippedRect.left -= InputPoint.x;
- InputPoint.x = 0;
- }
- if (InputPoint.y < 0)
- {
- InputClippedRect.top -= InputPoint.y;
- InputPoint.y = 0;
- }
- if (psoSource->sizlBitmap.cx < InputPoint.x +
- InputClippedRect.right -
- InputClippedRect.left)
- {
- InputClippedRect.right = InputClippedRect.left +
- psoSource->sizlBitmap.cx - InputPoint.x;
- }
- if (psoSource->sizlBitmap.cy < InputPoint.y +
- InputClippedRect.bottom -
- InputClippedRect.top)
- {
- InputClippedRect.bottom = InputClippedRect.top +
- psoSource->sizlBitmap.cy - InputPoint.y;
- }
-
- if (InputClippedRect.right < InputClippedRect.left ||
- InputClippedRect.bottom < InputClippedRect.top)
- {
- /* Everything clipped away, nothing to do */
+ SURFACE *psurfTrg;
+ SURFACE *psurfSrc = NULL;
+ BOOL bResult;
+ RECTL rclClipped;
+ RECTL rclSrc;
+// INTENG_ENTER_LEAVE EnterLeaveSource;
+// INTENG_ENTER_LEAVE EnterLeaveDest;
+ PFN_DrvBitBlt pfnBitBlt;
+
+ ASSERT(psoTrg);
+ psurfTrg = CONTAINING_RECORD(psoTrg, SURFACE, SurfObj);
+
+ /* FIXME: Should we really allow to pass non-well-ordered rects? */
+ rclClipped = *prclTrg;
+ RECTL_vMakeWellOrdered(&rclClipped);
+
+ /* Clip target rect against the bounds of the clipping region */
+ if (pco)
+ {
+ if (!RECTL_bIntersectRect(&rclClipped, &rclClipped,
&pco->rclBounds))
+ {
+ /* Nothing left */
return TRUE;
}
- }
-
- /* Clip against the bounds of the clipping region so we won't try to write
- * outside the surface */
- if (NULL != ClipRegion)
- {
- if (!RECTL_bIntersectRect(&OutputRect, &InputClippedRect,
- &ClipRegion->rclBounds))
- {
- return TRUE;
- }
- InputPoint.x += OutputRect.left - InputClippedRect.left;
- InputPoint.y += OutputRect.top - InputClippedRect.top;
- }
- else
- {
- OutputRect = InputClippedRect;
- }
-
- if (RemoveMouse)
- {
- SURFACE_LockBitmapBits(psurfDest);
-
- if (UsesSource)
- {
- if (psoSource != psoDest)
- {
- psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
- SURFACE_LockBitmapBits(psurfSource);
- }
- MouseSafetyOnDrawStart(psoSource, InputPoint.x, InputPoint.y,
- (InputPoint.x + abs(DestRect->right -
DestRect->left)),
- (InputPoint.y + abs(DestRect->bottom -
DestRect->top)));
- }
- MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
- }
-
- /* No success yet */
- ret = FALSE;
-
- /* Call the driver's DrvBitBlt if available */
- if (psurfDest->flHooks & HOOK_BITBLT)
- {
- ret = GDIDEVFUNCS(psoDest).BitBlt(
- psoDest, psoSource, MaskSurf, ClipRegion, ColorTranslation,
- &OutputRect, &InputPoint, MaskOrigin, pbo, BrushOrigin,
- Rop4);
- }
-
- if (! ret)
- {
- ret = EngBitBlt(psoDest, psoSource, MaskSurf, ClipRegion, ColorTranslation,
- &OutputRect, &InputPoint, MaskOrigin, pbo, BrushOrigin,
- Rop4);
- }
-
- if (RemoveMouse)
- {
- MouseSafetyOnDrawEnd(psoDest);
- if (UsesSource)
- {
- MouseSafetyOnDrawEnd(psoSource);
- if (psoSource != psoDest)
- {
- SURFACE_UnlockBitmapBits(psurfSource);
- }
- }
-
- SURFACE_UnlockBitmapBits(psurfDest);
- }
-
- return ret;
+
+ /* Don't pass a clipobj with only a single rect */
+ if (pco->iDComplexity == DC_RECT)
+ pco = NULL;
+ }
+
+ if (ROP4_USES_SOURCE(rop4))
+ {
+ ASSERT(psoSrc);
+ psurfSrc = CONTAINING_RECORD(psoSrc, SURFACE, SurfObj);
+
+ /* Calculate source rect */
+ rclSrc.left = pptlSrc->x + rclClipped.left - prclTrg->left;
+ rclSrc.top = pptlSrc->y + rclClipped.top - prclTrg->top;
+ rclSrc.right = rclSrc.left + rclClipped.right - rclClipped.left;
+ rclSrc.bottom = rclSrc.top + rclClipped.bottom - rclClipped.top;
+ }
+ else
+ {
+ psoSrc = NULL;
+ psurfSrc = NULL;
+ }
+
+ if (bRemoveMouse)
+ {
+ SURFACE_LockBitmapBits(psurfTrg);
+
+ if (psoSrc)
+ {
+ if (psoSrc != psoTrg)
+ {
+ SURFACE_LockBitmapBits(psurfSrc);
+ }
+ MouseSafetyOnDrawStart(psoSrc, rclSrc.left, rclSrc.top,
+ rclSrc.right, rclSrc.bottom);
+ }
+ MouseSafetyOnDrawStart(psoTrg, rclClipped.left, rclClipped.top,
+ rclClipped.right, rclClipped.bottom);
+ }
+
+ /* Is the target surface device managed? */
+ if (psurfTrg->flHooks & HOOK_BITBLT)
+ {
+ /* Is the source a different device managed surface? */
+ if (psoSrc && psoSrc->hdev != psoTrg->hdev &&
psurfSrc->flHooks & HOOK_BITBLT)
+ {
+ DPRINT1("Need to copy to standard bitmap format!\n");
+ ASSERT(FALSE);
+ }
+
+ pfnBitBlt = GDIDEVFUNCS(psoTrg).BitBlt;
+ }
+
+ /* Is the source surface device managed? */
+ else if (psoSrc && psurfSrc->flHooks & HOOK_BITBLT)
+ {
+ pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt;
+ }
+ else
+ {
+ pfnBitBlt = EngBitBlt;
+ }
+
+ bResult = pfnBitBlt(psoTrg,
+ psoSrc,
+ psoMask,
+ pco,
+ pxlo,
+ &rclClipped,
+ (POINTL*)&rclSrc,
+ pptlMask,
+ pbo,
+ pptlBrush,
+ rop4);
+
+ // FIXME: cleanup temp surface!
+
+ if (bRemoveMouse)
+ {
+ MouseSafetyOnDrawEnd(psoTrg);
+ if (psoSrc)
+ {
+ MouseSafetyOnDrawEnd(psoSrc);
+ if (psoSrc != psoTrg)
+ {
+ SURFACE_UnlockBitmapBits(psurfSrc);
+ }
+ }
+
+ SURFACE_UnlockBitmapBits(psurfTrg);
+ }
+
+ return bResult;
}
@@ -1057,4 +1003,5 @@
return ret;
}
+
/* EOF */