[PATCH xserver 2/3] glamor: Scissor CopyArea to the bounds of the drawing.

Eric Anholt eric at anholt.net
Tue Aug 1 20:59:14 UTC 2017


Like the previous fix to rectangles, this reduces the area drawn on
tiled renderers by letting the CPU-side tile setup know what tiles
might be drawn at all.

Surprisingly, it improves x11perf -copypixwin1 -repeat 1 -reps 10000
on i965 by 2.93185% +/- 1.5561% (n=90).

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 glamor/glamor_copy.c  | 27 +++++++++++++++++++++++----
 glamor/glamor_utils.h |  9 +++++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index f7d6eb163fac..3296b7b1bf75 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -351,6 +351,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
     const glamor_facet *copy_facet;
     int n;
     Bool ret = FALSE;
+    BoxRec bounds = glamor_no_rendering_bounds();
 
     glamor_make_current(glamor_priv);
 
@@ -391,11 +392,20 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
                           2 * sizeof (GLshort), vbo_offset);
 
+    if (nbox < 100) {
+        bounds = glamor_start_rendering_bounds();
+        for (int i = 0; i < nbox; i++)
+            glamor_bounds_union_box(&bounds, &box[i]);
+    }
+
     for (n = 0; n < nbox; n++) {
         v[0] = box->x1; v[1] = box->y1;
         v[2] = box->x1; v[3] = box->y2;
         v[4] = box->x2; v[5] = box->y2;
         v[6] = box->x2; v[7] = box->y1;
+
+        glamor_bounds_union_box(&bounds, box);
+
         v += 8;
         box++;
     }
@@ -417,15 +427,24 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
             goto bail_ctx;
 
         glamor_pixmap_loop(dst_priv, dst_box_index) {
+            BoxRec scissor = {
+                .x1 = max(-args.dx, bounds.x1),
+                .y1 = max(-args.dy, bounds.y1),
+                .x2 = min(-args.dx + src_box->x2 - src_box->x1, bounds.x2),
+                .y2 = min(-args.dy + src_box->y2 - src_box->y1, bounds.y2),
+            };
+            if (scissor.x1 >= scissor.x2 || scissor.y1 >= scissor.y2)
+                continue;
+
             if (!glamor_set_destination_drawable(dst, dst_box_index, FALSE, FALSE,
                                                  prog->matrix_uniform,
                                                  &dst_off_x, &dst_off_y))
                 goto bail_ctx;
 
-            glScissor(dst_off_x - args.dx,
-                      dst_off_y - args.dy,
-                      src_box->x2 - src_box->x1,
-                      src_box->y2 - src_box->y1);
+            glScissor(scissor.x1 + dst_off_x,
+                      scissor.y1 + dst_off_y,
+                      scissor.x2 - scissor.x1,
+                      scissor.y2 - scissor.y1);
 
             glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
         }
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 824be1a09338..81df944b38ba 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -764,6 +764,15 @@ glamor_bounds_union_rect(BoxPtr bounds, xRectangle *rect)
     bounds->y2 = max(bounds->y2, rect->y + rect->height);
 }
 
+static inline void
+glamor_bounds_union_box(BoxPtr bounds, BoxPtr box)
+{
+    bounds->x1 = min(bounds->x1, box->x1);
+    bounds->y1 = min(bounds->y1, box->y1);
+    bounds->x2 = max(bounds->x2, box->x2);
+    bounds->y2 = max(bounds->y2, box->y2);
+}
+
 /**
  * Helper function for implementing draws with GL_QUADS on GLES2,
  * where we don't have them.
-- 
2.13.3



More information about the xorg-devel mailing list