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/win32/win32k/eng/engblt.c?rev=44252&r1=44251&r2=44252&view=diff
==============================================================================
--- 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 ([email protected])
+                    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/win32/win32k/gdi/bitmap.c?rev=44252&r1=44251&r2=44252&view=diff
==============================================================================
--- 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/win32/win32k/gre/bitblt.c?rev=44252&r1=44251&r2=44252&view=diff
==============================================================================
--- 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/win32/win32k/include/gre.h?rev=44252&r1=44251&r2=44252&view=diff
==============================================================================
--- 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,


Reply via email to