From 0164c2ddfd8a46eddf55e89a5b5e28c4bdc450f9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 30 Sep 2016 22:44:01 -0700 Subject: [PATCH] glamor: Accelerate up XY pixmap putimage a little 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 --- glamor/glamor_image.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c index 54db9d0ed..343fa53f5 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))