[mutter/wayland] shaped-texture: Move unobscured_region processing here



commit f6db756326e514f4ba02f4e0deb1c435f93ff01e
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Feb 5 14:06:32 2014 -0500

    shaped-texture: Move unobscured_region processing here
    
    We want to remove a bunch of auxilliary duties from the MetaWindowActor
    and MetaSurfaceActor, including some details of how culling is done.
    Move the unobscured region culling code to the MetaShapedTexture, which
    helps the actor become "more independent".
    
    https://bugzilla.gnome.org/show_bug.cgi?id=720631

 src/compositor/meta-shaped-texture-private.h |    3 +
 src/compositor/meta-shaped-texture.c         |  102 +++++++++++++++++++++++---
 src/compositor/meta-surface-actor.c          |   31 +++++---
 src/compositor/meta-surface-actor.h          |   11 ++-
 src/compositor/meta-window-actor.c           |   65 ++---------------
 src/meta/meta-shaped-texture.h               |    3 +-
 src/wayland/meta-wayland-surface.c           |    6 +-
 7 files changed, 127 insertions(+), 94 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index 18d61a7..48ae0df 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -32,5 +32,8 @@
 ClutterActor *meta_shaped_texture_new (void);
 void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
                                       CoglTexture       *texture);
+gboolean meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture     *stex,
+                                                    cairo_rectangle_int_t *unobscured_bounds);
+gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
 
 #endif
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 1424877..3796833 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -73,10 +73,15 @@ struct _MetaShapedTexturePrivate
   CoglTexture *texture;
   CoglTexture *mask_texture;
 
-  cairo_region_t *clip_region;
   cairo_region_t *input_shape_region;
+
+  /* The region containing only fully opaque pixels */
   cairo_region_t *opaque_region;
 
+  /* MetaCullable regions, see that documentation for more details */
+  cairo_region_t *clip_region;
+  cairo_region_t *unobscured_region;
+
   guint tex_width, tex_height;
 
   guint create_mipmaps : 1;
@@ -114,6 +119,21 @@ meta_shaped_texture_init (MetaShapedTexture *self)
 }
 
 static void
+set_unobscured_region (MetaShapedTexture *self,
+                       cairo_region_t    *unobscured_region)
+{
+  MetaShapedTexturePrivate *priv = self->priv;
+
+  g_clear_pointer (&priv->unobscured_region, (GDestroyNotify) cairo_region_destroy);
+  if (unobscured_region)
+    {
+      cairo_rectangle_int_t bounds = { 0, 0, priv->tex_width, priv->tex_height };
+      priv->unobscured_region = cairo_region_copy (unobscured_region);
+      cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
+    }
+}
+
+static void
 set_clip_region (MetaShapedTexture *self,
                  cairo_region_t    *clip_region)
 {
@@ -138,6 +158,7 @@ meta_shaped_texture_dispose (GObject *object)
   g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
 
   meta_shaped_texture_set_mask_texture (self, NULL);
+  set_unobscured_region (self, NULL);
   set_clip_region (self, NULL);
 
   G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
@@ -546,10 +567,37 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self,
 }
 
 static gboolean
-meta_shaped_texture_get_paint_volume (ClutterActor *self,
+meta_shaped_texture_get_paint_volume (ClutterActor *actor,
                                       ClutterPaintVolume *volume)
 {
-  return clutter_paint_volume_set_from_allocation (volume, self);
+  MetaShapedTexture *self = META_SHAPED_TEXTURE (actor);
+  cairo_rectangle_int_t unobscured_bounds;
+
+  if (!clutter_paint_volume_set_from_allocation (volume, actor))
+    return FALSE;
+
+  if (meta_shaped_texture_get_unobscured_bounds (self, &unobscured_bounds))
+    {
+      ClutterVertex origin;
+      cairo_rectangle_int_t bounds;
+
+      /* I hate ClutterPaintVolume so much... */
+      clutter_paint_volume_get_origin (volume, &origin);
+      bounds.x = origin.x;
+      bounds.y = origin.y;
+      bounds.width = clutter_paint_volume_get_width (volume);
+      bounds.height = clutter_paint_volume_get_height (volume);
+
+      gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
+
+      origin.x = bounds.x;
+      origin.y = bounds.y;
+      clutter_paint_volume_set_origin (volume, &origin);
+      clutter_paint_volume_set_width (volume, bounds.width);
+      clutter_paint_volume_set_height (volume, bounds.height);
+    }
+
+  return TRUE;
 }
 
 void
@@ -594,6 +642,41 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
   clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
 }
 
