Author: tkreuzer
Date: Wed Dec 31 15:15:44 2014
New Revision: 65919
URL: 
http://svn.reactos.org/svn/reactos?rev=65919&view=rev
Log:
[WIN32K]
Rewrite IntEngMaskBlt to work with device managed surfaces. Should fix CORE-7821 and
CORE-8711
Modified:
    trunk/reactos/win32ss/gdi/eng/bitblt.c
    trunk/reactos/win32ss/gdi/eng/inteng.h
Modified: trunk/reactos/win32ss/gdi/eng/bitblt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/bitblt.c?r…
==============================================================================
--- trunk/reactos/win32ss/gdi/eng/bitblt.c      [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/eng/bitblt.c      [iso-8859-1] Wed Dec 31 15:15:44 2014
@@ -65,6 +65,7 @@
     DWORD fgndRop, bkgndRop;
     ASSERT(IS_VALID_ROP4(Rop4));
+    ASSERT(psoMask->iBitmapFormat == BMF_1BPP);
     if (!psoMask) return FALSE;
@@ -984,64 +985,141 @@
     return Ret;
 }
-BOOL APIENTRY
-IntEngMaskBlt(SURFOBJ *psoDest,
-              SURFOBJ *psoMask,
-              CLIPOBJ *ClipRegion,
-              XLATEOBJ *DestColorTranslation,
-              XLATEOBJ *SourceColorTranslation,
-              RECTL *DestRect,
-              POINTL *pptlMask,
-              BRUSHOBJ *pbo,
-              POINTL *BrushOrigin)
+BOOL
+APIENTRY
+IntEngMaskBlt(
+    _Inout_ SURFOBJ *psoDest,
+    _In_ SURFOBJ *psoMask,
+    _In_ CLIPOBJ *pco,
+    _In_ XLATEOBJ *pxloDest,
+    _In_ XLATEOBJ *pxloSource,
+    _In_ RECTL *prclDest,
+    _In_ POINTL *pptlMask,
+    _In_ BRUSHOBJ *pbo,
+    _In_ POINTL *pptlBrushOrg)
 {
     BOOLEAN ret;
-    RECTL OutputRect;
-    POINTL InputPoint = {0,0};
-    //SURFACE *psurfDest;
-
+    RECTL rcDest;
+    POINTL ptMask = {0,0};
+    PSURFACE psurfTemp;
+    RECTL rcTemp;
+
+    ASSERT(psoDest);
     ASSERT(psoMask);
+    /* Is this a 1 BPP mask? */
+    if (psoMask->iBitmapFormat == BMF_1BPP)
+    {
+        /* Use IntEngBitBlt with an appropriate ROP4 */
+        return IntEngBitBlt(psoDest,
+                            NULL,
+                            psoMask,
+                            pco,
+                            pxloDest,
+                            prclDest,
+                            NULL,
+                            pptlMask,
+                            pbo,
+                            pptlBrushOrg,
+                            ROP4_MASKPAINT);
+    }
+
+    ASSERT(psoMask->iBitmapFormat == BMF_8BPP);
+
     if (pptlMask)
     {
-        InputPoint = *pptlMask;
+        ptMask = *pptlMask;
     }
     /* 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, DestRect,
&ClipRegion->rclBounds))
+    if (pco != NULL)
+    {
+        /* Intersect with the clip bounds and check if everything was clipped */
+        if (!RECTL_bIntersectRect(&rcDest, prclDest, &pco->rclBounds))
         {
             return TRUE;
         }
-        InputPoint.x += OutputRect.left - DestRect->left;
-        InputPoint.y += OutputRect.top - DestRect->top;
-    }
-    else
-    {
-        OutputRect = *DestRect;
-    }
-
-    /* No success yet */
-    ret = FALSE;
-    ASSERT(psoDest);
-    //psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
-
-    /* Dummy BitBlt to let driver know that it should flush its changes.
-       This should really be done using a call to DrvSynchronizeSurface,
-       but the VMware driver doesn't hook that call. */
-    IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
-                   DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
-                   ROP4_NOOP);
-
-    ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation,
SourceColorTranslation,
-                        &OutputRect, &InputPoint, pbo, BrushOrigin);
-
-    /* Dummy BitBlt to let driver know that something has changed. */
-    IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
-                   DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
-                   ROP4_NOOP);
+
+        /* Adjust the mask point */
+        ptMask.x += rcDest.left - prclDest->left;
+        ptMask.y += rcDest.top - prclDest->top;
+    }
+    else
+    {
+        rcDest = *prclDest;
+    }
+
+    /* Check if the target surface is device managed */
+    if (psoDest->iType != STYPE_BITMAP)
+    {
+        rcTemp.left = 0;
+        rcTemp.top = 0;
+        rcTemp.right = rcDest.right - rcDest.left;
+        rcTemp.bottom = rcDest.bottom - rcDest.top;
+
+        /* Allocate a temporary surface */
+        psurfTemp = SURFACE_AllocSurface(STYPE_BITMAP,
+                                         rcTemp.right,
+                                         rcTemp.bottom,
+                                         psoDest->iBitmapFormat,
+                                         0,
+                                         0,
+                                         NULL);
+        if (psurfTemp == NULL)
+        {
+            return FALSE;
+        }
+
+        /* Copy the current target surface bits to the temp surface */
+        ret = EngCopyBits(&psurfTemp->SurfObj,
+                          psoDest,
+                          NULL, // pco
+                          NULL, // pxlo
+                          &rcTemp,
+                          (PPOINTL)&rcDest);
+
+        if (ret)
+        {
+            /* Do the operation on the temp surface */
+            ret = EngMaskBitBlt(&psurfTemp->SurfObj,
+                                psoMask,
+                                NULL,
+                                pxloDest,
+                                pxloSource,
+                                &rcTemp,
+                                &ptMask,
+                                pbo,
+                                pptlBrushOrg);
+        }
+
+        if (ret)
+        {
+            /* Copy the result back to the dest surface */
+            ret = EngCopyBits(psoDest,
+                              &psurfTemp->SurfObj,
+                              pco,
+                              NULL,
+                              &rcDest,
+                              (PPOINTL)&rcTemp);
+        }
+
+        /* Delete the temp surface */
+        GDIOBJ_vDeleteObject(&psurfTemp->BaseObject);
+    }
+    else
+    {
+        /* Do the operation on the target surface */
+        ret = EngMaskBitBlt(psoDest,
+                            psoMask,
+                            pco,
+                            pxloDest,
+                            pxloSource,
+                            &rcDest,
+                            &ptMask,
+                            pbo,
+                            pptlBrushOrg);
+    }
     return ret;
 }
Modified: trunk/reactos/win32ss/gdi/eng/inteng.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/inteng.h?r…
==============================================================================
--- trunk/reactos/win32ss/gdi/eng/inteng.h      [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/eng/inteng.h      [iso-8859-1] Wed Dec 31 15:15:44 2014
@@ -53,6 +53,7 @@
 #define ROP4_NOOP (R3_OPINDEX_NOOP | (R3_OPINDEX_NOOP << 8))
 #define ROP4_MASK (R3_OPINDEX_SRCCOPY | (R3_OPINDEX_NOOP << 8))
+#define ROP4_MASKPAINT (R3_OPINDEX_PATCOPY | (R3_OPINDEX_NOOP << 8))
 /* Definitions of IntEngXxx functions */