Author: khornicek
Date: Sat Nov 21 15:09:27 2009
New Revision: 44252
URL:
http://svn.reactos.org/svn/reactos?rev=44252&view=rev
Log:
- bring alpha blend from trunk
Modified:
branches/arwinss/reactos/subsystems/win32/win32k/eng/engblt.c
branches/arwinss/reactos/subsystems/win32/win32k/gdi/bitmap.c
branches/arwinss/reactos/subsystems/win32/win32k/gre/bitblt.c
branches/arwinss/reactos/subsystems/win32/win32k/include/gre.h
Modified: branches/arwinss/reactos/subsystems/win32/win32k/eng/engblt.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win3…
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/eng/engblt.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/eng/engblt.c [iso-8859-1] Sat Nov 21
15:09:27 2009
@@ -4,6 +4,7 @@
* FILE: subsystems/win32/win32k/eng/engblt.c
* PURPOSE: Bit-Block Transfer Support Routines
* PROGRAMMERS: Stefan Ginsberg (stefan__100__(a)hotmail.com)
+ Jason Filby
*/
/* INCLUDES ******************************************************************/
@@ -429,16 +430,247 @@
BOOL
APIENTRY
-EngAlphaBlend(IN SURFOBJ* DestSurf,
- IN SURFOBJ* SourceSurf,
+EngAlphaBlend(IN SURFOBJ* psoDest,
+ IN SURFOBJ* psoSource,
IN CLIPOBJ* ClipRegion,
IN XLATEOBJ* ColorTranslation,
IN PRECTL DestRect,
IN PRECTL SourceRect,
IN BLENDOBJ* BlendObj)
{
- UNIMPLEMENTED;
- return FALSE;
+ RECTL SourceStretchedRect;
+ SIZEL SourceStretchedSize;
+ HBITMAP SourceStretchedBitmap = 0;
+ SURFOBJ* SourceStretchedObj = NULL;
+ RECTL InputRect;
+ RECTL OutputRect;
+ RECTL ClipRect;
+ RECTL CombinedRect;
+ RECTL Rect;
+ POINTL Translate;
+ INTENG_ENTER_LEAVE EnterLeaveSource;
+ INTENG_ENTER_LEAVE EnterLeaveDest;
+ SURFOBJ* InputObj;
+ SURFOBJ* OutputObj;
+ LONG Width;
+ LONG ClippingType;
+ RECT_ENUM RectEnum;
+ BOOL EnumMore;
+ INT i;
+ BOOLEAN Ret;
+
+ DPRINT("EngAlphaBlend(psoDest:0x%p, psoSource:0x%p, ClipRegion:0x%p,
ColorTranslation:0x%p,\n", psoDest, psoSource, ClipRegion, ColorTranslation);
+ DPRINT(" DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x,
0x%x, 0x%x},\n",
+ DestRect->left, DestRect->top, DestRect->right, DestRect->bottom,
+ SourceRect->left, SourceRect->top, SourceRect->right,
SourceRect->bottom);
+ DPRINT(" BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n",
BlendObj->BlendFunction.BlendOp,
+ BlendObj->BlendFunction.BlendFlags,
BlendObj->BlendFunction.SourceConstantAlpha,
+ BlendObj->BlendFunction.AlphaFormat);
+
+
+ /* Validate output */
+ OutputRect = *DestRect;
+ if (OutputRect.right < OutputRect.left)
+ {
+ OutputRect.left = DestRect->right;
+ OutputRect.right = DestRect->left;
+ }
+ if (OutputRect.bottom < OutputRect.top)
+ {
+ OutputRect.left = DestRect->right;
+ OutputRect.right = DestRect->left;
+ }
+
+
+ /* Validate input */
+
+ /* FIXME when WindowOrg.x or .y are negitve this check are not vaild,
+ * we need convert the inputRect to the windows org and do it right */
+ InputRect = *SourceRect;
+ if ( (InputRect.top < 0) || (InputRect.bottom < 0) ||
+ (InputRect.left < 0) || (InputRect.right < 0) )
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (psoDest == psoSource &&
+ !(OutputRect.left >= SourceRect->right || InputRect.left >=
OutputRect.right ||
+ OutputRect.top >= SourceRect->bottom || InputRect.top >=
OutputRect.bottom))
+ {
+ DPRINT1("Source and destination rectangles overlap!\n");
+ return FALSE;
+ }
+
+ if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER)
+ {
+ DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n",
BlendObj->BlendFunction.BlendOp);
+ return FALSE;
+ }
+ if (BlendObj->BlendFunction.BlendFlags != 0)
+ {
+ DPRINT1("BlendFlags != 0 (0x%x)\n",
BlendObj->BlendFunction.BlendFlags);
+ return FALSE;
+ }
+ if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0)
+ {
+ DPRINT1("Unsupported AlphaFormat (0x%x)\n",
BlendObj->BlendFunction.AlphaFormat);
+ return FALSE;
+ }
+
+ /* Check if there is anything to draw */
+ if (ClipRegion != NULL &&
+ (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
+ ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
+ {
+ /* Nothing to do */
+ return TRUE;
+ }
+
+ /* Stretch source if needed */
+ if (OutputRect.right - OutputRect.left != InputRect.right - InputRect.left ||
+ OutputRect.bottom - OutputRect.top != InputRect.bottom - InputRect.top)
+ {
+ SourceStretchedSize.cx = OutputRect.right - OutputRect.left;
+ SourceStretchedSize.cy = OutputRect.bottom - OutputRect.top;
+ Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx,
BitsPerFormat(psoSource->iBitmapFormat));
+ /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and
IntEngStretchBlt
+ if possible to get a HW accelerated stretch. */
+ SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width,
psoSource->iBitmapFormat,
+ BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
+
+ if (SourceStretchedBitmap == 0)
+ {
+ DPRINT1("EngCreateBitmap failed!\n");
+ return FALSE;
+ }
+ SourceStretchedObj = EngLockSurface(SourceStretchedBitmap);
+ if (SourceStretchedObj == NULL)
+ {
+ DPRINT1("EngLockSurface failed!\n");
+ EngDeleteSurface(SourceStretchedBitmap);
+ return FALSE;
+ }
+
+ SourceStretchedRect.left = 0;
+ SourceStretchedRect.right = SourceStretchedSize.cx;
+ SourceStretchedRect.top = 0;
+ SourceStretchedRect.bottom = SourceStretchedSize.cy;
+ /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
+ try to acquire an already acquired mutex (lock the already locked
source surface) */
+ /*if (!IntEngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL,
+ NULL, &SourceStretchedRect, SourceRect, NULL,
+ NULL, NULL, COLORONCOLOR))*/
+ if (!EngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL, NULL,
+ NULL, NULL, &SourceStretchedRect, &InputRect,
+ NULL, COLORONCOLOR))
+ {
+ DPRINT1("EngStretchBlt failed!\n");
+ EngFreeMem(SourceStretchedObj->pvBits);
+ EngUnlockSurface(SourceStretchedObj);
+ EngDeleteSurface((HSURF)SourceStretchedBitmap);
+ return FALSE;
+ }
+ InputRect.top = SourceStretchedRect.top;
+ InputRect.bottom = SourceStretchedRect.bottom;
+ InputRect.left = SourceStretchedRect.left;
+ InputRect.right = SourceStretchedRect.right;
+ psoSource = SourceStretchedObj;
+ }
+
+ /* Now call the DIB function */
+ if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE,
&Translate, &InputObj))
+ {
+ EngUnlockSurface(SourceStretchedObj);
+ EngDeleteSurface(SourceStretchedBitmap);
+ return FALSE;
+ }
+
+ InputRect.left += Translate.x;
+ InputRect.right += Translate.x;
+ InputRect.top += Translate.y;
+ InputRect.bottom += Translate.y;
+
+ if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE,
&Translate, &OutputObj))
+ {
+ IntEngLeave(&EnterLeaveSource);
+ EngUnlockSurface(SourceStretchedObj);
+ EngDeleteSurface(SourceStretchedBitmap);
+ return FALSE;
+ }
+ OutputRect.left += Translate.x;
+ OutputRect.right += Translate.x;
+ OutputRect.top += Translate.y;
+ OutputRect.bottom += Translate.y;
+
+ Ret = FALSE;
+ ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity;
+ switch (ClippingType)
+ {
+ case DC_TRIVIAL:
+ Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+ OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion,
ColorTranslation, BlendObj);
+ break;
+
+ case DC_RECT:
+ ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
+ ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
+ ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
+ ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+ {
+ Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
+ Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
+ Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
+ Rect.bottom = InputRect.bottom + CombinedRect.bottom -
OutputRect.bottom;
+ Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+ OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion,
ColorTranslation, BlendObj);
+ }
+ break;
+
+ case DC_COMPLEX:
+ Ret = TRUE;
+ CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
+ do
+ {
+ EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
+ (PVOID) &RectEnum);
+
+ for (i = 0; i < RectEnum.c; i++)
+ {
+ ClipRect.left = RectEnum.arcl[i].left + Translate.x;
+ ClipRect.right = RectEnum.arcl[i].right + Translate.x;
+ ClipRect.top = RectEnum.arcl[i].top + Translate.y;
+ ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
+ if (RECTL_bIntersectRect(&CombinedRect, &OutputRect,
&ClipRect))
+ {
+ Rect.left = InputRect.left + CombinedRect.left -
OutputRect.left;
+ Rect.right = InputRect.right + CombinedRect.right -
OutputRect.right;
+ Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
+ Rect.bottom = InputRect.bottom + CombinedRect.bottom -
OutputRect.bottom;
+ Ret =
DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+ OutputObj, InputObj, &CombinedRect, &Rect,
ClipRegion, ColorTranslation, BlendObj) && Ret;
+ }
+ }
+ }
+ while (EnumMore);
+ break;
+
+ default:
+ UNIMPLEMENTED;
+ ASSERT(FALSE);
+ break;
+ }
+
+ IntEngLeave(&EnterLeaveDest);
+ IntEngLeave(&EnterLeaveSource);
+
+ if(SourceStretchedObj != NULL)
+ EngUnlockSurface(SourceStretchedObj);
+ if(SourceStretchedBitmap != 0)
+ EngDeleteSurface(SourceStretchedBitmap);
+
+ return Ret;
}
BOOL
Modified: branches/arwinss/reactos/subsystems/win32/win32k/gdi/bitmap.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win3…
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/gdi/bitmap.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/gdi/bitmap.c [iso-8859-1] Sat Nov 21
15:09:27 2009
@@ -17,12 +17,31 @@
/* PUBLIC FUNCTIONS **********************************************************/
-BOOL APIENTRY RosGdiAlphaBlend(HDC devDst, INT xDst, INT yDst, INT widthDst, INT
heightDst,
- HDC devSrc, INT xSrc, INT ySrc, INT widthSrc, INT
heightSrc,
+BOOL APIENTRY RosGdiAlphaBlend(HDC physDevDst, INT xDst, INT yDst, INT widthDst, INT
heightDst,
+ HDC physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT
heightSrc,
BLENDFUNCTION blendfn)
{
- UNIMPLEMENTED;
- return FALSE;
+ BOOLEAN bRes;
+ PDC pSrc, pDst;
+
+ DPRINT("AlphaBlend %x -> %x\n", physDevSrc, physDevDst);
+
+ /* Get a pointer to the DCs */
+ pSrc = DC_Lock(physDevSrc);
+ if (physDevSrc != physDevDst)
+ pDst = DC_Lock(physDevDst);
+ else
+ pDst = pSrc;
+
+ /* Call the internal helper */
+ bRes = GreAlphaBlend(pDst, xDst, yDst, widthDst, heightDst, pSrc, xSrc, ySrc,
widthSrc, heightSrc, blendfn);
+
+ /* Release DC objects */
+ if (physDevSrc != physDevDst) DC_Unlock(pDst);
+ DC_Unlock(pSrc);
+
+ /* Return status */
+ return bRes;
}
BOOL APIENTRY RosGdiBitBlt( HDC physDevDst, INT xDst, INT yDst,
Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/bitblt.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win3…
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/gre/bitblt.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/gre/bitblt.c [iso-8859-1] Sat Nov 21
15:09:27 2009
@@ -61,6 +61,69 @@
return ((width * depth + 31) & ~31) >> 3;
}
+BOOL APIENTRY
+GrepAlphaBlend(IN SURFOBJ *psoDest,
+ IN SURFOBJ *psoSource,
+ IN CLIPOBJ *ClipRegion,
+ IN XLATEOBJ *ColorTranslation,
+ IN PRECTL DestRect,
+ IN PRECTL SourceRect,
+ IN BLENDOBJ *BlendObj)
+{
+ BOOL ret = FALSE;
+ SURFACE *psurfDest;
+ SURFACE *psurfSource;
+
+ ASSERT(psoDest);
+ psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
+
+ ASSERT(psoSource);
+ psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
+
+ ASSERT(DestRect);
+ ASSERT(SourceRect);
+
+ /* Check if there is anything to draw */
+ if (ClipRegion != NULL &&
+ (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
+ ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
+ {
+ /* Nothing to do */
+ return TRUE;
+ }
+
+ 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)
+ {
+ ret = GDIDEVFUNCS(psoDest).AlphaBlend(
+ psoDest, psoSource, ClipRegion, ColorTranslation,
+ DestRect, SourceRect, BlendObj);
+ }
+
+ if (! ret)
+ {
+ ret = EngAlphaBlend(psoDest, psoSource, ClipRegion, ColorTranslation,
+ DestRect, SourceRect, BlendObj);
+ }
+
+ MouseSafetyOnDrawEnd(psoSource);
+ if (psoSource != psoDest)
+ SURFACE_UnlockBitmapBits(psurfSource);
+ MouseSafetyOnDrawEnd(psoDest);
+ SURFACE_UnlockBitmapBits(psurfDest);
+
+ return ret;
+}
+
BOOLEAN
NTAPI
GrepBitBltEx(
@@ -192,6 +255,67 @@
}
/* PUBLIC FUNCTIONS **********************************************************/
+
+BOOLEAN
+NTAPI
+GreAlphaBlend(PDC pDest, INT XDest, INT YDest,
+ INT WidthDst, INT HeightDst, PDC pSrc,
+ INT XSrc, INT YSrc, INT WidthSrc, INT HeightSrc,
+ BLENDFUNCTION blendfn)
+{
+ RECTL DestRect, SrcRect;
+ BOOL Status;
+ XLATEOBJ *XlateObj;
+ BLENDOBJ BlendObj;
+ BlendObj.BlendFunction = blendfn;
+
+ DestRect.left = XDest;
+ DestRect.top = YDest;
+ DestRect.right = XDest+WidthDst;
+ DestRect.bottom = YDest+HeightDst;
+
+ DestRect.left += pDest->rcVport.left + pDest->rcDcRect.left;
+ DestRect.top += pDest->rcVport.top + pDest->rcDcRect.top;
+ DestRect.right += pDest->rcVport.left + pDest->rcDcRect.left;
+ DestRect.bottom += pDest->rcVport.top + pDest->rcDcRect.top;
+
+ SrcRect.left = XSrc;
+ SrcRect.top = YSrc;
+ SrcRect.right = XSrc+WidthSrc;
+ SrcRect.bottom = YSrc+HeightSrc;
+
+ SrcRect.left += pSrc->rcVport.left + pSrc->rcDcRect.left;
+ SrcRect.top += pSrc->rcVport.top + pSrc->rcDcRect.top;
+ SrcRect.right += pSrc->rcVport.left + pSrc->rcDcRect.left;
+ SrcRect.bottom += pSrc->rcVport.top + pSrc->rcDcRect.top;
+
+ /* Create the XLATEOBJ. */
+ XlateObj = IntCreateXlateForBlt(pDest, pSrc, pDest->pBitmap, pSrc->pBitmap);
+
+ if (XlateObj == (XLATEOBJ*)-1)
+ {
+ DPRINT1("couldn't create XlateObj\n");
+ SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ XlateObj = NULL;
+ Status = FALSE;
+ }
+ else
+ {
+ /* Perform the alpha blend operation */
+ Status = GrepAlphaBlend(&pDest->pBitmap->SurfObj,
+ &pSrc->pBitmap->SurfObj,
+ pDest->CombinedClip,
+ XlateObj,
+ &DestRect,
+ &SrcRect,
+ &BlendObj);
+ }
+
+ if (XlateObj != NULL)
+ EngDeleteXlate(XlateObj);
+
+ return Status;
+}
BOOLEAN
NTAPI
Modified: branches/arwinss/reactos/subsystems/win32/win32k/include/gre.h
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win3…
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/include/gre.h [iso-8859-1]
(original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/include/gre.h [iso-8859-1] Sat Nov 21
15:09:27 2009
@@ -3,6 +3,12 @@
/* bitblt.c */
INT NTAPI DIB_GetDIBWidthBytes(INT width, INT depth);
+
+BOOLEAN NTAPI
+GreAlphaBlend(PDC pDest, INT XDest, INT YDest,
+ INT WidthDst, INT HeightDst, PDC pSrc,
+ INT XSrc, INT YSrc, INT WidthSrc, INT HeightSrc,
+ BLENDFUNCTION blendfn);
BOOLEAN NTAPI
GreBitBlt(PDC pDevDst, INT xDst, INT yDst,