Rewrite IntEngMaskBlt to work with device managed surfaces. Should fix CORE-7821 and CORE-8711

svn path=/trunk/; revision=65919
This commit is contained in:
Timo Kreuzer 2014-12-31 15:15:44 +00:00
parent b193a23ecc
commit 7b0c1877b9
2 changed files with 114 additions and 35 deletions

View file

@ -65,6 +65,7 @@ BltMask(SURFOBJ* psoDest,
DWORD fgndRop, bkgndRop; DWORD fgndRop, bkgndRop;
ASSERT(IS_VALID_ROP4(Rop4)); ASSERT(IS_VALID_ROP4(Rop4));
ASSERT(psoMask->iBitmapFormat == BMF_1BPP);
if (!psoMask) return FALSE; if (!psoMask) return FALSE;
@ -984,64 +985,141 @@ EngMaskBitBlt(SURFOBJ *psoDest,
return Ret; return Ret;
} }
BOOL APIENTRY BOOL
IntEngMaskBlt(SURFOBJ *psoDest, APIENTRY
SURFOBJ *psoMask, IntEngMaskBlt(
CLIPOBJ *ClipRegion, _Inout_ SURFOBJ *psoDest,
XLATEOBJ *DestColorTranslation, _In_ SURFOBJ *psoMask,
XLATEOBJ *SourceColorTranslation, _In_ CLIPOBJ *pco,
RECTL *DestRect, _In_ XLATEOBJ *pxloDest,
POINTL *pptlMask, _In_ XLATEOBJ *pxloSource,
BRUSHOBJ *pbo, _In_ RECTL *prclDest,
POINTL *BrushOrigin) _In_ POINTL *pptlMask,
_In_ BRUSHOBJ *pbo,
_In_ POINTL *pptlBrushOrg)
{ {
BOOLEAN ret; BOOLEAN ret;
RECTL OutputRect; RECTL rcDest;
POINTL InputPoint = {0,0}; POINTL ptMask = {0,0};
//SURFACE *psurfDest; PSURFACE psurfTemp;
RECTL rcTemp;
ASSERT(psoDest);
ASSERT(psoMask); 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) if (pptlMask)
{ {
InputPoint = *pptlMask; ptMask = *pptlMask;
} }
/* Clip against the bounds of the clipping region so we won't try to write /* Clip against the bounds of the clipping region so we won't try to write
* outside the surface */ * outside the surface */
if (NULL != ClipRegion) if (pco != NULL)
{ {
if (!RECTL_bIntersectRect(&OutputRect, DestRect, &ClipRegion->rclBounds)) /* Intersect with the clip bounds and check if everything was clipped */
if (!RECTL_bIntersectRect(&rcDest, prclDest, &pco->rclBounds))
{ {
return TRUE; return TRUE;
} }
InputPoint.x += OutputRect.left - DestRect->left;
InputPoint.y += OutputRect.top - DestRect->top; /* Adjust the mask point */
ptMask.x += rcDest.left - prclDest->left;
ptMask.y += rcDest.top - prclDest->top;
} }
else else
{ {
OutputRect = *DestRect; rcDest = *prclDest;
} }
/* No success yet */ /* Check if the target surface is device managed */
ret = FALSE; if (psoDest->iType != STYPE_BITMAP)
ASSERT(psoDest); {
//psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); rcTemp.left = 0;
rcTemp.top = 0;
rcTemp.right = rcDest.right - rcDest.left;
rcTemp.bottom = rcDest.bottom - rcDest.top;
/* Dummy BitBlt to let driver know that it should flush its changes. /* Allocate a temporary surface */
This should really be done using a call to DrvSynchronizeSurface, psurfTemp = SURFACE_AllocSurface(STYPE_BITMAP,
but the VMware driver doesn't hook that call. */ rcTemp.right,
IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation, rcTemp.bottom,
DestRect, pptlMask, pptlMask, pbo, BrushOrigin, psoDest->iBitmapFormat,
ROP4_NOOP); 0,
0,
NULL);
if (psurfTemp == NULL)
{
return FALSE;
}
ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation, /* Copy the current target surface bits to the temp surface */
&OutputRect, &InputPoint, pbo, BrushOrigin); ret = EngCopyBits(&psurfTemp->SurfObj,
psoDest,
NULL, // pco
NULL, // pxlo
&rcTemp,
(PPOINTL)&rcDest);
/* Dummy BitBlt to let driver know that something has changed. */ if (ret)
IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation, {
DestRect, pptlMask, pptlMask, pbo, BrushOrigin, /* Do the operation on the temp surface */
ROP4_NOOP); 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; return ret;
} }

View file

@ -53,6 +53,7 @@ enum _R3_ROPCODES
#define ROP4_NOOP (R3_OPINDEX_NOOP | (R3_OPINDEX_NOOP << 8)) #define ROP4_NOOP (R3_OPINDEX_NOOP | (R3_OPINDEX_NOOP << 8))
#define ROP4_MASK (R3_OPINDEX_SRCCOPY | (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 */ /* Definitions of IntEngXxx functions */