From e6ab3b1109e72a1512c6b7b92dd84525ad8c8052 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 6 Jul 2017 16:15:17 -0700 Subject: [PATCH] glamor: Scissor CopyArea to the bounds of the drawing. 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). v2: Drop extra glamor_bounds_union_box() from previous debugging (caught by Mark Marshall). Signed-off-by: Eric Anholt Reviewed-by: Keith Packard (v1) --- glamor/glamor_copy.c | 25 +++++++++++++++++++++---- glamor/glamor_utils.h | 9 +++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c index f7d6eb163..cbaf06ddd 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,18 @@ 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; + v += 8; box++; } @@ -417,15 +425,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 f1f8f5633..6e9d88674 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 = min(SHRT_MAX, 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.