mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
[WIN32K]
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:
parent
b193a23ecc
commit
7b0c1877b9
2 changed files with 114 additions and 35 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue