Implement AlphaBlend using the XRENDER extension.
This commit is contained in:
parent
c09881d51c
commit
dd5b23fddb
|
@ -398,14 +398,30 @@ error:
|
|||
/******************************************************************************
|
||||
* GdiAlphaBlend [GDI32.@]
|
||||
*/
|
||||
BOOL WINAPI GdiAlphaBlend(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
|
||||
HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
|
||||
BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heightDst,
|
||||
HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
|
||||
BLENDFUNCTION blendFunction)
|
||||
{
|
||||
FIXME("partial stub - using StretchBlt\n");
|
||||
return StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
|
||||
hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
|
||||
SRCCOPY);
|
||||
BOOL ret = FALSE;
|
||||
DC *dcDst, *dcSrc;
|
||||
DWORD bfn = 0;
|
||||
|
||||
if ((dcSrc = DC_GetDCUpdate( hdcSrc ))) GDI_ReleaseObj( hdcSrc );
|
||||
/* FIXME: there is a race condition here */
|
||||
if ((dcDst = DC_GetDCUpdate( hdcDst )))
|
||||
{
|
||||
dcSrc = DC_GetDCPtr( hdcSrc );
|
||||
TRACE("%p %d,%d %dx%d -> %p %d,%d %dx%d blend=%08lx\n",
|
||||
hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
|
||||
hdcDst, xDst, yDst, widthDst, heightDst, bfn );
|
||||
if (dcDst->funcs->pAlphaBlend)
|
||||
ret = dcDst->funcs->pAlphaBlend( dcDst->physDev, xDst, yDst, widthDst, heightDst,
|
||||
dcSrc ? dcSrc->physDev : NULL,
|
||||
xSrc, ySrc, widthSrc, heightSrc, bfn );
|
||||
if (dcSrc) GDI_ReleaseObj( hdcSrc );
|
||||
GDI_ReleaseObj( hdcDst );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -77,6 +77,7 @@ static struct graphics_driver *create_driver( HMODULE module )
|
|||
|
||||
GET_FUNC(AbortDoc);
|
||||
GET_FUNC(AbortPath);
|
||||
GET_FUNC(AlphaBlend);
|
||||
GET_FUNC(AngleArc);
|
||||
GET_FUNC(Arc);
|
||||
GET_FUNC(ArcTo);
|
||||
|
|
|
@ -36,6 +36,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
|
|||
{
|
||||
NULL, /* pAbortDoc */
|
||||
EMFDRV_AbortPath, /* pAbortPath */
|
||||
NULL, /* pAlphaBlend */
|
||||
NULL, /* pAngleArc */
|
||||
EMFDRV_Arc, /* pArc */
|
||||
NULL, /* pArcTo */
|
||||
|
|
|
@ -52,6 +52,7 @@ typedef struct tagDC_FUNCS
|
|||
{
|
||||
INT (*pAbortDoc)(PHYSDEV);
|
||||
BOOL (*pAbortPath)(PHYSDEV);
|
||||
BOOL (*pAlphaBlend)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,DWORD);
|
||||
BOOL (*pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
|
||||
BOOL (*pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
|
||||
BOOL (*pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
|
||||
|
|
|
@ -36,6 +36,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
|
|||
{
|
||||
NULL, /* pAbortDoc */
|
||||
MFDRV_AbortPath, /* pAbortPath */
|
||||
NULL, /* pAlphaBlend */
|
||||
NULL, /* pAngleArc */
|
||||
MFDRV_Arc, /* pArc */
|
||||
NULL, /* pArcTo */
|
||||
|
|
|
@ -117,6 +117,10 @@ extern unsigned int X11DRV_server_startticks;
|
|||
|
||||
/* Wine driver X11 functions */
|
||||
|
||||
extern BOOL X11DRV_AlphaBlend( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
|
||||
INT widthDst, INT heightDst,
|
||||
X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc,
|
||||
INT widthSrc, INT heightSrc, DWORD blendfn );
|
||||
extern BOOL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
|
||||
INT width, INT height, X11DRV_PDEVICE *physDevSrc,
|
||||
INT xSrc, INT ySrc, DWORD rop );
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# GDI driver
|
||||
|
||||
@ cdecl AlphaBlend(ptr long long long long ptr long long long long long) X11DRV_AlphaBlend
|
||||
@ cdecl Arc(ptr long long long long long long long long) X11DRV_Arc
|
||||
@ cdecl BitBlt(ptr long long long long ptr long long long) X11DRV_BitBlt
|
||||
@ cdecl ChoosePixelFormat(ptr ptr) X11DRV_ChoosePixelFormat
|
||||
|
|
|
@ -47,6 +47,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(xrender);
|
|||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
/* Older version of the Xrender headers don't define these */
|
||||
#ifndef PictStandardARGB32
|
||||
|
||||
#define PictStandardARGB32 0
|
||||
XRenderPictFormat * XRenderFindStandardFormat (Display *dpy, int format);
|
||||
|
||||
#endif
|
||||
|
||||
static XRenderPictFormat *screen_format; /* format of screen */
|
||||
static XRenderPictFormat *mono_format; /* format of mono bitmap */
|
||||
|
||||
|
@ -109,6 +117,7 @@ static void *xrender_handle;
|
|||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f;
|
||||
MAKE_FUNCPTR(XRenderAddGlyphs)
|
||||
MAKE_FUNCPTR(XRenderComposite)
|
||||
MAKE_FUNCPTR(XRenderCompositeString8)
|
||||
MAKE_FUNCPTR(XRenderCompositeString16)
|
||||
MAKE_FUNCPTR(XRenderCompositeString32)
|
||||
|
@ -116,6 +125,7 @@ MAKE_FUNCPTR(XRenderCreateGlyphSet)
|
|||
MAKE_FUNCPTR(XRenderCreatePicture)
|
||||
MAKE_FUNCPTR(XRenderFillRectangle)
|
||||
MAKE_FUNCPTR(XRenderFindFormat)
|
||||
MAKE_FUNCPTR(XRenderFindStandardFormat)
|
||||
MAKE_FUNCPTR(XRenderFindVisualFormat)
|
||||
MAKE_FUNCPTR(XRenderFreeGlyphSet)
|
||||
MAKE_FUNCPTR(XRenderFreePicture)
|
||||
|
@ -152,6 +162,7 @@ void X11DRV_XRender_Init(void)
|
|||
|
||||
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xrender_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
|
||||
LOAD_FUNCPTR(XRenderAddGlyphs)
|
||||
LOAD_FUNCPTR(XRenderComposite)
|
||||
LOAD_FUNCPTR(XRenderCompositeString8)
|
||||
LOAD_FUNCPTR(XRenderCompositeString16)
|
||||
LOAD_FUNCPTR(XRenderCompositeString32)
|
||||
|
@ -159,6 +170,7 @@ LOAD_FUNCPTR(XRenderCreateGlyphSet)
|
|||
LOAD_FUNCPTR(XRenderCreatePicture)
|
||||
LOAD_FUNCPTR(XRenderFillRectangle)
|
||||
LOAD_FUNCPTR(XRenderFindFormat)
|
||||
LOAD_FUNCPTR(XRenderFindStandardFormat)
|
||||
LOAD_FUNCPTR(XRenderFindVisualFormat)
|
||||
LOAD_FUNCPTR(XRenderFreeGlyphSet)
|
||||
LOAD_FUNCPTR(XRenderFreePicture)
|
||||
|
@ -1504,6 +1516,123 @@ done:
|
|||
return retv;
|
||||
}
|
||||
|
||||
BOOL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
|
||||
X11DRV_PDEVICE *devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
|
||||
DWORD blendfn)
|
||||
{
|
||||
XRenderPictureAttributes pa;
|
||||
XRenderPictFormat *src_format;
|
||||
Picture dst_pict, src_pict;
|
||||
Pixmap xpm;
|
||||
HBITMAP hBitmap;
|
||||
BITMAPOBJ *bmp;
|
||||
XImage *image;
|
||||
GC gc;
|
||||
XGCValues gcv;
|
||||
char *dstbits, *data;
|
||||
int y;
|
||||
POINT pts[2];
|
||||
|
||||
if(!X11DRV_XRender_Installed) {
|
||||
FIXME("Unable to AlphaBlend without Xrender\n");
|
||||
return FALSE;
|
||||
}
|
||||
pts[0].x = xDst;
|
||||
pts[0].y = yDst;
|
||||
pts[1].x = xDst + widthDst;
|
||||
pts[1].y = yDst + heightDst;
|
||||
LPtoDP(devDst->hdc, pts, 2);
|
||||
xDst = pts[0].x;
|
||||
yDst = pts[0].y;
|
||||
widthDst = pts[1].x - pts[0].x;
|
||||
heightDst = pts[1].y - pts[0].y;
|
||||
|
||||
pts[0].x = xSrc;
|
||||
pts[0].y = ySrc;
|
||||
pts[1].x = xSrc + widthSrc;
|
||||
pts[1].y = ySrc + heightSrc;
|
||||
LPtoDP(devSrc->hdc, pts, 2);
|
||||
xSrc = pts[0].x;
|
||||
ySrc = pts[0].y;
|
||||
widthSrc = pts[1].x - pts[0].x;
|
||||
heightSrc = pts[1].y - pts[0].y;
|
||||
|
||||
|
||||
if(widthDst != widthSrc || heightDst != heightSrc) {
|
||||
FIXME("Unable to Stretch\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hBitmap = GetCurrentObject( devSrc->hdc, OBJ_BITMAP );
|
||||
bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC );
|
||||
if(!bmp || !bmp->dib) {
|
||||
FIXME("not a dibsection\n");
|
||||
GDI_ReleaseObj( hBitmap );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(bmp->dib->dsBm.bmBitsPixel != 32) {
|
||||
FIXME("not a 32 bpp dibsection\n");
|
||||
GDI_ReleaseObj( hBitmap );
|
||||
return FALSE;
|
||||
}
|
||||
dstbits = data = HeapAlloc(GetProcessHeap(), 0, heightSrc * widthSrc * 4);
|
||||
for(y = ySrc + heightSrc - 1; y >= ySrc; y--) {
|
||||
memcpy(dstbits, (char *)bmp->dib->dsBm.bmBits + y * bmp->dib->dsBm.bmWidthBytes + xSrc * 4,
|
||||
widthSrc * 4);
|
||||
dstbits += widthSrc * 4;
|
||||
}
|
||||
|
||||
wine_tsx11_lock();
|
||||
image = XCreateImage(gdi_display, visual, 32, ZPixmap, 0,
|
||||
data, widthSrc, heightSrc, 32, widthSrc * 4);
|
||||
|
||||
src_format = pXRenderFindStandardFormat(gdi_display, PictStandardARGB32);
|
||||
|
||||
|
||||
TRACE("src_format %p\n", src_format);
|
||||
|
||||
pa.subwindow_mode = IncludeInferiors;
|
||||
|
||||
/* FIXME use devDst->xrender->pict ? */
|
||||
dst_pict = pXRenderCreatePicture(gdi_display,
|
||||
devDst->drawable,
|
||||
(devDst->depth == 1) ?
|
||||
mono_format : screen_format,
|
||||
CPSubwindowMode, &pa);
|
||||
TRACE("dst_pict %08lx\n", dst_pict);
|
||||
TRACE("src_drawable = %08lx\n", devSrc->drawable);
|
||||
xpm = XCreatePixmap(gdi_display,
|
||||
devSrc->drawable,
|
||||
widthSrc, heightSrc, 32);
|
||||
gcv.graphics_exposures = False;
|
||||
gc = XCreateGC(gdi_display, xpm, GCGraphicsExposures, &gcv);
|
||||
TRACE("xpm = %08lx\n", xpm);
|
||||
XPutImage(gdi_display, xpm, gc, image, 0, 0, 0, 0, widthSrc, heightSrc);
|
||||
|
||||
src_pict = pXRenderCreatePicture(gdi_display,
|
||||
xpm, src_format,
|
||||
CPSubwindowMode, &pa);
|
||||
TRACE("src_pict %08lx\n", src_pict);
|
||||
|
||||
pXRenderComposite(gdi_display, PictOpOver, src_pict, 0, dst_pict,
|
||||
xSrc, ySrc, 0, 0,
|
||||
xDst + devDst->org.x, yDst + devDst->org.y, widthSrc, heightSrc);
|
||||
|
||||
|
||||
pXRenderFreePicture(gdi_display, src_pict);
|
||||
XFreePixmap(gdi_display, xpm);
|
||||
XFreeGC(gdi_display, gc);
|
||||
pXRenderFreePicture(gdi_display, dst_pict);
|
||||
image->data = NULL;
|
||||
XDestroyImage(image);
|
||||
|
||||
wine_tsx11_unlock();
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
GDI_ReleaseObj( hBitmap );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* HAVE_X11_EXTENSIONS_XRENDER_H */
|
||||
|
||||
void X11DRV_XRender_Init(void)
|
||||
|
@ -1542,4 +1671,12 @@ void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev)
|
|||
return;
|
||||
}
|
||||
|
||||
BOOL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
|
||||
X11DRV_PDEVICE *devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
|
||||
DWORD blendfn)
|
||||
{
|
||||
FIXME("not supported - XRENDER headers were missing at compile time\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* HAVE_X11_EXTENSIONS_XRENDER_H */
|
||||
|
|
Loading…
Reference in New Issue