[mutter] Port MetaShapedTexture/MetaWindowActor to use cairo regions instead of XRects



commit 65e1b416effbc625b1046fd38644f66a9964aaeb
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Jul 8 15:06:13 2011 -0400

    Port MetaShapedTexture/MetaWindowActor to use cairo regions instead of XRects
    
    https://bugzilla.gnome.org/show_bug.cgi?id=644930

 src/compositor/meta-shaped-texture.c |   84 ++++++++++++----------------------
 src/compositor/meta-shaped-texture.h |    9 +---
 src/compositor/meta-window-actor.c   |   41 ++++++++++------
 3 files changed, 57 insertions(+), 77 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index fa6d5f2..58a04a7 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -34,7 +34,6 @@
 #include <string.h>
 
 static void meta_shaped_texture_dispose  (GObject    *object);
-static void meta_shaped_texture_finalize (GObject    *object);
 static void meta_shaped_texture_notify   (GObject    *object,
 					  GParamSpec *pspec);
 
@@ -65,11 +64,10 @@ struct _MetaShapedTexturePrivate
   CoglHandle material_unshaped;
 
   cairo_region_t *clip_region;
+  cairo_region_t *shape_region;
 
   guint mask_width, mask_height;
 
-  GArray *rectangles;
-
   guint create_mipmaps : 1;
 };
 
@@ -81,7 +79,6 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
   ClutterX11TexturePixmapClass *x11_texture_class = (ClutterX11TexturePixmapClass *) klass;
 
   gobject_class->dispose = meta_shaped_texture_dispose;
-  gobject_class->finalize = meta_shaped_texture_finalize;
   gobject_class->notify = meta_shaped_texture_notify;
 
   actor_class->paint = meta_shaped_texture_paint;
@@ -99,8 +96,7 @@ meta_shaped_texture_init (MetaShapedTexture *self)
 
   priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
 
-  priv->rectangles = g_array_new (FALSE, FALSE, sizeof (XRectangle));
-
+  priv->shape_region = NULL;
   priv->paint_tower = meta_texture_tower_new ();
   priv->mask_texture = COGL_INVALID_HANDLE;
   priv->create_mipmaps = TRUE;
@@ -129,23 +125,13 @@ meta_shaped_texture_dispose (GObject *object)
       priv->material_unshaped = COGL_INVALID_HANDLE;
     }
 
+  meta_shaped_texture_set_shape_region (self, NULL);
   meta_shaped_texture_set_clip_region (self, NULL);
 
   G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
 }
 
 static void
