Alexandre Julliard : winex11: Add a helper function to create the source pixmap from an image.
Alexandre Julliard
julliard at winehq.org
Tue Sep 20 13:08:35 CDT 2011
Module: wine
Branch: master
Commit: aa4655e8995e14e49450f6b23866b80e186a8329
URL: http://source.winehq.org/git/wine.git/?a=commit;h=aa4655e8995e14e49450f6b23866b80e186a8329
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Sep 20 11:21:00 2011 +0200
winex11: Add a helper function to create the source pixmap from an image.
---
dlls/winex11.drv/xrender.c | 124 ++++++++++++++++++++++++++------------------
1 files changed, 74 insertions(+), 50 deletions(-)
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index b991935..384275f 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -2388,6 +2388,56 @@ static void get_colors( struct xrender_physdev *physdev_src, struct xrender_phys
get_xrender_color( physdev_dst->pict_format, physdev_dst->x11dev->backgroundPixel, bg );
}
+/* create a pixmap and render picture for an image */
+static DWORD create_image_pixmap( BITMAPINFO *info, const struct gdi_image_bits *bits,
+ struct bitblt_coords *src, enum wxr_format format,
+ Pixmap *pixmap, Picture *pict, BOOL *use_repeat )
+{
+ DWORD ret;
+ int width = src->visrect.right - src->visrect.left;
+ int height = src->visrect.bottom - src->visrect.top;
+ int depth = pict_formats[format]->depth;
+ struct gdi_image_bits dst_bits;
+ XRenderPictureAttributes pa;
+ XImage *image;
+
+ wine_tsx11_lock();
+ image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, NULL,
+ info->bmiHeader.biWidth, height, 32, 0 );
+ wine_tsx11_unlock();
+ if (!image) return ERROR_OUTOFMEMORY;
+
+ ret = copy_image_bits( info, (format == WXR_FORMAT_R8G8B8), image, bits, &dst_bits, src, NULL, ~0u );
+ if (ret) return ret;
+
+ image->data = dst_bits.ptr;
+ /* hack: make sure the bits are readable if we are reading from a DIB section */
+ /* to be removed once we get rid of DIB access protections */
+ if (!dst_bits.is_copy) IsBadReadPtr( dst_bits.ptr, image->height * image->bytes_per_line );
+
+ *use_repeat = (width == 1 && height == 1);
+ pa.repeat = *use_repeat ? RepeatNormal : RepeatNone;
+
+ wine_tsx11_lock();
+ *pixmap = XCreatePixmap( gdi_display, root_window, width, height, depth );
+ XPutImage( gdi_display, *pixmap, get_bitmap_gc( depth ), image,
+ src->visrect.left, 0, 0, 0, width, height );
+ *pict = pXRenderCreatePicture( gdi_display, *pixmap, pict_formats[format], CPRepeat, &pa );
+ wine_tsx11_unlock();
+
+ /* make coordinates relative to the pixmap */
+ src->x -= src->visrect.left;
+ src->y -= src->visrect.top;
+ OffsetRect( &src->visrect, -src->visrect.left, -src->visrect.top );
+
+ image->data = NULL;
+ wine_tsx11_lock();
+ XDestroyImage( image );
+ wine_tsx11_unlock();
+ if (dst_bits.free) dst_bits.free( &dst_bits );
+ return ret;
+}
+
static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xrender_physdev *physdev_dst,
Drawable drawable, HRGN clip, const struct bitblt_coords *src,
const struct bitblt_coords *dst )
@@ -2488,21 +2538,18 @@ static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xr
HeapFree( GetProcessHeap(), 0, clip_data );
}
-static void xrender_put_image( XImage *image, HRGN clip, XRenderPictFormat *src_format,
+
+static void xrender_put_image( Pixmap src_pixmap, Picture src_pict, HRGN clip,
XRenderPictFormat *dst_format, struct xrender_physdev *physdev,
- Drawable drawable, struct bitblt_coords *src, struct bitblt_coords *dst )
+ Drawable drawable, struct bitblt_coords *src,
+ struct bitblt_coords *dst, BOOL use_repeat )
{
int x_src, y_src, x_dst, y_dst;
- Picture dst_pict, src_pict;
+ Picture dst_pict;
XRenderPictureAttributes pa;
- Pixmap src_pixmap;
double xscale, yscale;
RGNDATA *clip_data = NULL;
- /* make source relative to tmp pixmap origin */
- x_src = src->x - src->visrect.left;
- y_src = src->y - src->visrect.top;
-
if (drawable) /* using an intermediate pixmap */
{
if (clip) clip_data = X11DRV_GetRegionData( clip, 0 );
@@ -2524,35 +2571,25 @@ static void xrender_put_image( XImage *image, HRGN clip, XRenderPictFormat *src_
if (clip) clip_data = add_xrender_clipping_region( physdev, clip );
}
- if (image->width == 1 && image->height == 1)
- {
- pa.repeat = RepeatNormal;
- xscale = yscale = 1; /* no scaling needed with a repeating source */
- }
- else
+ if (!use_repeat)
{
- pa.repeat = RepeatNone;
xscale = src->width / (double)dst->width;
yscale = src->height / (double)dst->height;
}
+ else xscale = yscale = 1; /* no scaling needed with a repeating source */
+ x_src = src->x;
+ y_src = src->y;
if (src->width < 0) x_src += src->width + 1;
if (src->height < 0) y_src += src->height + 1;
if (dst->width < 0) x_dst += dst->width + 1;
if (dst->height < 0) y_dst += dst->height + 1;
wine_tsx11_lock();
- src_pixmap = XCreatePixmap( gdi_display, root_window, image->width, image->height, src_format->depth );
- XPutImage( gdi_display, src_pixmap, get_bitmap_gc( src_format->depth ),
- image, src->visrect.left, 0, 0, 0, image->width, image->height );
- src_pict = pXRenderCreatePicture( gdi_display, src_pixmap, src_format, CPRepeat, &pa );
-
xrender_blit( PictOpSrc, src_pict, 0, dst_pict, x_src, y_src, x_dst, y_dst,
xscale, yscale, abs( dst->width ), abs( dst->height ));
if (drawable) pXRenderFreePicture( gdi_display, dst_pict );
- pXRenderFreePicture( gdi_display, src_pict );
- XFreePixmap( gdi_display, src_pixmap );
wine_tsx11_unlock();
if (!drawable) update_xrender_clipping( physdev, clip_data );
@@ -2655,12 +2692,13 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
struct xrender_physdev *physdev;
X_PHYSBITMAP *bitmap;
DWORD ret;
- XImage *image;
Pixmap tmp_pixmap;
GC gc;
- struct gdi_image_bits dst_bits;
enum wxr_format src_format, dst_format;
XRenderPictFormat *pict_format;
+ Pixmap src_pixmap;
+ Picture src_pict;
+ BOOL use_repeat;
if (!X11DRV_XRender_Installed) goto x11drv_fallback;
@@ -2691,24 +2729,11 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
if (!bits) return ERROR_SUCCESS; /* just querying the format */
- wine_tsx11_lock();
- image = XCreateImage( gdi_display, visual, pict_format->depth, ZPixmap, 0, NULL,
- info->bmiHeader.biWidth, src->visrect.bottom - src->visrect.top, 32, 0 );
- wine_tsx11_unlock();
- if (!image) return ERROR_OUTOFMEMORY;
-
- ret = copy_image_bits( info, (src_format == WXR_FORMAT_R8G8B8),
- image, bits, &dst_bits, src, NULL, ~0u );
-
+ ret = create_image_pixmap( info, bits, src, src_format, &src_pixmap, &src_pict, &use_repeat );
if (!ret)
{
struct bitblt_coords tmp;
- image->data = dst_bits.ptr;
- /* hack: make sure the bits are readable if we are reading from a DIB section */
- /* to be removed once we get rid of DIB access protections */
- if (!dst_bits.is_copy) IsBadReadPtr( dst_bits.ptr, image->height * image->bytes_per_line );
-
if (bitmap)
{
HRGN rgn = CreateRectRgnIndirect( &dst->visrect );
@@ -2716,8 +2741,8 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
X11DRV_DIB_Lock( bitmap, DIB_Status_GdiMod );
- xrender_put_image( image, rgn, pict_formats[src_format], pict_formats[dst_format],
- NULL, bitmap->pixmap, src, dst );
+ xrender_put_image( src_pixmap, src_pict, rgn, pict_formats[dst_format],
+ NULL, bitmap->pixmap, src, dst, use_repeat );
X11DRV_DIB_Unlock( bitmap, TRUE );
DeleteObject( rgn );
@@ -2746,8 +2771,8 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
tmp.visrect.bottom - tmp.visrect.top, physdev->x11dev->depth );
wine_tsx11_unlock();
- xrender_put_image( image, NULL, pict_format, physdev->pict_format,
- NULL, tmp_pixmap, src, &tmp );
+ xrender_put_image( src_pixmap, src_pict, NULL, physdev->pict_format,
+ NULL, tmp_pixmap, src, &tmp, use_repeat );
execute_rop( physdev->x11dev, tmp_pixmap, gc, &dst->visrect, rop );
wine_tsx11_lock();
@@ -2761,20 +2786,19 @@ static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMA
{
HRGN rgn = CreateRectRgnIndirect( &dst->visrect );
if (clip) CombineRgn( rgn, rgn, clip, RGN_AND );
- xrender_put_image( image, rgn, pict_format, physdev->pict_format, physdev, 0, src, dst );
+ xrender_put_image( src_pixmap, src_pict, rgn,
+ physdev->pict_format, physdev, 0, src, dst, use_repeat );
DeleteObject( rgn );
}
- X11DRV_UnlockDIBSection( physdev->x11dev, !ret );
+ X11DRV_UnlockDIBSection( physdev->x11dev, TRUE );
}
- image->data = NULL;
+ wine_tsx11_lock();
+ pXRenderFreePicture( gdi_display, src_pict );
+ XFreePixmap( gdi_display, src_pixmap );
+ wine_tsx11_unlock();
}
-
- wine_tsx11_lock();
- XDestroyImage( image );
- wine_tsx11_unlock();
- if (dst_bits.free) dst_bits.free( &dst_bits );
return ret;
update_format:
More information about the wine-cvs
mailing list