[WIN32K]
authorJérôme Gardou <jerome.gardou@reactos.org>
Sat, 17 Apr 2010 14:20:48 +0000 (14:20 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Sat, 17 Apr 2010 14:20:48 +0000 (14:20 +0000)
  - 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
subsystems/win32/win32k/include/dc.h
subsystems/win32/win32k/include/gdiobj.h
subsystems/win32/win32k/objects/bitblt.c
subsystems/win32/win32k/objects/dclife.c
subsystems/win32/win32k/objects/gdiobj.c

index 30ba88f..3322dc2 100644 (file)
@@ -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;
index 82fc625..0840c31 100644 (file)
@@ -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);
 
index 40ca099..29f3ea2 100644 (file)
@@ -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);
 
index a02d652..c5c3bf3 100644 (file)
@@ -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;
             }
index 1426770..b93ba33 100644 (file)
@@ -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(
index a5c3723..66d0505 100644 (file)
@@ -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[i] >= (ULONG_PTR)ahObj[iSecond])
-        {
-            iSecond = 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;
+            }
         }
-        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);
 }