[PATCH xserver 2/3] glamor: Accelerate up XY pixmap putimage a little

Keith Packard keithp at keithp.com
Sat Oct 1 05:44:01 UTC 2016


Convert the image to a temporary CPU pixmap, then copy that to the
destination. This is a lot faster for small images, and not any slower
for large images.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 glamor/glamor_image.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index 798277b..47968e2 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -237,6 +237,52 @@ bail:
     return ret;
 }
 
+/*
+ * Create a temporary in-memory pixmap, put the image there then copy
+ * to the destination.
+ */
+
+static Bool
+glamor_put_image_xy_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+                       int w, int h, int leftPad, int format, char *bits)
+{
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+    ScreenPtr   screen = drawable->pScreen;
+    PixmapPtr   temp_pixmap = NULL;
+    DrawablePtr temp_drawable;
+    GCPtr       temp_gc;
+    Bool        ret = FALSE;
+    ChangeGCVal gcv[3];
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return FALSE;
+
+    temp_pixmap = (*screen->CreatePixmap)(screen, w, h, drawable->depth, GLAMOR_CREATE_PIXMAP_CPU);
+    if (!temp_pixmap)
+        goto bail;
+    temp_drawable = &temp_pixmap->drawable;
+    temp_gc = GetScratchGC(temp_drawable->depth, screen);
+    if (!temp_gc)
+        goto bail_pixmap;
+
+    /* copy mode for the first plane to clear all of the other bits */
+    gcv[0].val = GXcopy;
+    gcv[1].val = gc->fgPixel;
+    gcv[2].val = gc->bgPixel;
+    ChangeGC(NullClient, temp_gc, GCFunction|GCForeground|GCBackground, gcv);
+    ValidateGC(temp_drawable, temp_gc);
+    (*temp_gc->ops->PutImage)(temp_drawable, temp_gc, depth, 0, 0, w, h, leftPad, format, bits);
+    (*gc->ops->CopyArea)(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y);
+    ret = TRUE;
+
+    FreeScratchGC(temp_gc);
+bail_pixmap:
+    (*screen->DestroyPixmap)(temp_pixmap);
+bail:
+    return ret;
+}
+
 static void
 glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
                       int w, int h, int leftPad, int format, char *bits)
@@ -256,6 +302,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
             return;
         break;
     case XYPixmap:
+        if (glamor_put_image_xy_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits))
+            return;
         break;
     case XYBitmap:
         if (glamor_put_image_xybitmap_gl(drawable, gc, x, y, w, h, leftPad, bits))
-- 
2.9.3



More information about the xorg-devel mailing list