[PATCH 5/5] glamor: Optimization to copy area when the source doesn't have an FBO

Michel Dänzer michel at daenzer.net
Wed Apr 23 02:54:45 PDT 2014


From: Anthony Waters <awaters1 at gmail.com>

For instances where the destination has a FBO but the source doesn't,
the code now just puts the data that was in source directly into
destination through glamor_upload_sub_pixmap_to_texture.  This is the
same way that EXA works in this case as well.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71813
Signed-off-by: Anthony Waters <awaters1 at gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 glamor/glamor_copyarea.c | 49 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 36 insertions(+), 13 deletions(-)

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index e198822..143b599 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -130,30 +130,54 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     glamor_pixmap_private *src_pixmap_priv;
     glamor_pixmap_private *dst_pixmap_priv;
     int src_x_off, src_y_off, dst_x_off, dst_y_off;
-    enum glamor_pixmap_status src_status = GLAMOR_NONE;
     GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
 
     src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
     dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
 
+    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+
     if (src_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
-#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
-        glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
-        return FALSE;
-#else
-        src_status = glamor_upload_pixmap_to_texture(src_pixmap);
-        if (src_status != GLAMOR_UPLOAD_DONE)
+        /* Optimize when the source doesn't have an FBO, just upload
+         * the data directly to the dest FBO
+         */
+        int src_stride = src_pixmap->devKind;
+        int bpp = src_pixmap->drawable.bitsPerPixel;
+        void *src_data = NULL;
+        if (src->bitsPerPixel != dst->bitsPerPixel) {
+            DEBUGF("Non-matching bpp\n");
             return FALSE;
-
-        src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
-#endif
+        }
+        if (src->bitsPerPixel < 8) {
+            DEBUGF("bpp < 8\n");
+            return FALSE;
+        }
+        if (gc && !(gc->alu == GXcopy && glamor_pm_is_solid(src, gc->planemask))) {
+            DEBUGF("non gxcopy and solid\n");
+            return FALSE;
+        }
+        for (i = 0; i < nbox; i++) {
+            int x = box[i].x1 + dst_x_off;
+            int y = box[i].y1 + dst_y_off;
+            int w = box[i].x2 - box[i].x1;
+            int h = box[i].y2 - box[i].y1;
+            src_data = (char *)src_pixmap->devPrivate.ptr +
+                (box[i].y1 + dy + src_y_off) * src_stride +
+                (box[i].x1 + dx + src_x_off) * (bpp / 8);
+            if (!glamor_upload_sub_pixmap_to_texture(dst_pixmap,
+                                                     x, y, w, h,
+                                                     src_stride, src_data, 0)) {
+                ErrorF("Failed to upload the sub pixmap to dst\n");
+                return FALSE;
+            }
+        }
+        return TRUE;
     }
 
     pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
     pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
 
-    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
-
     glamor_make_current(glamor_priv);
 
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
@@ -161,7 +185,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
                           GL_FALSE, 2 * sizeof(float), vertices);
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-    glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
     dx += src_x_off;
     dy += src_y_off;
 
-- 
1.9.2



More information about the xorg-devel mailing list