diff options
author | Eric Anholt <eric@anholt.net> | 2017-07-06 15:43:14 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2017-08-14 12:35:55 -0700 |
commit | 60cc7e367a2a5e6014f193105dafd47a4d598fd9 (patch) | |
tree | de6d67ed954484963f14a5289871e7a5db0b0655 /glamor | |
parent | f2110157713cf22c8b5c46a0d5416fdb033c27d3 (diff) |
glamor: Scissor rectangle drawing to the bounds of the rects.
Scissors provide a critical hint to tiled renderers as to what tiles
need to be load/stored because they could be modified by the
rendering.
The bounds calculation here is limited to when we have a small number
of rects (large enough to cover rounded window corners, but probably
not xeyes) to avoid overhead on desktop GL.
No performance difference on i965 with x11perf -rect1 -repeat 1 -reps
10000 (n=50)
v2: Clamp rectangle bounds addition.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'glamor')
-rw-r--r-- | glamor/glamor_rects.c | 26 | ||||
-rw-r--r-- | glamor/glamor_utils.h | 35 |
2 files changed, 57 insertions, 4 deletions
diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c index cc029c8c0..6cbb040c1 100644 --- a/glamor/glamor_rects.c +++ b/glamor/glamor_rects.c @@ -53,6 +53,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable, char *vbo_offset; int box_index; Bool ret = FALSE; + BoxRec bounds = glamor_no_rendering_bounds(); pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) @@ -60,6 +61,12 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable, glamor_make_current(glamor_priv); + if (nrect < 100) { + bounds = glamor_start_rendering_bounds(); + for (int i = 0; i < nrect; i++) + glamor_bounds_union_rect(&bounds, &prect[i]); + } + if (glamor_priv->glsl_version >= 130) { prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_fill_rect_program, @@ -121,11 +128,22 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable, goto bail; while (nbox--) { - glScissor(box->x1 + off_x, - box->y1 + off_y, - box->x2 - box->x1, - box->y2 - box->y1); + BoxRec scissor = { + .x1 = max(box->x1, bounds.x1 + drawable->x), + .y1 = max(box->y1, bounds.y1 + drawable->y), + .x2 = min(box->x2, bounds.x2 + drawable->x), + .y2 = min(box->y2, bounds.y2 + drawable->y), + }; + box++; + + if (scissor.x1 >= scissor.x2 || scissor.y1 >= scissor.y2) + continue; + + glScissor(scissor.x1 + off_x, + scissor.y1 + off_y, + scissor.x2 - scissor.x1, + scissor.y2 - scissor.y1); if (glamor_priv->glsl_version >= 130) glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect); else { diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index a35917c37..f1f8f5633 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -729,6 +729,41 @@ glamor_make_current(glamor_screen_private *glamor_priv) } } +static inline BoxRec +glamor_no_rendering_bounds(void) +{ + BoxRec bounds = { + .x1 = 0, + .y1 = 0, + .x2 = MAXSHORT, + .y2 = MAXSHORT, + }; + + return bounds; +} + +static inline BoxRec +glamor_start_rendering_bounds(void) +{ + BoxRec bounds = { + .x1 = MAXSHORT, + .y1 = MAXSHORT, + .x2 = 0, + .y2 = 0, + }; + + return bounds; +} + +static inline void +glamor_bounds_union_rect(BoxPtr bounds, xRectangle *rect) +{ + bounds->x1 = min(bounds->x1, rect->x); + bounds->y1 = min(bounds->y1, rect->y); + bounds->x2 = min(SHRT_MAX, max(bounds->x2, rect->x + rect->width)); + bounds->y2 = min(SHRT_MAX, max(bounds->y2, rect->y + rect->height)); +} + /** * Helper function for implementing draws with GL_QUADS on GLES2, * where we don't have them. |