Alexandre Julliard : winex11: Avoid an intermediate pixmap copy when stretching with SRCCOPY through XRender .

Alexandre Julliard julliard at winehq.org
Thu Sep 15 12:34:52 CDT 2011


Module: wine
Branch: master
Commit: 14f6c42708a56a47c4e827fc815118d0ff496dc7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=14f6c42708a56a47c4e827fc815118d0ff496dc7

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Sep 15 13:12:54 2011 +0200

winex11: Avoid an intermediate pixmap copy when stretching with SRCCOPY through XRender.

---

 dlls/winex11.drv/xrender.c |   52 ++++++++++++++++++++++++-------------------
 1 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index 5b5a451..036ab39 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -2411,13 +2411,15 @@ static void get_colors( struct xrender_physdev *physdev_src, struct xrender_phys
 }
 
 static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xrender_physdev *physdev_dst,
-                                  Pixmap pixmap, const struct bitblt_coords *src,
+                                  Drawable drawable, const struct bitblt_coords *src,
                                   const struct bitblt_coords *dst )
 {
     int width = dst->visrect.right - dst->visrect.left;
     int height = dst->visrect.bottom - dst->visrect.top;
     int x_src = physdev_src->x11dev->dc_rect.left + src->visrect.left;
     int y_src = physdev_src->x11dev->dc_rect.top + src->visrect.top;
+    int x_dst = physdev_dst->x11dev->dc_rect.left + dst->visrect.left;
+    int y_dst = physdev_dst->x11dev->dc_rect.top + dst->visrect.top;
     Picture src_pict=0, dst_pict=0, mask_pict=0;
     BOOL use_repeat;
     double xscale, yscale;
@@ -2434,6 +2436,8 @@ static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xr
     }
     else xscale = yscale = 1;  /* no scaling needed with a repeating source */
 
+    if (drawable != physdev_dst->x11dev->drawable) x_dst = y_dst = 0;  /* using an intermediate pixmap */
+
     /* mono -> color */
     if (physdev_src->info.format->format == WXR_FORMAT_MONO &&
         physdev_dst->info.format->format != WXR_FORMAT_MONO)
@@ -2452,12 +2456,12 @@ static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xr
 
         /* Create a destination picture and fill it with textPixel color as the background color */
         wine_tsx11_lock();
-        dst_pict = pXRenderCreatePicture( gdi_display, pixmap, physdev_dst->info.format->pict_format,
+        dst_pict = pXRenderCreatePicture( gdi_display, drawable, physdev_dst->info.format->pict_format,
                                           CPSubwindowMode|CPRepeat, &pa );
-        pXRenderFillRectangle(gdi_display, PictOpSrc, dst_pict, &fg, 0, 0, width, height);
+        pXRenderFillRectangle( gdi_display, PictOpSrc, dst_pict, &fg, x_dst, y_dst, width, height );
 
         xrender_mono_blit( src_pict, mask_pict, dst_pict, x_src, y_src,
-                           0, 0, xscale, yscale, width, height );
+                           x_dst, y_dst, xscale, yscale, width, height );
 
         if (dst_pict) pXRenderFreePicture(gdi_display, dst_pict);
         wine_tsx11_unlock();
@@ -2470,11 +2474,11 @@ static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xr
         src_pict = get_xrender_picture_source( physdev_src->x11dev, use_repeat );
 
         wine_tsx11_lock();
-        dst_pict = pXRenderCreatePicture( gdi_display, pixmap, physdev_dst->info.format->pict_format,
+        dst_pict = pXRenderCreatePicture( gdi_display, drawable, physdev_dst->info.format->pict_format,
                                           CPSubwindowMode|CPRepeat, &pa );
 
         xrender_blit( PictOpSrc, src_pict, mask_pict, dst_pict,
-                      x_src, y_src, 0, 0, xscale, yscale, width, height );
+                      x_src, y_src, x_dst, y_dst, xscale, yscale, width, height );
 
         if (dst_pict) pXRenderFreePicture(gdi_display, dst_pict);
         wine_tsx11_unlock();
@@ -2490,10 +2494,7 @@ static BOOL xrenderdrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
 {
     struct xrender_physdev *physdev_dst = get_xrender_dev( dst_dev );
     struct xrender_physdev *physdev_src = get_xrender_dev( src_dev );
-    INT width, height;
     INT sSrc, sDst;
-    Pixmap src_pixmap;
-    GC tmpGC;
     BOOL stretch = (src->width != dst->width) || (src->height != dst->height);
 
     if (src_dev->funcs != dst_dev->funcs)
@@ -2525,23 +2526,28 @@ static BOOL xrenderdrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
     X11DRV_CoerceDIBSection( physdev_dst->x11dev, DIB_Status_GdiMod );
     if (physdev_dst != physdev_src) X11DRV_CoerceDIBSection( physdev_src->x11dev, DIB_Status_GdiMod );
 
-    width  = dst->visrect.right - dst->visrect.left;
-    height = dst->visrect.bottom - dst->visrect.top;
+    if (rop != SRCCOPY)
+    {
+        GC tmpGC;
+        Pixmap tmp_pixmap;
 
-    wine_tsx11_lock();
-    tmpGC = XCreateGC( gdi_display, physdev_dst->x11dev->drawable, 0, NULL );
-    XSetSubwindowMode( gdi_display, tmpGC, IncludeInferiors );
-    XSetGraphicsExposures( gdi_display, tmpGC, False );
-    src_pixmap = XCreatePixmap( gdi_display, root_window, width, height, physdev_dst->x11dev->depth );
-    wine_tsx11_unlock();
+        wine_tsx11_lock();
+        tmpGC = XCreateGC( gdi_display, physdev_dst->x11dev->drawable, 0, NULL );
+        XSetSubwindowMode( gdi_display, tmpGC, IncludeInferiors );
+        XSetGraphicsExposures( gdi_display, tmpGC, False );
+        tmp_pixmap = XCreatePixmap( gdi_display, root_window, dst->visrect.right - dst->visrect.left,
+                                    dst->visrect.bottom - dst->visrect.top, physdev_dst->x11dev->depth );
+        wine_tsx11_unlock();
 
-    xrender_stretch_blit( physdev_src, physdev_dst, src_pixmap, src, dst );
-    execute_rop( physdev_dst->x11dev, src_pixmap, tmpGC, &dst->visrect, rop );
+        xrender_stretch_blit( physdev_src, physdev_dst, tmp_pixmap, src, dst );
+        execute_rop( physdev_dst->x11dev, tmp_pixmap, tmpGC, &dst->visrect, rop );
 
-    wine_tsx11_lock();
-    XFreePixmap( gdi_display, src_pixmap );
-    XFreeGC( gdi_display, tmpGC );
-    wine_tsx11_unlock();
+        wine_tsx11_lock();
+        XFreePixmap( gdi_display, tmp_pixmap );
+        XFreeGC( gdi_display, tmpGC );
+        wine_tsx11_unlock();
+    }
+    else xrender_stretch_blit( physdev_src, physdev_dst, physdev_dst->x11dev->drawable, src, dst );
 
     if (physdev_dst != physdev_src) X11DRV_UnlockDIBSection( physdev_src->x11dev, FALSE );
     X11DRV_UnlockDIBSection( physdev_dst->x11dev, TRUE );




More information about the wine-cvs mailing list