+static cairo_region_t *
+effective_unobscured_region (MetaShapedTexture *self)
+{
+  MetaShapedTexturePrivate *priv = self->priv;
+
+  return clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)) ? NULL : priv->unobscured_region;
+}
+
+gboolean
+meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture     *self,
+                                           cairo_rectangle_int_t *unobscured_bounds)
+{
+  cairo_region_t *unobscured_region = effective_unobscured_region (self);
+
+  if (unobscured_region)
+    {
+      cairo_region_get_extents (unobscured_region, unobscured_bounds);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+gboolean
+meta_shaped_texture_is_obscured (MetaShapedTexture *self)
+{
+  MetaShapedTexturePrivate *priv = self->priv;
+  cairo_region_t *unobscured_region = effective_unobscured_region (self);
+
+  if (unobscured_region)
+    return cairo_region_is_empty (unobscured_region);
+  else
+    return FALSE;
+}
+
 /**
  * meta_shaped_texture_update_area:
  * @stex: #MetaShapedTexture
@@ -601,14 +684,9 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
  * @y: the y coordinate of the damaged area
  * @width: the width of the damaged area
  * @height: the height of the damaged area
- * @unobscured_region: The unobscured region of the window or %NULL if
- * there is no valid one (like when the actor is transformed or
- * has a mapped clone)
  *
  * Repairs the damaged area indicated by @x, @y, @width and @height
- * and queues a redraw for the intersection @unobscured_region and
- * the damage area. If @unobscured_region is %NULL a redraw will always
- * get queued.
+ * and potentially queues a redraw.
  *
  * Return value: Whether a redraw have been queued or not
  */
@@ -617,10 +695,10 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
                                 int                x,
                                 int                y,
                                 int                width,
-                                int                height,
-                                cairo_region_t    *unobscured_region)
+                                int                height)
 {
   MetaShapedTexturePrivate *priv;
+  cairo_region_t *unobscured_region;
   const cairo_rectangle_int_t clip = { x, y, width, height };
 
   priv = stex->priv;
@@ -630,6 +708,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
 
   meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
 
+  unobscured_region = effective_unobscured_region (stex);
   if (unobscured_region)
     {
       cairo_region_t *intersection;
@@ -857,6 +936,7 @@ meta_shaped_texture_cull_out (MetaCullable   *cullable,
   MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable);
   MetaShapedTexturePrivate *priv = self->priv;
 
+  set_unobscured_region (self, unobscured_region);
   set_clip_region (self, clip_region);
 
   if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff)
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 37b87b0..541094c 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -31,6 +31,14 @@ static void cullable_iface_init (MetaCullableInterface *iface);
 G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
                          G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
 
+gboolean
+meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor      *self,
+                                          cairo_rectangle_int_t *unobscured_bounds)
+{
+  MetaSurfaceActorPrivate *priv = self->priv;
+  return meta_shaped_texture_get_unobscured_bounds (priv->texture, unobscured_bounds);
+}
+
 static void
 meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
 {
@@ -109,18 +117,13 @@ update_area (MetaSurfaceActor *self,
 }
 
 gboolean
-meta_surface_actor_damage_all (MetaSurfaceActor *self,
-                               cairo_region_t   *unobscured_region)
+meta_surface_actor_damage_all (MetaSurfaceActor *self)
 {
   MetaSurfaceActorPrivate *priv = self->priv;
   CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture);
 
   update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture));
-  return meta_shaped_texture_update_area (priv->texture,
-                                          0, 0,
-                                          cogl_texture_get_width (texture),
-                                          cogl_texture_get_height (texture),
-                                          unobscured_region);
+  return meta_shaped_texture_update_area (priv->texture, 0, 0, cogl_texture_get_width (texture), 
cogl_texture_get_height (texture));
 }
 
 gboolean
