summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel van Vugt <daniel.van.vugt@canonical.com>2020-07-08 17:18:23 +0800
committerRobert Mader <robert.mader@posteo.de>2020-08-30 11:49:09 +0000
commita1dd3c43fbb77e5e4a5ffe92af1a611592543b9e (patch)
tree99a6ab91e2b3d5768cae075ce02b69c6d77947fc
parent8e72566fc358cb67a7fdf51eeafb97ae913c728c (diff)
downloadmutter-a1dd3c43fbb77e5e4a5ffe92af1a611592543b9e.tar.gz
clutter-actor: Cull actors that don't intersect the redraw clip
Previously we only culled actors that didn't intersect the bounding box of the redraw clip. Now we also cull those whose paint volume bounds don't intersect the arbitrary shape of the redraw clip. This was inspired by the activities overview where idle windows and workspace previews were being needlessly repainted. In that particular case this yields more than 10% reduction in render time. But it probably helps in other situations too. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1359
-rw-r--r--clutter/clutter/clutter-actor.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 05148e907..8805b35b1 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -3458,6 +3458,43 @@ cull_actor (ClutterActor *self,
*result_out =
_clutter_paint_volume_cull (&priv->last_paint_volume, stage_clip);
+ if (*result_out != CLUTTER_CULL_RESULT_OUT)
+ {
+ const cairo_region_t *redraw_clip;
+
+ redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
+ if (redraw_clip)
+ {
+ ClutterActorBox paint_box;
+ cairo_rectangle_int_t paint_box_bounds;
+ cairo_region_overlap_t overlap;
+
+ _clutter_paint_volume_get_stage_paint_box (&priv->last_paint_volume,
+ stage,
+ &paint_box);
+
+ paint_box_bounds.x = floorf (paint_box.x1);
+ paint_box_bounds.y = floorf (paint_box.y1);
+ paint_box_bounds.width = ceilf (paint_box.x2 - paint_box_bounds.x);
+ paint_box_bounds.height = ceilf (paint_box.y2 - paint_box_bounds.y);
+
+ overlap = cairo_region_contains_rectangle (redraw_clip,
+ &paint_box_bounds);
+ switch (overlap)
+ {
+ case CAIRO_REGION_OVERLAP_IN:
+ *result_out = CLUTTER_CULL_RESULT_IN;
+ break;
+ case CAIRO_REGION_OVERLAP_PART:
+ *result_out = CLUTTER_CULL_RESULT_PARTIAL;
+ break;
+ case CAIRO_REGION_OVERLAP_OUT:
+ *result_out = CLUTTER_CULL_RESULT_OUT;
+ break;
+ }
+ }
+ }
+
return TRUE;
}