mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
[WIN32K]
- Rewrite NtGdiInvertRgn to not violate locking order - Remove DceUpdateVisRgn from DC_vPrepareDCsForBlit: It is not GDI's task to handle Window clipping, it violates locking order, it's slow, it's ugly to call USER functions from GDI internals, it's a hack. I couldn't see any clipping regression, if you find anything, let me know. svn path=/trunk/; revision=65910
This commit is contained in:
@@ -1024,6 +1024,81 @@ REGION_LPTODP(
|
||||
return REGION_bXformRgn(prgnDest, DC_pmxWorldToDevice(pdc));
|
||||
}
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
IntGdiBitBltRgn(
|
||||
_In_ PDC pdc,
|
||||
_In_ PREGION prgn,
|
||||
_In_opt_ BRUSHOBJ *pbo,
|
||||
_In_opt_ POINTL *pptlBrush,
|
||||
_In_ ROP4 rop4)
|
||||
{
|
||||
PREGION prgnClip;
|
||||
XCLIPOBJ xcoClip;
|
||||
BOOL bResult;
|
||||
PSURFACE psurf;
|
||||
NT_ASSERT((pdc != NULL) && (prgn != NULL));
|
||||
|
||||
/* Get the surface */
|
||||
psurf = pdc->dclevel.pSurface;
|
||||
if (psurf == NULL)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Create an empty clip region */
|
||||
prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||
if (prgnClip == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Transform given region into device coordinates */
|
||||
if (!REGION_LPTODP(pdc, prgnClip, prgn) ||
|
||||
!REGION_bOffsetRgn(prgnClip, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y))
|
||||
{
|
||||
REGION_Delete(prgnClip);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Intersect with the system or RAO region */
|
||||
if (pdc->prgnRao)
|
||||
IntGdiCombineRgn(prgnClip, prgnClip, pdc->prgnRao, RGN_AND);
|
||||
else
|
||||
IntGdiCombineRgn(prgnClip, prgnClip, pdc->prgnVis, RGN_AND);
|
||||
|
||||
/* Initialize a clip object */
|
||||
IntEngInitClipObj(&xcoClip);
|
||||
IntEngUpdateClipRegion(&xcoClip,
|
||||
prgnClip->rdh.nCount,
|
||||
prgnClip->Buffer,
|
||||
&prgnClip->rdh.rcBound);
|
||||
|
||||
/* Prepare the DC */
|
||||
DC_vPrepareDCsForBlit(pdc, &prgnClip->rdh.rcBound, NULL, NULL);
|
||||
|
||||
/* Call the Eng or Drv function */
|
||||
bResult = IntEngBitBlt(&psurf->SurfObj,
|
||||
NULL,
|
||||
NULL,
|
||||
&xcoClip.ClipObj,
|
||||
NULL,
|
||||
&prgnClip->rdh.rcBound,
|
||||
NULL,
|
||||
NULL,
|
||||
pbo,
|
||||
pptlBrush,
|
||||
rop4);
|
||||
|
||||
/* Cleanup */
|
||||
DC_vFinishBlit(pdc, NULL);
|
||||
REGION_Delete(prgnClip);
|
||||
IntEngFreeClipResources(&xcoClip);
|
||||
|
||||
/* Return the result */
|
||||
return bResult;
|
||||
}
|
||||
|
||||
BOOL
|
||||
IntGdiFillRgn(
|
||||
_In_ PDC pdc,
|
||||
@@ -1190,34 +1265,48 @@ NtGdiFrameRgn(
|
||||
BOOL
|
||||
APIENTRY
|
||||
NtGdiInvertRgn(
|
||||
HDC hDC,
|
||||
HRGN hRgn)
|
||||
_In_ HDC hdc,
|
||||
_In_ HRGN hrgn)
|
||||
{
|
||||
PREGION RgnData;
|
||||
ULONG i;
|
||||
PRECTL rc;
|
||||
BOOL bResult;
|
||||
PDC pdc;
|
||||
PREGION prgn;
|
||||
|
||||
RgnData = REGION_LockRgn(hRgn);
|
||||
if (RgnData == NULL)
|
||||
/* Lock the DC */
|
||||
pdc = DC_LockDc(hdc);
|
||||
if (pdc == NULL)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = RgnData->Buffer;
|
||||
for (i = 0; i < RgnData->rdh.nCount; i++)
|
||||
/* Check if the DC has no surface (empty mem or info DC) */
|
||||
if (pdc->dclevel.pSurface == NULL)
|
||||
{
|
||||
|
||||
if (!NtGdiPatBlt(hDC, rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, DSTINVERT))
|
||||
{
|
||||
REGION_UnlockRgn(RgnData);
|
||||
return FALSE;
|
||||
}
|
||||
rc++;
|
||||
/* Nothing to do, Windows returns TRUE! */
|
||||
DC_UnlockDc(pdc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
REGION_UnlockRgn(RgnData);
|
||||
return TRUE;
|
||||
/* Lock the region */
|
||||
prgn = REGION_LockRgn(hrgn);
|
||||
if (prgn == NULL)
|
||||
{
|
||||
DC_UnlockDc(pdc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Call the internal function */
|
||||
bResult = IntGdiBitBltRgn(pdc,
|
||||
prgn,
|
||||
NULL, // pbo
|
||||
NULL, // pptlBrush,
|
||||
ROP_TO_ROP4(DSTINVERT));
|
||||
|
||||
/* Unlock the region and DC and return the result */
|
||||
REGION_UnlockRgn(prgn);
|
||||
DC_UnlockDc(pdc);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
COLORREF
|
||||
|
||||
@@ -506,7 +506,8 @@ DC_vPrepareDCsForBlit(
|
||||
/* Lock them in good order */
|
||||
if(pdcSrc)
|
||||
{
|
||||
if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >= (ULONG_PTR)pdcSrc->ppdev->hsemDevLock)
|
||||
if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >=
|
||||
(ULONG_PTR)pdcSrc->ppdev->hsemDevLock)
|
||||
{
|
||||
pdcFirst = pdcDest;
|
||||
prcFirst = rcDest;
|
||||
@@ -529,19 +530,11 @@ DC_vPrepareDCsForBlit(
|
||||
prcSecond = NULL;
|
||||
}
|
||||
|
||||
/* Update clipping of dest DC if needed */
|
||||
if (pdcDest->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
DCE* dce = DceGetDceFromDC(pdcDest->BaseObject.hHmgr);
|
||||
if (dce)
|
||||
DceUpdateVisRgn(dce, dce->pwndOrg, dce->DCXFlags);
|
||||
}
|
||||
|
||||
if (pdcDest->fs & DC_FLAG_DIRTY_RAO)
|
||||
CLIPPING_UpdateGCRegion(pdcDest);
|
||||
|
||||
/* Lock and update first DC */
|
||||
if(pdcFirst->dctype == DCTYPE_DIRECT)
|
||||
if (pdcFirst->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock);
|
||||
/* Update surface if needed */
|
||||
@@ -551,7 +544,7 @@ DC_vPrepareDCsForBlit(
|
||||
}
|
||||
}
|
||||
|
||||
if(pdcFirst->dctype == DCTYPE_DIRECT)
|
||||
if (pdcFirst->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
if (!prcFirst)
|
||||
prcFirst = &pdcFirst->erclClip;
|
||||
@@ -567,9 +560,10 @@ DC_vPrepareDCsForBlit(
|
||||
return;
|
||||
|
||||
/* Lock and update second DC */
|
||||
if(pdcSecond->dctype == DCTYPE_DIRECT)
|
||||
if (pdcSecond->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock);
|
||||
|
||||
/* Update surface if needed */
|
||||
if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
|
||||
{
|
||||
@@ -577,7 +571,7 @@ DC_vPrepareDCsForBlit(
|
||||
}
|
||||
}
|
||||
|
||||
if(pdcSecond->dctype == DCTYPE_DIRECT)
|
||||
if (pdcSecond->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
if (!prcSecond)
|
||||
prcSecond = &pdcSecond->erclClip;
|
||||
|
||||
Reference in New Issue
Block a user