From b174bde4d2e94c3fdfaadaf3e2c1af4491bb404b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 12 Sep 2011 12:20:01 +0200 Subject: [PATCH] winex11: Add an AlphaBlend entry point in the XRender driver. --- dlls/winex11.drv/bitblt.c | 22 -------------- dlls/winex11.drv/init.c | 2 +- dlls/winex11.drv/x11drv.h | 6 ---- dlls/winex11.drv/xrender.c | 62 +++++++++++++++++++++----------------- 4 files changed, 35 insertions(+), 57 deletions(-) diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 2e851c0b446..bcdb996669f 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -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 ); diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index db430eca89c..df6084a047c 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -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 */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 76d0bb5839e..c128da781be 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -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; diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 64df1440eb4..62db5b09d1f 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -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 ); + } - dst_pict = get_xrender_picture( devDst ); + if (physdev_src->x11dev != physdev_dst->x11dev) X11DRV_LockDIBSection( physdev_src->x11dev, DIB_Status_GdiMod ); + X11DRV_LockDIBSection( physdev_dst->x11dev, DIB_Status_GdiMod ); - use_repeat = use_source_repeat( devSrc ); + dst_pict = get_xrender_picture( physdev_dst->x11dev ); + + 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();