[mutter] clutter-actor: Cull actors that don't intersect the redraw clip



commit a1dd3c43fbb77e5e4a5ffe92af1a611592543b9e
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Wed Jul 8 17:18:23 2020 +0800

    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

 clutter/clutter/clutter-actor.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 05148e907f..8805b35b11 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;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]