summaryrefslogtreecommitdiff
path: root/glamor
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2017-07-06 15:43:14 -0700
committerEric Anholt <eric@anholt.net>2017-08-14 12:35:55 -0700
commit60cc7e367a2a5e6014f193105dafd47a4d598fd9 (patch)
treede6d67ed954484963f14a5289871e7a5db0b0655 /glamor
parentf2110157713cf22c8b5c46a0d5416fdb033c27d3 (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.c26
-rw-r--r--glamor/glamor_utils.h35
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.