Commit a16dbbe3 authored by Alexandre Julliard's avatar Alexandre Julliard

winex11: Implement a SelectBrush entry point in the XRender driver.

parent 26506897
......@@ -217,29 +217,27 @@ static void BRUSH_SelectPatternBrush( X11DRV_PDEVICE *physDev, HBITMAP hbitmap,
X11DRV_DIB_Lock( physBitmap, DIB_Status_GdiMod );
if (physDev->brush.pixmap)
{
wine_tsx11_lock();
XFreePixmap( gdi_display, physDev->brush.pixmap );
wine_tsx11_unlock();
}
wine_tsx11_lock();
if (physDev->brush.pixmap) XFreePixmap( gdi_display, physDev->brush.pixmap );
if ((physDev->depth == 1) && (physBitmap->depth != 1))
{
wine_tsx11_lock();
/* Special case: a color pattern on a monochrome DC */
physDev->brush.pixmap = XCreatePixmap( gdi_display, root_window,
bitmap.bmWidth, bitmap.bmHeight, 1);
/* FIXME: should probably convert to monochrome instead */
XCopyPlane( gdi_display, physBitmap->pixmap, physDev->brush.pixmap,
get_bitmap_gc(1), 0, 0, bitmap.bmWidth, bitmap.bmHeight, 0, 0, 1 );
wine_tsx11_unlock();
}
else
{
/* XRender is needed because of possible depth conversion */
X11DRV_XRender_CopyBrush(physDev, physBitmap, bitmap.bmWidth, bitmap.bmHeight);
physDev->brush.pixmap = XCreatePixmap( gdi_display, root_window,
bitmap.bmWidth, bitmap.bmHeight, physBitmap->depth );
XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap,
get_bitmap_gc(physBitmap->depth), 0, 0, bitmap.bmWidth, bitmap.bmHeight, 0, 0 );
}
wine_tsx11_unlock();
X11DRV_DIB_Unlock( physBitmap, TRUE );
......
......@@ -267,6 +267,7 @@ extern void X11DRV_FONT_Init( int log_pixels_x, int log_pixels_y ) DECLSPEC_HIDD
extern void X11DRV_XInput2_Init(void) DECLSPEC_HIDDEN;
extern int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) DECLSPEC_HIDDEN;
extern HBITMAP create_brush_bitmap( X11DRV_PDEVICE *physDev, const BITMAPINFO *info, void *bits, UINT usage ) DECLSPEC_HIDDEN;
extern XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth ) DECLSPEC_HIDDEN;
extern void X11DRV_DIB_DestroyXImage( XImage *image ) DECLSPEC_HIDDEN;
extern HGLOBAL X11DRV_DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp) DECLSPEC_HIDDEN;
......@@ -304,7 +305,6 @@ extern int client_side_antialias_with_render DECLSPEC_HIDDEN;
extern int using_client_side_fonts DECLSPEC_HIDDEN;
extern const struct gdi_dc_funcs *X11DRV_XRender_Init(void) DECLSPEC_HIDDEN;
extern void X11DRV_XRender_Finalize(void) DECLSPEC_HIDDEN;
extern void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height) DECLSPEC_HIDDEN;
extern BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib) DECLSPEC_HIDDEN;
extern Drawable get_glxdrawable(X11DRV_PDEVICE *physDev) DECLSPEC_HIDDEN;
......
......@@ -544,6 +544,22 @@ static enum wxr_format get_xrender_format_from_bitmapinfo( const BITMAPINFO *inf
return WXR_INVALID_FORMAT;
}
static enum wxr_format get_bitmap_format( int bpp )
{
enum wxr_format format = WXR_INVALID_FORMAT;
if (bpp == screen_bpp)
{
switch (bpp)
{
case 16: format = WXR_FORMAT_R5G6B5; break;
case 24: format = WXR_FORMAT_R8G8B8; break;
case 32: format = WXR_FORMAT_A8R8G8B8; break;
}
}
return format;
}
/* Set the x/y scaling and x/y offsets in the transformation matrix of the source picture */
static void set_xrender_transformation(Picture src_pict, double xscale, double yscale, int xoffset, int yoffset)
{
......@@ -1264,20 +1280,13 @@ static INT xrenderdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID
*/
static BOOL xrenderdrv_CreateBitmap( PHYSDEV dev, HBITMAP hbitmap )
{
enum wxr_format format = WXR_INVALID_FORMAT;
enum wxr_format format;
BITMAP bitmap;
if (!GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return FALSE;
if (bitmap.bmPlanes == 1 && bitmap.bmBitsPixel == screen_bpp)
{
switch (bitmap.bmBitsPixel)
{
case 16: format = WXR_FORMAT_R5G6B5; break;
case 24: format = WXR_FORMAT_R8G8B8; break;
case 32: format = WXR_FORMAT_A8R8G8B8; break;
}
}
if (bitmap.bmPlanes != 1) return FALSE;
format = get_bitmap_format( bitmap.bmBitsPixel );
if (pict_formats[format])
return X11DRV_create_phys_bitmap( hbitmap, &bitmap, pict_formats[format]->depth,
......@@ -2971,43 +2980,73 @@ static BOOL xrenderdrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
return TRUE;
}
void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height)
/***********************************************************************
* xrenderdrv_SelectBrush
*/
static HBRUSH xrenderdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap,
const BITMAPINFO *info, void *bits, UINT usage )
{
/* At depths >1, the depth of physBitmap and physDev might not be the same e.g. the physbitmap might be a 16-bit DIB while the physdev uses 24-bit */
int depth = physBitmap->depth == 1 ? 1 : physDev->depth;
enum wxr_format src_format = get_xrender_format_from_color_shifts(physBitmap->depth, &physBitmap->color_shifts);
enum wxr_format dst_format = get_xrender_format_from_color_shifts(physDev->depth, physDev->color_shifts);
struct xrender_physdev *physdev = get_xrender_dev( dev );
X_PHYSBITMAP *physbitmap;
enum wxr_format format;
BOOL delete_bitmap = FALSE;
BITMAP bm;
Pixmap pixmap;
Picture src_pict, dst_pict;
XRenderPictureAttributes pa;
wine_tsx11_lock();
physDev->brush.pixmap = XCreatePixmap(gdi_display, root_window, width, height, depth);
if (!X11DRV_XRender_Installed) goto x11drv_fallback;
if (!bitmap && !info) goto x11drv_fallback;
if (physdev->format == WXR_FORMAT_MONO) goto x11drv_fallback;
/* Use XCopyArea when the physBitmap and brush.pixmap have the same format. */
if( (physBitmap->depth == 1) || (!X11DRV_XRender_Installed && physDev->depth == physBitmap->depth) ||
(src_format == dst_format) )
if (!bitmap || !(physbitmap = X11DRV_get_phys_bitmap( bitmap )))
{
XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap,
get_bitmap_gc(physBitmap->depth), 0, 0, width, height, 0, 0 );
format = get_bitmap_format( info->bmiHeader.biBitCount );
if (format == physdev->format || !pict_formats[format]) goto x11drv_fallback;
if (!(bitmap = create_brush_bitmap( physdev->x11dev, info, bits, usage ))) return 0;
physbitmap = X11DRV_get_phys_bitmap( bitmap );
delete_bitmap = TRUE;
}
else /* We need depth conversion */
else
{
Picture src_pict, dst_pict;
XRenderPictureAttributes pa;
pa.subwindow_mode = IncludeInferiors;
pa.repeat = RepeatNone;
format = get_xrender_format_from_color_shifts( physbitmap->depth, &physbitmap->color_shifts );
if (format == WXR_FORMAT_MONO || format == physdev->format || !pict_formats[format])
goto x11drv_fallback;
}
src_pict = pXRenderCreatePicture(gdi_display, physBitmap->pixmap,
pict_formats[src_format], CPSubwindowMode|CPRepeat, &pa);
dst_pict = pXRenderCreatePicture(gdi_display, physDev->brush.pixmap,
pict_formats[dst_format], CPSubwindowMode|CPRepeat, &pa);
GetObjectW( bitmap, sizeof(bm), &bm );
xrender_blit(PictOpSrc, src_pict, 0, dst_pict, 0, 0, 0, 0, 1.0, 1.0, width, height);
pXRenderFreePicture(gdi_display, src_pict);
pXRenderFreePicture(gdi_display, dst_pict);
}
X11DRV_DIB_Lock( physbitmap, DIB_Status_GdiMod );
wine_tsx11_lock();
pixmap = XCreatePixmap( gdi_display, root_window, bm.bmWidth, bm.bmHeight,
physdev->pict_format->depth );
pa.repeat = RepeatNone;
src_pict = pXRenderCreatePicture(gdi_display, physbitmap->pixmap, pict_formats[format], CPRepeat, &pa);
dst_pict = pXRenderCreatePicture(gdi_display, pixmap, physdev->pict_format, CPRepeat, &pa);
xrender_blit( PictOpSrc, src_pict, 0, dst_pict, 0, 0, 0, 0, 1.0, 1.0, bm.bmWidth, bm.bmHeight );
pXRenderFreePicture( gdi_display, src_pict );
pXRenderFreePicture( gdi_display, dst_pict );
if (physdev->x11dev->brush.pixmap) XFreePixmap( gdi_display, physdev->x11dev->brush.pixmap );
physdev->x11dev->brush.pixmap = pixmap;
physdev->x11dev->brush.fillStyle = FillTiled;
physdev->x11dev->brush.pixel = 0; /* ignored */
wine_tsx11_unlock();
X11DRV_DIB_Unlock( physbitmap, TRUE );
if (delete_bitmap) DeleteObject( bitmap );
return hbrush;
x11drv_fallback:
if (delete_bitmap) DeleteObject( bitmap );
dev = GET_NEXT_PHYSDEV( dev, pSelectBrush );
return dev->funcs->pSelectBrush( dev, hbrush, bitmap, info, bits, usage );
}
static const struct gdi_dc_funcs xrender_funcs =
{
NULL, /* pAbortDoc */
......@@ -3102,7 +3141,7 @@ static const struct gdi_dc_funcs xrender_funcs =
NULL, /* pScaleViewportExt */
NULL, /* pScaleWindowExt */
xrenderdrv_SelectBitmap, /* pSelectBitmap */
NULL, /* pSelectBrush */
xrenderdrv_SelectBrush, /* pSelectBrush */
NULL, /* pSelectClipPath */
xrenderdrv_SelectFont, /* pSelectFont */
NULL, /* pSelectPalette */
......@@ -3158,16 +3197,6 @@ void X11DRV_XRender_Finalize(void)
{
}
void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height)
{
wine_tsx11_lock();
physDev->brush.pixmap = XCreatePixmap(gdi_display, root_window, width, height, physBitmap->depth);
XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap,
get_bitmap_gc(physBitmap->depth), 0, 0, width, height, 0, 0 );
wine_tsx11_unlock();
}
BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib)
{
return FALSE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment