[mutter/wip/chergert/reduce-region-allocs] cogl: reduce temporary allocations calculating redraw regions



commit d35bf06b25bed259866d23e746c29510e5ea0721
Author: Christian Hergert <chergert redhat com>
Date:   Wed Feb 19 17:34:49 2020 -0800

    cogl: reduce temporary allocations calculating redraw regions
    
    When calculating regions, a lot of temporary allocations are created. For
    the array of rects (which is often a short number of them) we can use
    stack allocations up to 1 page (256 cairo_rectangle_int_t). For building
    a region of rectangles, cairo and pixman are much faster if you have all
    of the rectangles up front or else it mallocs quite a bit of temporary
    memory.
    
    If we re-use the cairo_rectangle_int_t array we've already allocated (and
    preferably on the stack), we can delay the creation of regions until after
    the tight loop.
    
    Additionally, it requires fewer allocations to union to cairo_region_t than
    to incrementally union the rectangles into the region.
    
    Before (percentages are of total number of allocations)
    
         TOTAL    FUNCTION
    [ 100.00%]    [Everything]
    [ 100.00%]      [gnome-shell --wayland --display-server]
    [  99.67%]        _start
    [  99.67%]          __libc_start_main
    [  99.67%]            main
    [  98.60%]              meta_run
    [  96.90%]                g_main_loop_run
    [  96.90%]                  g_main_context_iterate.isra.0
    [  96.90%]                    g_main_context_dispatch
    [  90.27%]                      clutter_clock_dispatch
    [  86.54%]                        _clutter_stage_do_update
    [  85.00%]                          clutter_stage_cogl_redraw
    [  84.98%]                            clutter_stage_cogl_redraw_view
    [  81.09%]                              cairo_region_union_rectangle
    
    After (overhead has much dropped)
    
         TOTAL    FUNCTION
    [ 100.00%]    [Everything]
    [  99.80%]      [gnome-shell --wayland --display-server]
    [  99.48%]        _start
    [  99.48%]          __libc_start_main
    [  99.48%]            main
    [  92.37%]              meta_run
    [  81.49%]                g_main_loop_run
    [  81.49%]                  g_main_context_iterate.isra.0
    [  81.43%]                    g_main_context_dispatch
    [  39.40%]                      clutter_clock_dispatch
    [  26.93%]                        _clutter_stage_do_update
    [  25.80%]                          clutter_stage_cogl_redraw
    [  25.60%]                            clutter_stage_cogl_redraw_view

 clutter/clutter/cogl/clutter-stage-cogl.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)
---
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 9b26d5553..ae58eafdc 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -742,10 +742,9 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 
       may_use_clipped_redraw = TRUE;
 
-      fb_clip_region = cairo_region_create ();
-
       n_rects = cairo_region_num_rectangles (redraw_clip);
-      rects = g_new (cairo_rectangle_int_t, n_rects);
+      rects = n_rects < 256 ? g_newa (cairo_rectangle_int_t, n_rects) :
+                              g_new (cairo_rectangle_int_t, n_rects);
       for (i = 0; i < n_rects; i++)
         {
           cairo_rectangle_int_t new_fb_clip_rect;
@@ -756,9 +755,14 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
           graphene_rect_offset (&rect, -view_rect.x, -view_rect.y);
           scale_and_clamp_rect (&rect, fb_scale, &new_fb_clip_rect);
 
-          cairo_region_union_rectangle (fb_clip_region, &new_fb_clip_rect);
+          rects[i] = new_fb_clip_rect;
         }
-      g_free (rects);
+      if (n_rects == 0)
+        fb_clip_region = cairo_region_create ();
+      else
+        fb_clip_region = cairo_region_create_rectangles (rects, n_rects);
+      if (n_rects >= 256)
+        g_free (rects);
 
       if (fb_scale != floorf (fb_scale))
         {
@@ -808,6 +812,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
               graphene_rect_t rect;
               cairo_rectangle_int_t damage_region;
               cairo_rectangle_int_t *rects;
+              cairo_region_t *add_clip;
               int n_rects, i;
 
               fill_current_damage_history (view, fb_clip_region);
@@ -831,9 +836,11 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
                                                   view_rect.x,
                                                   view_rect.y,
                                                   &damage_region);
-                  cairo_region_union_rectangle (stage_cogl->redraw_clip,
-                                                &damage_region);
+                  rects[i] = damage_region;
                 }
+              add_clip = cairo_region_create_rectangles (rects, n_rects);
+              cairo_region_union (stage_cogl->redraw_clip, add_clip);
+              cairo_region_destroy (add_clip);
 
               CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
                             age,


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