winex11: Add an AlphaBlend entry point in the XRender driver.
authorAlexandre Julliard <julliard@winehq.org>
Mon, 12 Sep 2011 10:20:01 +0000 (12:20 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Mon, 12 Sep 2011 12:03:11 +0000 (14:03 +0200)
dlls/winex11.drv/bitblt.c
dlls/winex11.drv/init.c
dlls/winex11.drv/x11drv.h
dlls/winex11.drv/xrender.c

index 2e851c0b4460a1e2bc6293ae3b86084688a69870..bcdb996669f7759b19a8bb3ba3ab2eae15682e02 100644 (file)
@@ -1553,28 +1553,6 @@ done:
 }
 
 
-/***********************************************************************
- *           X11DRV_AlphaBlend
- */
-BOOL X11DRV_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
-                        PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION blendfn )
-{
-    X11DRV_PDEVICE *physDevDst = get_x11drv_dev( dst_dev );
-    X11DRV_PDEVICE *physDevSrc = get_x11drv_dev( src_dev ); /* FIXME: check that it's really an x11 dev */
-
-    if (src->x < 0 || src->y < 0 || src->width < 0 || src->height < 0 ||
-        src->width > physDevSrc->drawable_rect.right - physDevSrc->drawable_rect.left - src->x ||
-        src->height > physDevSrc->drawable_rect.bottom - physDevSrc->drawable_rect.top - src->y)
-    {
-        WARN( "Invalid src coords: (%d,%d), size %dx%d\n", src->x, src->y, src->width, src->height );
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return FALSE;
-    }
-
-    return XRender_AlphaBlend( physDevDst, dst, physDevSrc, src, blendfn );
-}
-
-
 static void free_heap_bits( struct gdi_image_bits *bits )
 {
     HeapFree( GetProcessHeap(), 0, bits->ptr );
index db430eca89c7285f7016a920e572b8428bef8d6a..df6084a047c25f365fda2738233147fe0c7ef24a 100644 (file)
@@ -467,7 +467,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
 {
     NULL,                               /* pAbortDoc */
     NULL,                               /* pAbortPath */
-    X11DRV_AlphaBlend,                  /* pAlphaBlend */
+    NULL,                               /* pAlphaBlend */
     NULL,                               /* pAngleArc */
     X11DRV_Arc,                         /* pArc */
     NULL,                               /* pArcTo */
index 76d0bb5839ecb4e26131b29a93d1d8aaf8be839f..c128da781be1de6fb5aabdd16261782826939dbe 100644 (file)
@@ -180,9 +180,6 @@ extern GC get_bitmap_gc(int depth) DECLSPEC_HIDDEN;
 
 /* Wine driver X11 functions */
 
-extern BOOL X11DRV_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
-                               PHYSDEV src_dev, struct bitblt_coords *src,
-                               BLENDFUNCTION blendfn ) DECLSPEC_HIDDEN;
 extern BOOL X11DRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
                         INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
 extern BOOL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
@@ -309,9 +306,6 @@ extern BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits
 BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
                                       Pixmap pixmap, GC gc,
                                       const struct bitblt_coords *src, const struct bitblt_coords *dst ) DECLSPEC_HIDDEN;
-extern BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst,
-                                X11DRV_PDEVICE *devSrc, struct bitblt_coords *src,
-                                BLENDFUNCTION blendfn ) DECLSPEC_HIDDEN;
 
 extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev) DECLSPEC_HIDDEN;
 extern BOOL destroy_glxpixmap(Display *display, XID glxpixmap) DECLSPEC_HIDDEN;
index 64df1440eb4a8f16d959d7124027ab204b0b73cb..62db5b09d1f0dedd3d28f279c9d7a2e72decd4fa 100644 (file)
@@ -2335,28 +2335,39 @@ static void xrender_mono_blit( Picture src_pict, Picture mask_pict, Picture dst_
                       0, 0, x_offset, y_offset, 0, 0, width, height);
 }
 
-/******************************************************************************
- * AlphaBlend
+/***********************************************************************
+ *           xrenderdrv_AlphaBlend
  */
-BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst,
-                         X11DRV_PDEVICE *devSrc, struct bitblt_coords *src, BLENDFUNCTION blendfn )
+static BOOL xrenderdrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
+                                   PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION blendfn )
 {
+    struct xrender_physdev *physdev_dst = get_xrender_dev( dst_dev );
+    struct xrender_physdev *physdev_src = get_xrender_dev( src_dev );
     Picture dst_pict, src_pict = 0, mask_pict = 0, tmp_pict = 0;
-    struct xrender_info *src_info = get_xrender_info( devSrc );
     double xscale, yscale;
     BOOL use_repeat;
 
-    if(!X11DRV_XRender_Installed) {
-        FIXME("Unable to AlphaBlend without Xrender\n");
+    if (src->x < 0 || src->y < 0 || src->width < 0 || src->height < 0 ||
+        src->width > physdev_src->x11dev->drawable_rect.right - physdev_src->x11dev->drawable_rect.left - src->x ||
+        src->height > physdev_src->x11dev->drawable_rect.bottom - physdev_src->x11dev->drawable_rect.top - src->y)
+    {
+        WARN( "Invalid src coords: (%d,%d), size %dx%d\n", src->x, src->y, src->width, src->height );
+        SetLastError( ERROR_INVALID_PARAMETER );
         return FALSE;
     }
 
-    if (devSrc != devDst) X11DRV_LockDIBSection( devSrc, DIB_Status_GdiMod );
-    X11DRV_LockDIBSection( devDst, DIB_Status_GdiMod );
+    if (!X11DRV_XRender_Installed || src_dev->funcs != dst_dev->funcs)
+    {
+        dst_dev = GET_NEXT_PHYSDEV( dst_dev, pAlphaBlend );
+        return dst_dev->funcs->pAlphaBlend( dst_dev, dst, src_dev, src, blendfn );
+    }
+
+    if (physdev_src->x11dev != physdev_dst->x11dev) X11DRV_LockDIBSection( physdev_src->x11dev, DIB_Status_GdiMod );
+    X11DRV_LockDIBSection( physdev_dst->x11dev, DIB_Status_GdiMod );
 
-    dst_pict = get_xrender_picture( devDst );
+    dst_pict = get_xrender_picture( physdev_dst->x11dev );
 
-    use_repeat = use_source_repeat( devSrc );
+    use_repeat = use_source_repeat( physdev_src->x11dev );
     if (!use_repeat)
     {
         xscale = src->width / (double)dst->width;
@@ -2364,11 +2375,11 @@ BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst,
     }
     else xscale = yscale = 1;  /* no scaling needed with a repeating source */
 
-    if (!(blendfn.AlphaFormat & AC_SRC_ALPHA) && src_info->format)
+    if (!(blendfn.AlphaFormat & AC_SRC_ALPHA) && physdev_src->info.format)
     {
         /* we need a source picture with no alpha */
-        WXRFormat format = get_format_without_alpha( src_info->format->format );
-        if (format != src_info->format->format)
+        WXRFormat format = get_format_without_alpha( physdev_src->info.format->format );
+        if (format != physdev_src->info.format->format)
         {
             XRenderPictureAttributes pa;
             const WineXRenderFormat *fmt = get_xrender_format( format );
@@ -2376,30 +2387,32 @@ BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst,
             wine_tsx11_lock();
             pa.subwindow_mode = IncludeInferiors;
             pa.repeat = use_repeat ? RepeatNormal : RepeatNone;
-            tmp_pict = pXRenderCreatePicture( gdi_display, devSrc->drawable, fmt->pict_format,
+            tmp_pict = pXRenderCreatePicture( gdi_display, physdev_src->x11dev->drawable, fmt->pict_format,
                                               CPSubwindowMode|CPRepeat, &pa );
             wine_tsx11_unlock();
             src_pict = tmp_pict;
         }
     }
 
-    if (!src_pict) src_pict = get_xrender_picture_source( devSrc, use_repeat );
+    if (!src_pict) src_pict = get_xrender_picture_source( physdev_src->x11dev, use_repeat );
 
     EnterCriticalSection( &xrender_cs );
     mask_pict = get_mask_pict( blendfn.SourceConstantAlpha * 257 );
 
     wine_tsx11_lock();
     xrender_blit( PictOpOver, src_pict, mask_pict, dst_pict,
-                  devSrc->dc_rect.left + src->visrect.left, devSrc->dc_rect.top + src->visrect.top,
-                  devDst->dc_rect.left + dst->visrect.left, devDst->dc_rect.top + dst->visrect.top,
+                  physdev_src->x11dev->dc_rect.left + src->visrect.left,
+                  physdev_src->x11dev->dc_rect.top + src->visrect.top,
+                  physdev_dst->x11dev->dc_rect.left + dst->visrect.left,
+                  physdev_dst->x11dev->dc_rect.top + dst->visrect.top,
                   xscale, yscale,
                   dst->visrect.right - dst->visrect.left, dst->visrect.bottom - dst->visrect.top );
     if (tmp_pict) pXRenderFreePicture( gdi_display, tmp_pict );
     wine_tsx11_unlock();
 
     LeaveCriticalSection( &xrender_cs );
-    if (devSrc != devDst) X11DRV_UnlockDIBSection( devSrc, FALSE );
-    X11DRV_UnlockDIBSection( devDst, TRUE );
+    if (physdev_src->x11dev != physdev_dst->x11dev) X11DRV_UnlockDIBSection( physdev_src->x11dev, FALSE );
+    X11DRV_UnlockDIBSection( physdev_dst->x11dev, TRUE );
     return TRUE;
 }
 
@@ -2540,7 +2553,7 @@ static const struct gdi_dc_funcs xrender_funcs =
 {
     NULL,                               /* pAbortDoc */
     NULL,                               /* pAbortPath */
-    NULL,                               /* pAlphaBlend */
+    xrenderdrv_AlphaBlend,              /* pAlphaBlend */
     NULL,                               /* pAngleArc */
     NULL,                               /* pArc */
     NULL,                               /* pArcTo */
@@ -2677,13 +2690,6 @@ void X11DRV_XRender_SetDeviceClipping(X11DRV_PDEVICE *physDev, const RGNDATA *da
     return;
 }
 
-BOOL XRender_AlphaBlend( X11DRV_PDEVICE *devDst, struct bitblt_coords *dst,
-                         X11DRV_PDEVICE *devSrc, struct bitblt_coords *src, BLENDFUNCTION blendfn )
-{
-  FIXME("not supported - XRENDER headers were missing at compile time\n");
-  return FALSE;
-}
-
 void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height)
 {
     wine_tsx11_lock();