@@ -128,15 +131,19 @@ meta_surface_actor_damage_area (MetaSurfaceActor *self,
                                 int               x,
                                 int               y,
                                 int               width,
-                                int               height,
-                                cairo_region_t   *unobscured_region)
+                                int               height)
 {
   MetaSurfaceActorPrivate *priv = self->priv;
 
   update_area (self, x, y, width, height);
-  return meta_shaped_texture_update_area (priv->texture,
-                                          x, y, width, height,
-                                          unobscured_region);
+  return meta_shaped_texture_update_area (priv->texture, x, y, width, height);
+}
+
+gboolean
+meta_surface_actor_is_obscured (MetaSurfaceActor *self)
+{
+  MetaSurfaceActorPrivate *priv = self->priv;
+  return meta_shaped_texture_is_obscured (priv->texture);
 }
 
 void
diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h
index 484877b..fa7f0c3 100644
--- a/src/compositor/meta-surface-actor.h
+++ b/src/compositor/meta-surface-actor.h
@@ -43,15 +43,16 @@ cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor      *self,
 
 MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
 
-gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self,
-                                        cairo_region_t   *unobscured_region);
-
+gboolean meta_surface_actor_damage_all  (MetaSurfaceActor *self);
 gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self,
                                          int               x,
                                          int               y,
                                          int               width,
-                                         int               height,
-                                         cairo_region_t   *unobscured_region);
+                                         int               height);
+
+gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self);
+gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor      *self,
+                                                   cairo_rectangle_int_t *unobscured_bounds);
 
 void meta_surface_actor_set_texture (MetaSurfaceActor *self,
                                      CoglTexture      *texture);
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 97654f0..60c22e3 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -72,9 +72,6 @@ struct _MetaWindowActorPrivate
   /* The region we should clip to when painting the shadow */
   cairo_region_t   *shadow_clip;
 
-  /* The region that is visible, used to optimize out redraws */
-  cairo_region_t   *unobscured_region;
-
   guint              send_frame_messages_timer;
   gint64             frame_drawn_time;
 
@@ -425,7 +422,6 @@ meta_window_actor_dispose (GObject *object)
       priv->send_frame_messages_timer = 0;
     }
 
-  g_clear_pointer (&priv->unobscured_region, cairo_region_destroy);
   g_clear_pointer (&priv->shape_region, cairo_region_destroy);
   g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
 
@@ -696,7 +692,7 @@ meta_window_actor_get_paint_volume (ClutterActor       *actor,
 {
   MetaWindowActor *self = META_WINDOW_ACTOR (actor);
   MetaWindowActorPrivate *priv = self->priv;
-  cairo_rectangle_int_t bounds;
+  cairo_rectangle_int_t unobscured_bounds, bounds;
   gboolean appears_focused = meta_window_appears_focused (priv->window);
   ClutterVertex origin;
 
@@ -721,12 +717,8 @@ meta_window_actor_get_paint_volume (ClutterActor       *actor,
       gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
     }
 
-  if (priv->unobscured_region && !clutter_actor_has_mapped_clones (actor))
-    {
-      cairo_rectangle_int_t unobscured_bounds;
-      cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds);
-      gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
-    }
+  if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds))
+    gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
 
   origin.x = bounds.x;
   origin.y = bounds.y;
@@ -925,7 +917,6 @@ static void
 meta_window_actor_damage_all (MetaWindowActor *self)
 {
   MetaWindowActorPrivate *priv = self->priv;
-  cairo_region_t *unobscured_region;
   gboolean redraw_queued;
 
   if (!priv->needs_damage_all)
@@ -934,11 +925,7 @@ meta_window_actor_damage_all (MetaWindowActor *self)
   if (!priv->mapped || priv->needs_pixmap)
     return;
 
-  unobscured_region =
-    clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface))
-    ? NULL : priv->unobscured_region;
-
-  redraw_queued = meta_surface_actor_damage_all (priv->surface, unobscured_region);
+  redraw_queued = meta_surface_actor_damage_all (priv->surface);
   priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
   priv->needs_damage_all = FALSE;
 }
