[mutter/wip/cb2eb3: 33/55] window-actor: Use MetaRegionBuilder when scanning the visible region



commit 865b9df9a99870d72b59bc42ce12177c5f4cd342
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sun Apr 29 07:10:15 2012 -0400

    window-actor: Use MetaRegionBuilder when scanning the visible region
    
    This gives a pretty solid performance improvement when resizing windows.

 src/compositor/meta-window-actor.c |   23 ++++++++++++++---------
 src/compositor/region-utils.c      |   23 ++++-------------------
 src/compositor/region-utils.h      |   28 ++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 28 deletions(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index b9932d4..5c655a4 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -26,6 +26,7 @@
 #include "meta-shadow-factory-private.h"
 #include "meta-window-actor-private.h"
 #include "meta-texture-rectangle.h"
+#include "region-utils.h"
 
 enum {
   POSITION_CHANGED,
@@ -2006,14 +2007,15 @@ meta_window_actor_sync_visibility (MetaWindowActor *self)
     }
 }
 
-static void
+static cairo_region_t *
 scan_visible_region (guchar         *mask_data,
                      int             stride,
-                     cairo_region_t *scan_area,
-                     cairo_region_t *union_against)
+                     cairo_region_t *scan_area)
 {
-  int i, n_rects;
-  n_rects = cairo_region_num_rectangles (scan_area);
+  int i, n_rects = cairo_region_num_rectangles (scan_area);
+  MetaRegionBuilder builder;
+
+  meta_region_builder_init (&builder);
 
   for (i = 0; i < n_rects; i++)
     {
@@ -2032,13 +2034,14 @@ scan_visible_region (guchar         *mask_data,
 
               if (w > 0)
                 {
-                  cairo_rectangle_int_t tmp = { x, y, w - x, 1 };
-                  cairo_region_union_rectangle (union_against, &tmp);
+                  meta_region_builder_add_rectangle (&builder, x, y, w - x, 1);
                   x = w;
                 }
             }
         }
     }
+
+  return meta_region_builder_finish (&builder);
 }
 
 static void
@@ -2078,7 +2081,7 @@ build_and_scan_frame_mask (MetaWindowActor       *self,
 
   if (priv->window->frame != NULL)
     {
-      cairo_region_t *frame_paint_region;
+      cairo_region_t *frame_paint_region, *scanned_region;
       cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
 
       /* Make sure we don't paint the frame over the client window. */
@@ -2099,7 +2102,9 @@ build_and_scan_frame_mask (MetaWindowActor       *self,
       cairo_paint (cr);
 
       cairo_surface_flush (surface);
-      scan_visible_region (mask_data, stride, frame_paint_region, shape_region);
+      scanned_region = scan_visible_region (mask_data, stride, frame_paint_region);
+      cairo_region_union (shape_region, scanned_region);
+      cairo_region_destroy (scanned_region);
     }
 
   cairo_destroy (cr);
diff --git a/src/compositor/region-utils.c b/src/compositor/region-utils.c
index cf3c64e..8139952 100644
--- a/src/compositor/region-utils.c
+++ b/src/compositor/region-utils.c
@@ -43,25 +43,10 @@
 /* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower.
  * But using 8 may be more robust to systems with slow malloc(). */
 #define MAX_CHUNK_RECTANGLES 8
+/* XXX: keep in sync with region-utils.h */
 #define MAX_LEVELS 16
 
-typedef struct
-{
-  /* To merge regions in binary tree order, we need to keep track of
-   * the regions that we've already merged together at different
-   * levels of the tree. We fill in an array in the pattern:
-   *
-   * |a  |
-   * |b  |a  |
-   * |c  |   |ab |
-   * |d  |c  |ab |
-   * |e  |   |   |abcd|
-   */
-  cairo_region_t *levels[MAX_LEVELS];
-  int n_levels;
-} MetaRegionBuilder;
-
-static void
+void
 meta_region_builder_init (MetaRegionBuilder *builder)
 {
   int i;
@@ -70,7 +55,7 @@ meta_region_builder_init (MetaRegionBuilder *builder)
   builder->n_levels = 1;
 }
 
-static void
+void
 meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
                                    int                x,
                                    int                y,
@@ -115,7 +100,7 @@ meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
     }
 }
 
-static cairo_region_t *
+cairo_region_t *
 meta_region_builder_finish (MetaRegionBuilder *builder)
 {
   cairo_region_t *result = NULL;
diff --git a/src/compositor/region-utils.h b/src/compositor/region-utils.h
index d20105c..2265881 100644
--- a/src/compositor/region-utils.h
+++ b/src/compositor/region-utils.h
@@ -63,6 +63,34 @@ struct _MetaRegionIterator {
   cairo_rectangle_int_t next_rectangle;
 };
 
+typedef struct _MetaRegionBuilder MetaRegionBuilder;
+
+/* XXX: keep in sync with region-utils.c */
+#define MAX_LEVELS 16
+struct _MetaRegionBuilder {
+  /* To merge regions in binary tree order, we need to keep track of
+   * the regions that we've already merged together at different
+   * levels of the tree. We fill in an array in the pattern:
+   *
+   * |a  |
+   * |b  |a  |
+   * |c  |   |ab |
+   * |d  |c  |ab |
+   * |e  |   |   |abcd|
+   */
+  cairo_region_t *levels[MAX_LEVELS];
+  int n_levels;
+};
+#undef MAX_LEVELS
+
+void     meta_region_builder_init       (MetaRegionBuilder *builder);
+void     meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
+                                            int                x,
+                                            int                y,
+                                            int                width,
+                                            int                height);
+cairo_region_t * meta_region_builder_finish (MetaRegionBuilder *builder);
+
 void     meta_region_iterator_init      (MetaRegionIterator *iter,
                                          cairo_region_t     *region);
 gboolean meta_region_iterator_at_end    (MetaRegionIterator *iter);


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