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/eng/bitblt.c?rev=40495&r1=40494&r2=40495&view=diff
==============================================================================
--- 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 */

Reply via email to