[PATCH xserver] glamor: Accelerate XYBitmap PutImage

Adam Jackson ajax at redhat.com
Fri Sep 30 14:12:11 UTC 2016


XYBitmap to a drawable of depth != 1 is special. Where bits are 1, we
draw the foreground color; where they are 0, we draw the background
color. To handle this without falling back, allocate a temporary pixmap,
do the color expansion in software, and then upload that image to the
destination.

This could probably be made faster if GL exposed an R1 texture format.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 glamor/glamor_image.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index 3158749..699bdb8 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -24,6 +24,33 @@
 #include "glamor_transfer.h"
 #include "glamor_transform.h"
 
+static PixmapPtr
+glamor_expand_bitmap(DrawablePtr drawable, GCPtr src, int w, int h, char *bits)
+{
+    ScreenPtr screen = drawable->pScreen;
+    PixmapPtr ret;
+    GCPtr gc;
+    ChangeGCVal v[2];
+
+    if (!(gc = GetScratchGC(drawable->depth, screen)))
+        return NULL;
+
+    ret = screen->CreatePixmap(screen, w, h, drawable->depth,
+                               GLAMOR_CREATE_PIXMAP_CPU);
+
+    if (ret) {
+        DrawablePtr scratch = &ret->drawable;
+        v[0].val = src->fgPixel;
+        v[1].val = src->bgPixel;
+        ChangeGC(serverClient, gc, GCForeground | GCBackground, v);
+        ValidateGC(scratch, gc);
+        fbPutImage(scratch, gc, gc->depth, 0, 0, w, h, 0, XYBitmap, bits);
+    }
+
+    FreeScratchGC(gc);
+    return ret;
+}
+
 /*
  * PutImage. Only does ZPixmap right now as other formats are quite a bit harder
  */
@@ -35,6 +62,7 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     ScreenPtr screen = drawable->pScreen;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    PixmapPtr tmp = NULL;
     glamor_pixmap_private *pixmap_priv;
     uint32_t    byte_stride = PixmapBytePad(w, drawable->depth);
     RegionRec   region;
@@ -55,6 +83,14 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     if (format == XYPixmap && drawable->depth == 1 && leftPad == 0)
         format = ZPixmap;
 
+    if (format == XYBitmap && leftPad == 0) {
+        if (!(tmp = glamor_expand_bitmap(drawable, gc, w, h, bits)))
+            goto bail;
+
+        bits = tmp->devPrivate.ptr;
+        format = ZPixmap;
+    }
+
     if (format != ZPixmap)
         goto bail;
 
@@ -79,6 +115,10 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     glamor_upload_region(pixmap, &region, x, y, (uint8_t *) bits, byte_stride);
 
     RegionUninit(&region);
+
+    if (tmp)
+        fbDestroyPixmap(tmp);
+
     return TRUE;
 bail:
     return FALSE;
-- 
2.9.3



More information about the xorg-devel mailing list