Author: jgardou Date: Sat Apr 17 16:20:48 2010 New Revision: 46902
URL: http://svn.reactos.org/svn/reactos?rev=46902&view=rev Log: [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
Modified: branches/reactos-yarotows/subsystems/win32/win32k/eng/alphablend.c branches/reactos-yarotows/subsystems/win32/win32k/include/dc.h branches/reactos-yarotows/subsystems/win32/win32k/include/gdiobj.h branches/reactos-yarotows/subsystems/win32/win32k/objects/bitblt.c branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c branches/reactos-yarotows/subsystems/win32/win32k/objects/gdiobj.c
Modified: branches/reactos-yarotows/subsystems/win32/win32k/eng/alphablend.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/eng/alphablend.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/eng/alphablend.c [iso-8859-1] Sat Apr 17 16:20:48 2010 @@ -1,4 +1,4 @@ -/* +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: GDI alpha blending functions @@ -71,7 +71,7 @@ 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 @@ }
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 @@ DestRect, SourceRect, BlendObj); }
- MouseSafetyOnDrawEnd(psoSource); if (psoSource != psoDest) SURFACE_UnlockBitmapBits(psurfSource); - MouseSafetyOnDrawEnd(psoDest); SURFACE_UnlockBitmapBits(psurfDest);
return ret;
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/dc.h URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/include/dc.h [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/include/dc.h [iso-8859-1] Sat Apr 17 16:20:48 2010 @@ -220,6 +220,8 @@ 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);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/gdiobj.h URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/include/gdiobj.h [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/include/gdiobj.h [iso-8859-1] Sat Apr 17 16:20:48 2010 @@ -34,7 +34,6 @@ 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 @@ 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);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/bitblt.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/bitblt.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/bitblt.c [iso-8859-1] Sat Apr 17 16:20:48 2010 @@ -42,6 +42,8 @@ { PDC DCDest; PDC DCSrc; + HDC ahDC[2]; + PGDIOBJ apObj[2]; SURFACE *BitmapDest, *BitmapSrc; RECTL DestRect, SourceRect; BOOL bResult; @@ -55,43 +57,29 @@ return FALSE; }
- DCDest = DC_LockDc(hDCDest); - if (NULL == DCDest) - { - DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCDest); + 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 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) - { - DC_UnlockDc(DCDest); + if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO) + { + 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 @@ !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 @@ &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 @@ (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; }
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c [iso-8859-1] Sat Apr 17 16:20:48 2010 @@ -451,6 +451,49 @@ 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(
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/gdiobj.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] Sat Apr 17 16:20:48 2010 @@ -1625,39 +1625,35 @@ 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++) - { - if((ULONG_PTR)ahObj[i] >= (ULONG_PTR)ahObj[iFirst]) - { - iSecond = iFirst ; - iFirst = i; - continue ; - } - 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); - + while(bUnsorted) + { + bUnsorted = FALSE; + for(i=1; i<ulCount; i++) + { + 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; + } + } + } + + for(i=0;i<ulCount;i++) + apObj[auiIndices[i]] = GDIOBJ_LockObj(ahObj[auiIndices[i]], GDI_OBJECT_TYPE_DONTCARE); }