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;
ASSERT(IS_VALID_ROP4(Rop4));
ASSERT(psoMask->iBitmapFormat == BMF_1BPP);
if (!psoMask) return FALSE;
@ -984,64 +985,141 @@ EngMaskBitBlt(SURFOBJ *psoDest,
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 (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;
}
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
{
OutputRect = *DestRect;
rcDest = *prclDest;
}
/* No success yet */
ret = FALSE;
ASSERT(psoDest);
//psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
/* 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;
/* 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);
/* Allocate a temporary surface */
psurfTemp = SURFACE_AllocSurface(STYPE_BITMAP,
rcTemp.right,
rcTemp.bottom,
psoDest->iBitmapFormat,
0,
0,
NULL);
if (psurfTemp == NULL)
{
return FALSE;
}
ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation,
&OutputRect, &InputPoint, pbo, BrushOrigin);
/* Copy the current target surface bits to the temp surface */
ret = EngCopyBits(&psurfTemp->SurfObj,
psoDest,
NULL, // pco
NULL, // pxlo
&rcTemp,
(PPOINTL)&rcDest);
/* Dummy BitBlt to let driver know that something has changed. */
IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
ROP4_NOOP);
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;
}

View file

@ -53,6 +53,7 @@ enum _R3_ROPCODES
#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 */