mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
[WIN32K]
- Introduce DC_vPrepareDCsForBlit and DC_vFinishBlit and use them in NtGdiAlphaBlend - Get rid of now unnecessary call for MouseSafetyOnDraw{Start,End} in IntEngAlphaBlend - Yet Another Rewrite of GDIOBJ_LockMultipleObjs :-/ and use it in NtGdiAlphaBlend svn path=/branches/reactos-yarotows/; revision=46902
This commit is contained in:
parent
4ec4675b9e
commit
0cdfd4399d
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: GDI alpha blending functions
|
||||
|
@ -71,7 +71,7 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
|
|||
InputRect = *SourceRect;
|
||||
if ( (InputRect.top < 0) || (InputRect.bottom < 0) ||
|
||||
(InputRect.left < 0) || (InputRect.right < 0) ||
|
||||
InputRect.right > psoSource->sizlBitmap.cx ||
|
||||
InputRect.right > psoSource->sizlBitmap.cx ||
|
||||
InputRect.bottom > psoSource->sizlBitmap.cy )
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
|
@ -306,13 +306,9 @@ IntEngAlphaBlend(IN SURFOBJ *psoDest,
|
|||
}
|
||||
|
||||
SURFACE_LockBitmapBits(psurfDest);
|
||||
MouseSafetyOnDrawStart(psoDest, DestRect->left, DestRect->top,
|
||||
DestRect->right, DestRect->bottom);
|
||||
|
||||
if (psoSource != psoDest)
|
||||
SURFACE_LockBitmapBits(psurfSource);
|
||||
MouseSafetyOnDrawStart(psoSource, SourceRect->left, SourceRect->top,
|
||||
SourceRect->right, SourceRect->bottom);
|
||||
|
||||
/* Call the driver's DrvAlphaBlend if available */
|
||||
if (psurfDest->flHooks & HOOK_ALPHABLEND)
|
||||
|
@ -328,10 +324,8 @@ IntEngAlphaBlend(IN SURFOBJ *psoDest,
|
|||
DestRect, SourceRect, BlendObj);
|
||||
}
|
||||
|
||||
MouseSafetyOnDrawEnd(psoSource);
|
||||
if (psoSource != psoDest)
|
||||
SURFACE_UnlockBitmapBits(psurfSource);
|
||||
MouseSafetyOnDrawEnd(psoDest);
|
||||
SURFACE_UnlockBitmapBits(psurfDest);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -220,6 +220,8 @@ VOID FASTCALL DC_vUpdateFillBrush(PDC pdc);
|
|||
VOID FASTCALL DC_vUpdateLineBrush(PDC pdc);
|
||||
VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
|
||||
VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc);
|
||||
VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2);
|
||||
VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdc1, RECT rc1, PDC pdc2, RECT rc2);
|
||||
|
||||
VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ extern PGDI_HANDLE_TABLE GdiHandleTable;
|
|||
typedef PVOID PGDIOBJ;
|
||||
|
||||
typedef BOOL (INTERNAL_CALL *GDICLEANUPPROC)(PVOID ObjectBody);
|
||||
typedef VOID (INTERNAL_CALL *GDILOCKOBJPROC)(PVOID ObjectBody);
|
||||
|
||||
/* Every GDI Object must have this standard type of header.
|
||||
* It's for thread locking. */
|
||||
|
@ -72,7 +71,7 @@ VOID INTERNAL_CALL GDIOBJ_FreeObj (POBJ pObj, UCHAR ObjectType);
|
|||
BOOL INTERNAL_CALL GDIOBJ_FreeObjByHandle (HGDIOBJ hObj, DWORD ObjectType);
|
||||
PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType);
|
||||
PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ObjectType);
|
||||
VOID INTERNAL_CALL GDIOBJ_LockMultipleObjs(ULONG ulCount, IN HGDIOBJ* ahObj, OUT PGDIOBJ* apObj);
|
||||
VOID INTERNAL_CALL GDIOBJ_LockMultipleObjs(ULONG ulCount, IN HGDIOBJ* ahObj, OUT PGDIOBJ* apObj);
|
||||
|
||||
PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process);
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ NtGdiAlphaBlend(
|
|||
{
|
||||
PDC DCDest;
|
||||
PDC DCSrc;
|
||||
HDC ahDC[2];
|
||||
PGDIOBJ apObj[2];
|
||||
SURFACE *BitmapDest, *BitmapSrc;
|
||||
RECTL DestRect, SourceRect;
|
||||
BOOL bResult;
|
||||
|
@ -55,43 +57,29 @@ NtGdiAlphaBlend(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
DCDest = DC_LockDc(hDCDest);
|
||||
if (NULL == DCDest)
|
||||
DPRINT("Locking DCs\n");
|
||||
ahDC[0] = hDCDest;
|
||||
ahDC[1] = hDCSrc ;
|
||||
GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
|
||||
DCDest = apObj[0];
|
||||
DCSrc = apObj[1];
|
||||
|
||||
if ((NULL == DCDest) || (NULL == DCSrc))
|
||||
{
|
||||
DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCDest);
|
||||
DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
|
||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||
if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
|
||||
if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (DCDest->dctype == DC_TYPE_INFO)
|
||||
if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
|
||||
{
|
||||
DC_UnlockDc(DCDest);
|
||||
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
|
||||
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
|
||||
/* Yes, Windows really returns TRUE in this case */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (hDCSrc != hDCDest)
|
||||
{
|
||||
DCSrc = DC_LockDc(hDCSrc);
|
||||
if (NULL == DCSrc)
|
||||
{
|
||||
DC_UnlockDc(DCDest);
|
||||
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCSrc);
|
||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (DCSrc->dctype == DC_TYPE_INFO)
|
||||
{
|
||||
DC_UnlockDc(DCSrc);
|
||||
DC_UnlockDc(DCDest);
|
||||
/* Yes, Windows really returns TRUE in this case */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DCSrc = DCDest;
|
||||
bResult = TRUE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
DestRect.left = XOriginDest;
|
||||
|
@ -121,35 +109,35 @@ NtGdiAlphaBlend(
|
|||
!SourceRect.right ||
|
||||
!SourceRect.bottom)
|
||||
{
|
||||
if (hDCSrc != hDCDest)
|
||||
DC_UnlockDc(DCSrc);
|
||||
DC_UnlockDc(DCDest);
|
||||
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
|
||||
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Prepare DCs for blit */
|
||||
DPRINT("Preparing DCs for blit\n");
|
||||
DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
|
||||
|
||||
/* Determine surfaces to be used in the bitblt */
|
||||
BitmapDest = DCDest->dclevel.pSurface;
|
||||
if (!BitmapDest)
|
||||
{
|
||||
if (hDCSrc != hDCDest)
|
||||
DC_UnlockDc(DCSrc);
|
||||
DC_UnlockDc(DCDest);
|
||||
return FALSE;
|
||||
bResult = FALSE ;
|
||||
goto leave ;
|
||||
}
|
||||
|
||||
BitmapSrc = DCSrc->dclevel.pSurface;
|
||||
if (!BitmapSrc)
|
||||
{
|
||||
if (hDCSrc != hDCDest)
|
||||
DC_UnlockDc(DCSrc);
|
||||
DC_UnlockDc(DCDest);
|
||||
return FALSE;
|
||||
bResult = FALSE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Create the XLATEOBJ. */
|
||||
EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
|
||||
|
||||
/* Perform the alpha blend operation */
|
||||
DPRINT("Performing the alpha Blend\n");
|
||||
bResult = IntEngAlphaBlend(&BitmapDest->SurfObj,
|
||||
&BitmapSrc->SurfObj,
|
||||
DCDest->rosdc.CombinedClip,
|
||||
|
@ -159,9 +147,11 @@ NtGdiAlphaBlend(
|
|||
&BlendObj);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
DC_UnlockDc(DCDest);
|
||||
if (hDCSrc != hDCDest)
|
||||
DC_UnlockDc(DCSrc);
|
||||
leave :
|
||||
DPRINT("Finishing blit\n");
|
||||
DC_vFinishBlit(DCDest, DCSrc);
|
||||
GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
|
||||
GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
@ -833,8 +823,8 @@ GreStretchBltMask(
|
|||
(BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
|
||||
BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc))
|
||||
{
|
||||
DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
|
||||
BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
|
||||
DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
|
||||
BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
|
||||
WidthSrc, HeightSrc);
|
||||
goto failed;
|
||||
}
|
||||
|
|
|
@ -451,6 +451,49 @@ leave:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Prepare a blit for up to 2 DCs */
|
||||
/* rc1 and rc2 are the rectangles where we want to draw or
|
||||
* from where we take pixels. */
|
||||
VOID
|
||||
FASTCALL
|
||||
DC_vPrepareDCsForBlit(PDC pdc1,
|
||||
RECT rc1,
|
||||
PDC pdc2,
|
||||
RECT rc2)
|
||||
{
|
||||
if(pdc1->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
EngAcquireSemaphore(pdc1->ppdev->hsemDevLock);
|
||||
MouseSafetyOnDrawStart(&pdc1->dclevel.pSurface->SurfObj, rc1.left, rc1.top, rc1.right, rc1.bottom) ;
|
||||
}
|
||||
if(pdc2 && pdc2->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
EngAcquireSemaphore(pdc2->ppdev->hsemDevLock);
|
||||
MouseSafetyOnDrawStart(&pdc2->dclevel.pSurface->SurfObj, rc2.left, rc2.top, rc2.right, rc2.bottom) ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finishes a blit for one or two DCs */
|
||||
VOID
|
||||
FASTCALL
|
||||
DC_vFinishBlit(PDC pdc1, PDC pdc2)
|
||||
{
|
||||
if(pdc1->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
MouseSafetyOnDrawEnd(&pdc1->dclevel.pSurface->SurfObj);
|
||||
EngReleaseSemaphore(pdc1->ppdev->hsemDevLock);
|
||||
}
|
||||
|
||||
if(pdc2)
|
||||
{
|
||||
if(pdc2->dctype == DCTYPE_DIRECT)
|
||||
{
|
||||
MouseSafetyOnDrawEnd(&pdc2->dclevel.pSurface->SurfObj);
|
||||
EngReleaseSemaphore(pdc2->ppdev->hsemDevLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HDC
|
||||
NTAPI
|
||||
GreOpenDCW(
|
||||
|
|
|
@ -1625,39 +1625,35 @@ GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process)
|
|||
return MappedView;
|
||||
}
|
||||
|
||||
/* Locks up to 3 objects at a time */
|
||||
/* Locks 2 or 3 objects at a time */
|
||||
VOID
|
||||
INTERNAL_CALL
|
||||
GDIOBJ_LockMultipleObjs(ULONG ulCount,
|
||||
IN HGDIOBJ* ahObj,
|
||||
OUT PGDIOBJ* apObj)
|
||||
{
|
||||
UINT iFirst = 0, iSecond = 0, iThird = 0;
|
||||
UINT i ;
|
||||
UINT auiIndices[3] = {0,1,2};
|
||||
UINT i, tmp ;
|
||||
BOOL bUnsorted = TRUE;
|
||||
|
||||
/* First is greatest */
|
||||
for(i=1; i<ulCount; i++)
|
||||
while(bUnsorted)
|
||||
{
|
||||
if((ULONG_PTR)ahObj[i] >= (ULONG_PTR)ahObj[iFirst])
|
||||
bUnsorted = FALSE;
|
||||
for(i=1; i<ulCount; i++)
|
||||
{
|
||||
iSecond = iFirst ;
|
||||
iFirst = i;
|
||||
continue ;
|
||||
if((ULONG_PTR)ahObj[auiIndices[i-1]] < (ULONG_PTR)ahObj[auiIndices[i]])
|
||||
{
|
||||
tmp = auiIndices[i-1];
|
||||
auiIndices[i-1] = auiIndices[i];
|
||||
auiIndices[i] = tmp;
|
||||
bUnsorted = TRUE;
|
||||
}
|
||||
}
|
||||
if((ULONG_PTR)ahObj[i] >= (ULONG_PTR)ahObj[iSecond])
|
||||
{
|
||||
iSecond = i;
|
||||
continue;
|
||||
}
|
||||
iThird = i;
|
||||
}
|
||||
|
||||
/* We consider that at least two handles were passed */
|
||||
apObj[iFirst] = GDIOBJ_LockObj(ahObj[iFirst], GDI_OBJECT_TYPE_DONTCARE);
|
||||
apObj[iSecond] = GDIOBJ_LockObj(ahObj[iSecond], GDI_OBJECT_TYPE_DONTCARE);
|
||||
if(ulCount == 3)
|
||||
apObj[iThird] = GDIOBJ_LockObj(ahObj[iThird], GDI_OBJECT_TYPE_DONTCARE);
|
||||
|
||||
for(i=0;i<ulCount;i++)
|
||||
apObj[auiIndices[i]] = GDIOBJ_LockObj(ahObj[auiIndices[i]], GDI_OBJECT_TYPE_DONTCARE);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue