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 */