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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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);
}