-meta_shaped_texture_finalize (GObject *object)
-{
-  MetaShapedTexture *self = (MetaShapedTexture *) object;
-  MetaShapedTexturePrivate *priv = self->priv;
-
-  g_array_free (priv->rectangles, TRUE);
-
-  G_OBJECT_CLASS (meta_shaped_texture_parent_class)->finalize (object);
-}
-
-static void
 meta_shaped_texture_notify (GObject    *object,
 			    GParamSpec *pspec)
 {
@@ -210,19 +196,23 @@ meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
   if (priv->mask_texture == COGL_INVALID_HANDLE)
     {
       guchar *mask_data;
-      const XRectangle *rect;
+      int i;
+      int n_rects;
       GLenum paint_gl_target;
 
       /* Create data for an empty image */
       mask_data = g_malloc0 (tex_width * tex_height);
 
-      /* Cut out a hole for each rectangle */
-      for (rect = (XRectangle *) priv->rectangles->data
-             + priv->rectangles->len;
-           rect-- > (XRectangle *) priv->rectangles->data;)
+      n_rects = cairo_region_num_rectangles (priv->shape_region);
+
+      /* Fill in each rectangle. */
+      for (i = 0; i < n_rects; i ++)
         {
-          gint x1 = rect->x, x2 = x1 + rect->width;
-          gint y1 = rect->y, y2 = y1 + rect->height;
+          cairo_rectangle_int_t rect;
+          cairo_region_get_rectangle (priv->shape_region, i, &rect);
+
+          gint x1 = rect.x, x2 = x1 + rect.width;
+          gint y1 = rect.y, y2 = y1 + rect.height;
           guchar *p;
 
           /* Clip the rectangle to the size of the texture */
@@ -321,9 +311,9 @@ meta_shaped_texture_paint (ClutterActor *actor)
   if (tex_width == 0 || tex_height == 0) /* no contents yet */
     return;
 
-  if (priv->rectangles->len < 1)
+  if (priv->shape_region == NULL)
     {
-      /* If there are no rectangles use a single-layer texture */
+      /* No region means an unclipped shape. Use a single-layer texture. */
 
       if (priv->material_unshaped == COGL_INVALID_HANDLE) 
         {
@@ -423,8 +413,8 @@ meta_shaped_texture_pick (ClutterActor       *actor,
   MetaShapedTexture *stex = (MetaShapedTexture *) actor;
   MetaShapedTexturePrivate *priv = stex->priv;
 
-  /* If there are no rectangles then use the regular pick */
-  if (priv->rectangles->len < 1)
+  /* If there is no region then use the regular pick */
+  if (priv->shape_region == NULL)
     CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)
       ->pick (actor, color);
   else if (clutter_actor_should_pick_paint (actor))
@@ -544,7 +534,8 @@ meta_shaped_texture_clear (MetaShapedTexture *stex)
 }
 
 void
-meta_shaped_texture_clear_rectangles (MetaShapedTexture *stex)
+meta_shaped_texture_set_shape_region (MetaShapedTexture *stex,
+                                      cairo_region_t    *region)
 {
   MetaShapedTexturePrivate *priv;
 
@@ -552,32 +543,17 @@ meta_shaped_texture_clear_rectangles (MetaShapedTexture *stex)
 
   priv = stex->priv;
 
-  g_array_set_size (priv->rectangles, 0);
-  meta_shaped_texture_dirty_mask (stex);
-  clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
-}
-
-void
-meta_shaped_texture_add_rectangle (MetaShapedTexture *stex,
-				   const XRectangle  *rect)
-{
-  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
-  meta_shaped_texture_add_rectangles (stex, 1, rect);
-}
-
-void
-meta_shaped_texture_add_rectangles (MetaShapedTexture *stex,
-				    size_t             num_rects,
-				    const XRectangle  *rects)
-{
-  MetaShapedTexturePrivate *priv;
-
-  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
-  priv = stex->priv;
+  if (priv->shape_region != NULL)
+    {
+      cairo_region_destroy (priv->shape_region);
+      priv->shape_region = NULL;
+    }
 
-  g_array_append_vals (priv->rectangles, rects, num_rects);
+  if (region != NULL)
+    {
+      cairo_region_reference (region);
+      priv->shape_region = region;
+    }
 
   meta_shaped_texture_dirty_mask (stex);
   clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
diff --git a/src/compositor/meta-shaped-texture.h b/src/compositor/meta-shaped-texture.h
index be53268..e27d65f 100644
--- a/src/compositor/meta-shaped-texture.h
+++ b/src/compositor/meta-shaped-texture.h
@@ -65,13 +65,8 @@ void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
 
 void meta_shaped_texture_clear (MetaShapedTexture *stex);
 
-void meta_shaped_texture_clear_rectangles (MetaShapedTexture *stex);
-
-void meta_shaped_texture_add_rectangle  (MetaShapedTexture *stex,
-					 const XRectangle  *rect);
-void meta_shaped_texture_add_rectangles (MetaShapedTexture *stex,
-					 size_t             num_rects,
-					 const XRectangle  *rects);
+void meta_shaped_texture_set_shape_region (MetaShapedTexture *stex,
+                                           cairo_region_t    *region);
 
 /* Assumes ownership of clip_region */
 void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index da0daf0..ea6c690 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1701,20 +1701,15 @@ meta_window_actor_update_bounding_region (MetaWindowActor *self,
 
 static void
 meta_window_actor_update_shape_region (MetaWindowActor *self,
-                                       int              n_rects,
-                                       XRectangle      *rects)
+                                       cairo_region_t  *region)
 {
   MetaWindowActorPrivate *priv = self->priv;
-  int i;
 
   meta_window_actor_clear_shape_region (self);
 
-  priv->shape_region = cairo_region_create ();
-  for (i = 0; i < n_rects; i++)
-    {
-      cairo_rectangle_int_t rect = { rects[i].x, rects[i].y, rects[i].width, rects[i].height };
-      cairo_region_union_rectangle (priv->shape_region, &rect);
-    }
+  /* region must be non-null */
+  priv->shape_region = region;
+  cairo_region_reference (region);
 
   /* Our "shape_region" is called the "bounding region" in the X Shape
    * Extension Documentation.
@@ -2106,12 +2101,12 @@ check_needs_reshape (MetaWindowActor *self)
   MetaWindowActorPrivate *priv = self->priv;
   MetaScreen *screen = priv->screen;
   MetaDisplay *display = meta_screen_get_display (screen);
+  cairo_region_t *region;
 
   if (!priv->needs_reshape)
     return;
 
-  meta_shaped_texture_clear_rectangles (META_SHAPED_TEXTURE (priv->actor));
-  meta_window_actor_clear_shape_region (self);
+  region = NULL;
 
 #ifdef HAVE_SHAPE
   if (priv->shaped)
@@ -2130,16 +2125,30 @@ check_needs_reshape (MetaWindowActor *self)
 
       if (rects)
         {
-          meta_shaped_texture_add_rectangles (META_SHAPED_TEXTURE (priv->actor),
-                                              n_rects, rects);
-
-          meta_window_actor_update_shape_region (self, n_rects, rects);
-
+          int i;
+
+          region = cairo_region_create ();
+
+          for (i = 0; i < n_rects; i ++)
+            {
+              cairo_rectangle_int_t rect = { rects[i].x,
+                                             rects[i].y,
+                                             rects[i].width,
+                                             rects[i].height };
+              cairo_region_union_rectangle (region, &rect);
+            }
           XFree (rects);
         }
     }
 #endif
 
+  meta_shaped_texture_set_shape_region (META_SHAPED_TEXTURE (priv->actor),
+                                        region);
+
+  meta_window_actor_update_shape_region (self, region);
+
+  cairo_region_destroy (region);
+
   priv->needs_reshape = FALSE;
   meta_window_actor_invalidate_shadow (self);
 }



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