@@ -996,17 +983,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
 
   if (!priv->repaint_scheduled)
     {
-      gboolean is_obscured = FALSE;
-
-      /* Find out whether the window is completly obscured */
-      if (priv->unobscured_region)
-        {
-          cairo_region_t *unobscured_window_region;
-          unobscured_window_region = cairo_region_copy (priv->shape_region);
-          cairo_region_intersect (unobscured_window_region, priv->unobscured_region);
-          is_obscured = cairo_region_is_empty (unobscured_window_region);
-          cairo_region_destroy (unobscured_window_region);
-        }
+      gboolean is_obscured = meta_surface_actor_is_obscured (priv->surface);
 
       /* A frame was marked by the client without actually doing any
        * damage or any unobscured, or while we had the window frozen
@@ -1699,30 +1676,6 @@ see_region (cairo_region_t *region,
 #endif
 
 /**
- * meta_window_actor_set_unobscured_region:
- * @self: a #MetaWindowActor
- * @unobscured_region: the region of the screen that isn't completely
- *  obscured.
- *
- * Provides a hint as to what areas of the window need to queue
- * redraws when damaged. Regions not in @unobscured_region are completely obscured.
- */
-static void
-meta_window_actor_set_unobscured_region (MetaWindowActor *self,
-                                         cairo_region_t  *unobscured_region)
-{
-  MetaWindowActorPrivate *priv = self->priv;
-
-  if (priv->unobscured_region)
-    cairo_region_destroy (priv->unobscured_region);
-
-  if (unobscured_region)
-    priv->unobscured_region = cairo_region_copy (unobscured_region);
-  else
-    priv->unobscured_region = NULL;
-}
-
-/**
  * meta_window_actor_set_clip_region_beneath:
  * @self: a #MetaWindowActor
  * @clip_region: the region of the screen that isn't completely
@@ -1772,7 +1725,6 @@ meta_window_actor_cull_out (MetaCullable   *cullable,
   if (priv->unredirected)
     return;
 
-  meta_window_actor_set_unobscured_region (self, unobscured_region);
   meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
   meta_window_actor_set_clip_region_beneath (self, clip_region);
 }
@@ -1949,7 +1901,6 @@ meta_window_actor_process_x11_damage (MetaWindowActor    *self,
   MetaWindowActorPrivate *priv = self->priv;
   MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen);
   gboolean redraw_queued;
-  cairo_region_t *unobscured_region;
 
   priv->received_x11_damage = TRUE;
 
@@ -1997,15 +1948,11 @@ meta_window_actor_process_x11_damage (MetaWindowActor    *self,
   if (!priv->mapped || priv->needs_pixmap)
     return;
 
-  unobscured_region =
-    clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface))
-    ? NULL : priv->unobscured_region;
   redraw_queued = meta_surface_actor_damage_area (priv->surface,
                                                   event->area.x,
                                                   event->area.y,
                                                   event->area.width,
-                                                  event->area.height,
-                                                  unobscured_region);
+                                                  event->area.height);
   priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
 }
 
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
index 9eea4b8..b0870bf 100644
--- a/src/meta/meta-shaped-texture.h
+++ b/src/meta/meta-shaped-texture.h
@@ -69,8 +69,7 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
                                           int                x,
                                           int                y,
                                           int                width,
-                                          int                height,
-                                          cairo_region_t    *unobscured_region);
+                                          int                height);
 
 CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
 
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 909d624..c24645e 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -115,11 +115,7 @@ surface_process_damage (MetaWaylandSurface *surface,
       cairo_rectangle_int_t rect;
       cairo_region_get_rectangle (region, i, &rect);
       meta_surface_actor_damage_area (surface->surface_actor,
-                                      rect.x,
-                                      rect.y,
-                                      rect.width,
-                                      rect.height,
-                                      NULL);
+                                      rect.x, rect.y, rect.width, rect.height);
     }
 }
 


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