From 0cdfd4399d9fc75ffc6557a4ea707654e7543ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Sat, 17 Apr 2010 14:20:48 +0000 Subject: [PATCH] [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 --- subsystems/win32/win32k/eng/alphablend.c | 10 +-- subsystems/win32/win32k/include/dc.h | 2 + subsystems/win32/win32k/include/gdiobj.h | 3 +- subsystems/win32/win32k/objects/bitblt.c | 82 +++++++++++------------- subsystems/win32/win32k/objects/dclife.c | 43 +++++++++++++ subsystems/win32/win32k/objects/gdiobj.c | 36 +++++------ 6 files changed, 100 insertions(+), 76 deletions(-) diff --git a/subsystems/win32/win32k/eng/alphablend.c b/subsystems/win32/win32k/eng/alphablend.c index 30ba88fd386..3322dc2c0f9 100644 --- a/subsystems/win32/win32k/eng/alphablend.c +++ b/subsystems/win32/win32k/eng/alphablend.c @@ -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; diff --git a/subsystems/win32/win32k/include/dc.h b/subsystems/win32/win32k/include/dc.h index 82fc6256bb0..0840c311eb3 100644 --- a/subsystems/win32/win32k/include/dc.h +++ b/subsystems/win32/win32k/include/dc.h @@ -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); diff --git a/subsystems/win32/win32k/include/gdiobj.h b/subsystems/win32/win32k/include/gdiobj.h index 40ca099dc5b..29f3ea230dd 100644 --- a/subsystems/win32/win32k/include/gdiobj.h +++ b/subsystems/win32/win32k/include/gdiobj.h @@ -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); diff --git a/subsystems/win32/win32k/objects/bitblt.c b/subsystems/win32/win32k/objects/bitblt.c index a02d652ce1e..c5c3bf3f123 100644 --- a/subsystems/win32/win32k/objects/bitblt.c +++ b/subsystems/win32/win32k/objects/bitblt.c @@ -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; } diff --git a/subsystems/win32/win32k/objects/dclife.c b/subsystems/win32/win32k/objects/dclife.c index 1426770ab31..b93ba336d36 100644 --- a/subsystems/win32/win32k/objects/dclife.c +++ b/subsystems/win32/win32k/objects/dclife.c @@ -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( diff --git a/subsystems/win32/win32k/objects/gdiobj.c b/subsystems/win32/win32k/objects/gdiobj.c index a5c372364ac..66d05057a50 100644 --- a/subsystems/win32/win32k/objects/gdiobj.c +++ b/subsystems/win32/win32k/objects/gdiobj.c @@ -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= (ULONG_PTR)ahObj[iFirst]) + bUnsorted = FALSE; + for(i=1; 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