[mutter/gbsneto/content: 8/12] shaped-texture: Move MetaCullable helpers to MetaSurfaceActor



commit 0eaa0b9cb507d6612bcec80be0a966807143309c
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Jan 29 19:53:50 2019 -0200

    shaped-texture: Move MetaCullable helpers to MetaSurfaceActor
    
    Now that MetaShapedTexture is not a ClutterActor anymore, it does
    not make sense to make it a MetaCullable semi-implementation. This
    is, naturally, a responsibility of MetaSurfaceActor, since now
    MetaShapedTexture is a ClutterContent and as such, it only cares
    about what to draw.
    
    Move the MetaCullable implementation of MetaShapedTexture to
    MetaSurfaceActor.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/409

 src/compositor/meta-shaped-texture-private.h |   6 -
 src/compositor/meta-shaped-texture.c         | 195 ++++-----------------------
 src/compositor/meta-surface-actor.c          | 146 ++++++++++++++++++--
 src/meta/meta-shaped-texture.h               |  11 +-
 4 files changed, 171 insertions(+), 187 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index 42458daa2..6839b0872 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -40,7 +40,6 @@ void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
 void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
                                             int                fallback_width,
                                             int                fallback_height);
-gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
 cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex);
 void meta_shaped_texture_set_transform (MetaShapedTexture    *stex,
                                         MetaMonitorTransform  transform);
@@ -51,11 +50,6 @@ void meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex,
                                                 int                dst_width,
                                                 int                dst_height);
 void meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex);
-void meta_shaped_texture_cull_out (MetaShapedTexture *stex,
-                                   cairo_region_t    *unobscured_region,
-                                   cairo_region_t    *clip_region,
-                                   uint8_t            opacity);
-void meta_shaped_texture_reset_culling (MetaShapedTexture *stex);
 void meta_shaped_texture_set_buffer_scale (MetaShapedTexture *stex,
                                            int                buffer_scale);
 int meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex);
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index c98aba954..235d54862 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -88,10 +88,6 @@ struct _MetaShapedTexture
   /* 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;
-
   gboolean size_invalid;
   MetaMonitorTransform transform;
   gboolean has_viewport_src_rect;
@@ -220,34 +216,6 @@ ensure_size_valid (MetaShapedTexture *stex)
     update_size (stex);
 }
 
-static void
-set_unobscured_region (MetaShapedTexture *stex,
-                       cairo_region_t    *unobscured_region)
-{
-  g_clear_pointer (&stex->unobscured_region, cairo_region_destroy);
-  if (unobscured_region)
-    {
-      int width, height;
-
-      ensure_size_valid (stex);
-      width = stex->dst_width;
-      height = stex->dst_height;
-
-      cairo_rectangle_int_t bounds = { 0, 0, width, height };
-      stex->unobscured_region = cairo_region_copy (unobscured_region);
-      cairo_region_intersect_rectangle (stex->unobscured_region, &bounds);
-    }
-}
-
-static void
-set_clip_region (MetaShapedTexture *stex,
-                 cairo_region_t    *clip_region)
-{
-  g_clear_pointer (&stex->clip_region, cairo_region_destroy);
-  if (clip_region)
-    stex->clip_region = cairo_region_copy (clip_region);
-}
-
 static void
 meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
 {
@@ -272,12 +240,8 @@ meta_shaped_texture_dispose (GObject *object)
   stex->paint_tower = NULL;
 
   g_clear_pointer (&stex->texture, cogl_object_unref);
-  g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
 
   meta_shaped_texture_set_mask_texture (stex, NULL);
-  set_unobscured_region (stex, NULL);
-  set_clip_region (stex, NULL);
-
   meta_shaped_texture_reset_pipelines (stex);
 
   g_clear_pointer (&stex->snippet, cogl_object_unref);
@@ -544,12 +508,6 @@ texture_is_idle_and_not_mipmapped (gpointer user_data)
   return G_SOURCE_REMOVE;
 }
 
-static cairo_region_t *
-effective_unobscured_region (MetaShapedTexture *stex)
-{
-  return stex->unobscured_region;
-}
-
 static void
 do_paint_content (MetaShapedTexture *stex,
                   ClutterPaintNode  *root_node,
@@ -561,7 +519,6 @@ do_paint_content (MetaShapedTexture *stex,
   int dst_width, dst_height;
   cairo_rectangle_int_t tex_rect;
   gboolean use_opaque_region;
-  cairo_region_t *clip_tex_region;
   cairo_region_t *blended_tex_region;
   CoglContext *ctx;
   CoglPipelineFilter filter;
@@ -591,31 +548,14 @@ do_paint_content (MetaShapedTexture *stex,
 
   use_opaque_region = stex->opaque_region && opacity == 255;
 
-  if (stex->clip_region)
-    {
-      clip_tex_region =
-        meta_region_scale (stex->clip_region, META_ROUNDING_STRATEGY_GROW);
-    }
-  else
-    {
-      clip_tex_region = NULL;
-    }
-
   if (use_opaque_region)
     {
-      if (clip_tex_region)
-        blended_tex_region = cairo_region_copy (clip_tex_region);
-      else
-        blended_tex_region = cairo_region_create_rectangle (&tex_rect);
-
+      blended_tex_region = cairo_region_create_rectangle (&tex_rect);
       cairo_region_subtract (blended_tex_region, stex->opaque_region);
     }
   else
     {
-      if (clip_tex_region)
-        blended_tex_region = cairo_region_reference (clip_tex_region);
-      else
-        blended_tex_region = NULL;
+      blended_tex_region = NULL;
     }
 
   /* Limit to how many separate rectangles we'll draw; beyond this just
@@ -637,21 +577,10 @@ do_paint_content (MetaShapedTexture *stex,
   /* First, paint the unblended parts, which are part of the opaque region. */
   if (use_opaque_region)
     {
-      cairo_region_t *region;
       int n_rects;
       int i;
 
-      if (clip_tex_region)
-        {
-          region = cairo_region_copy (clip_tex_region);
-          cairo_region_intersect (region, stex->opaque_region);
-        }
-      else
-        {
-          region = cairo_region_reference (stex->opaque_region);
-        }
-
-      if (!cairo_region_is_empty (region))
+      if (!cairo_region_is_empty (stex->opaque_region))
         {
           CoglPipeline *opaque_pipeline;
 
@@ -659,18 +588,16 @@ do_paint_content (MetaShapedTexture *stex,
           cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
           cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
 
-          n_rects = cairo_region_num_rectangles (region);
+          n_rects = cairo_region_num_rectangles (stex->opaque_region);
           for (i = 0; i < n_rects; i++)
             {
               cairo_rectangle_int_t rect;
-              cairo_region_get_rectangle (region, i, &rect);
+              cairo_region_get_rectangle (stex->opaque_region, i, &rect);
               paint_clipped_rectangle_node (stex, root_node,
                                             opaque_pipeline,
                                             &rect, alloc);
             }
         }
-
-      cairo_region_destroy (region);
     }
 
   /* Now, go ahead and paint the blended parts. */
@@ -737,7 +664,6 @@ do_paint_content (MetaShapedTexture *stex,
         }
     }
 
-  g_clear_pointer (&clip_tex_region, cairo_region_destroy);
   g_clear_pointer (&blended_tex_region, cairo_region_destroy);
 }
 
@@ -791,9 +717,6 @@ meta_shaped_texture_paint_content (ClutterContent   *content,
   CoglTexture *paint_tex = NULL;
   uint8_t opacity;
 
-  if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
-    return;
-
   /* The GL EXT_texture_from_pixmap extension does allow for it to be
    * used together with SGIS_generate_mipmap, however this is very
    * rarely supported. Also, even when it is supported there
@@ -878,17 +801,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
   clutter_content_invalidate (CLUTTER_CONTENT (stex));
 }
 
-gboolean
-meta_shaped_texture_is_obscured (MetaShapedTexture *stex)
-{
-  cairo_region_t *unobscured_region = effective_unobscured_region (stex);
-
-  if (unobscured_region)
-    return cairo_region_is_empty (unobscured_region);
-  else
-    return FALSE;
-}
-
 /**
  * meta_shaped_texture_update_area:
  * @stex: #MetaShapedTexture
@@ -896,6 +808,7 @@ meta_shaped_texture_is_obscured (MetaShapedTexture *stex)
  * @y: the y coordinate of the damaged area
  * @width: the width of the damaged area
  * @height: the height of the damaged area
+ * @clip: (out): the resulting clip region
  *
  * Repairs the damaged area indicated by @x, @y, @width and @height
  * and potentially queues a redraw.
@@ -903,33 +816,37 @@ meta_shaped_texture_is_obscured (MetaShapedTexture *stex)
  * Return value: Whether a redraw have been queued or not
  */
 gboolean
-meta_shaped_texture_update_area (MetaShapedTexture *stex,
-                                 int                x,
-                                 int                y,
-                                 int                width,
-                                 int                height)
+meta_shaped_texture_update_area (MetaShapedTexture     *stex,
+                                 int                    x,
+                                 int                    y,
+                                 int                    width,
+                                 int                    height,
+                                 cairo_rectangle_int_t *clip)
 {
-  cairo_region_t *unobscured_region;
-  cairo_rectangle_int_t clip;
   MetaMonitorTransform inverted_transform;
 
   if (stex->texture == NULL)
     return FALSE;
 
-  clip = (cairo_rectangle_int_t) {
+  *clip = (cairo_rectangle_int_t) {
     .x = x,
     .y = y,
     .width = width,
     .height = height
   };
 
+  meta_rectangle_scale_double (clip,
+                               1.0 / stex->buffer_scale,
+                               META_ROUNDING_STRATEGY_SHRINK,
+                               clip);
+
   inverted_transform = meta_monitor_transform_invert (stex->transform);
   ensure_size_valid (stex);
-  meta_rectangle_transform (&clip,
+  meta_rectangle_transform (clip,
                             inverted_transform,
                             stex->dst_width,
                             stex->dst_height,
-                            &clip);
+                            clip);
 
   if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
     {
@@ -974,18 +891,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
       inverted_dst_width = ceilf (viewport.size.width);
       inverted_dst_height = ceilf (viewport.size.height);
 
-      meta_rectangle_crop_and_scale (&clip,
+      meta_rectangle_crop_and_scale (clip,
                                      &inverted_viewport,
                                      inverted_dst_width,
                                      inverted_dst_height,
-                                     &clip);
+                                     clip);
     }
 
   meta_texture_tower_update_area (stex->paint_tower,
-                                  clip.x,
-                                  clip.y,
-                                  clip.width,
-                                  clip.height);
+                                  clip->x,
+                                  clip->y,
+                                  clip->width,
+                                  clip->height);
 
   stex->prev_invalidation = stex->last_invalidation;
   stex->last_invalidation = g_get_monotonic_time ();
@@ -1001,34 +918,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
         stex->fast_updates++;
     }
 
-  unobscured_region = effective_unobscured_region (stex);
-  if (unobscured_region)
-    {
-      cairo_region_t *intersection;
-
-      if (cairo_region_is_empty (unobscured_region))
-        return FALSE;
-
-      intersection = cairo_region_copy (unobscured_region);
-      cairo_region_intersect_rectangle (intersection, &clip);
-
-      if (!cairo_region_is_empty (intersection))
-        {
-          cairo_rectangle_int_t damage_rect;
-          cairo_region_get_extents (intersection, &damage_rect);
-          clutter_content_invalidate (CLUTTER_CONTENT (stex));
-          cairo_region_destroy (intersection);
-          return TRUE;
-        }
-
-      cairo_region_destroy (intersection);
-      return FALSE;
-    }
-  else
-    {
-      clutter_content_invalidate (CLUTTER_CONTENT (stex));
-      return TRUE;
-    }
+  return TRUE;
 }
 
 /**
@@ -1458,34 +1348,3 @@ meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex)
 
   return stex->buffer_scale;
 }
-
-void
-meta_shaped_texture_cull_out (MetaShapedTexture *stex,
-                              cairo_region_t    *unobscured_region,
-                              cairo_region_t    *clip_region,
-                              uint8_t            opacity)
-{
-  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
-  set_unobscured_region (stex, unobscured_region);
-  set_clip_region (stex, clip_region);
-
-  if (opacity == 0xff)
-    {
-      if (stex->opaque_region)
-        {
-          if (unobscured_region)
-            cairo_region_subtract (unobscured_region, stex->opaque_region);
-          if (clip_region)
-            cairo_region_subtract (clip_region, stex->opaque_region);
-        }
-    }
-}
-
-void
-meta_shaped_texture_reset_culling (MetaShapedTexture *stex)
-{
-  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
-  set_clip_region (stex, NULL);
-}
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index e50eb8018..b68eb5eee 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -30,6 +30,10 @@ typedef struct _MetaSurfaceActorPrivate
 
   cairo_region_t *input_region;
 
+  /* MetaCullable regions, see that documentation for more details */
+  cairo_region_t *clip_region;
+  cairo_region_t *unobscured_region;
+
   /* Freeze/thaw accounting */
   cairo_region_t *pending_damage;
   guint frozen : 1;
@@ -51,6 +55,74 @@ enum
 
 static guint signals[LAST_SIGNAL];
 
+static cairo_region_t *
+effective_unobscured_region (MetaSurfaceActor *surface_actor)
+{
+  MetaSurfaceActorPrivate *priv =
+    meta_surface_actor_get_instance_private (surface_actor);
+  ClutterActor *actor;
+
+  /* Fail if we have any mapped clones. */
+  actor = CLUTTER_ACTOR (surface_actor);
+  do
+    {
+      if (clutter_actor_has_mapped_clones (actor))
+        return NULL;
+      actor = clutter_actor_get_parent (actor);
+    }
+  while (actor != NULL);
+
+  return priv->unobscured_region;
+}
+
+
+static void
+set_unobscured_region (MetaSurfaceActor *surface_actor,
+                       cairo_region_t   *unobscured_region)
+{
+  MetaSurfaceActorPrivate *priv =
+    meta_surface_actor_get_instance_private (surface_actor);
+
+  g_clear_pointer (&priv->unobscured_region, cairo_region_destroy);
+  if (unobscured_region)
+    {
+      float width, height;
+
+      clutter_content_get_preferred_size (CLUTTER_CONTENT (priv->texture),
+                                          &width,
+                                          &height);
+
+      cairo_rectangle_int_t bounds = { 0, 0, width, height };
+      priv->unobscured_region = cairo_region_copy (unobscured_region);
+      cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
+    }
+}
+
+static void
+set_clip_region (MetaSurfaceActor *surface_actor,
+                 cairo_region_t   *clip_region)
+{
+  MetaSurfaceActorPrivate *priv =
+    meta_surface_actor_get_instance_private (surface_actor);
+
+  g_clear_pointer (&priv->clip_region, cairo_region_destroy);
+  if (clip_region)
+    priv->clip_region = cairo_region_copy (clip_region);
+}
+
+static void
+meta_surface_actor_paint (ClutterActor *actor)
+{
+  MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (actor);
+  MetaSurfaceActorPrivate *priv =
+    meta_surface_actor_get_instance_private (surface_actor);
+
+  if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
+    return;
+
+  CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->paint (actor);
+}
+
 static void
 meta_surface_actor_pick (ClutterActor       *actor,
                          const ClutterColor *color)
@@ -126,6 +198,9 @@ meta_surface_actor_dispose (GObject *object)
 
   g_clear_pointer (&priv->input_region, cairo_region_destroy);
 
+  set_unobscured_region (self, NULL);
+  set_clip_region (self, NULL);
+
   G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
 }
 
@@ -136,6 +211,7 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 
   object_class->dispose = meta_surface_actor_dispose;
+  actor_class->paint = meta_surface_actor_paint;
   actor_class->pick = meta_surface_actor_pick;
   actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
 
@@ -164,17 +240,31 @@ meta_surface_actor_cull_out (MetaCullable   *cullable,
     meta_surface_actor_get_instance_private (surface_actor);
   uint8_t opacity = clutter_actor_get_opacity (CLUTTER_ACTOR (cullable));
 
-  meta_shaped_texture_cull_out (priv->texture, unobscured_region, clip_region, opacity);
+  set_unobscured_region (surface_actor, unobscured_region);
+  set_clip_region (surface_actor, clip_region);
+
+  if (opacity == 0xff)
+    {
+      cairo_region_t *opaque_region;
+
+      opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
+
+      if (opaque_region)
+        {
+          if (unobscured_region)
+            cairo_region_subtract (unobscured_region, opaque_region);
+          if (clip_region)
+            cairo_region_subtract (clip_region, opaque_region);
+        }
+    }
 }
 
 static void
 meta_surface_actor_reset_culling (MetaCullable *cullable)
 {
   MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
-  MetaSurfaceActorPrivate *priv =
-    meta_surface_actor_get_instance_private (surface_actor);
 
-  meta_shaped_texture_reset_culling (priv->texture);
+  set_clip_region (surface_actor, NULL);
 }
 
 static void
@@ -232,18 +322,58 @@ meta_surface_actor_update_area (MetaSurfaceActor *self,
 {
   MetaSurfaceActorPrivate *priv =
     meta_surface_actor_get_instance_private (self);
+  gboolean repaint_scheduled = FALSE;
+  cairo_rectangle_int_t clip;
+
+  if (meta_shaped_texture_update_area (priv->texture, x, y, width, height, &clip))
+    {
+      cairo_region_t *unobscured_region;
+
+      unobscured_region = effective_unobscured_region (self);
 
-  if (meta_shaped_texture_update_area (priv->texture, x, y, width, height))
+      if (unobscured_region)
+        {
+          cairo_region_t *intersection;
+
+          if (cairo_region_is_empty (unobscured_region))
+            return;
+
+          intersection = cairo_region_copy (unobscured_region);
+          cairo_region_intersect_rectangle (intersection, &clip);
+
+          if (!cairo_region_is_empty (intersection))
+            {
+              cairo_rectangle_int_t damage_rect;
+
+              cairo_region_get_extents (intersection, &damage_rect);
+              clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &damage_rect);
+              repaint_scheduled = TRUE;
+            }
+
+          cairo_region_destroy (intersection);
+        }
+      else
+        {
+          clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &clip);
+          repaint_scheduled = TRUE;
+        }
+    }
+
+  if (repaint_scheduled)
     g_signal_emit (self, signals[REPAINT_SCHEDULED], 0);
 }
 
 gboolean
 meta_surface_actor_is_obscured (MetaSurfaceActor *self)
 {
-  MetaSurfaceActorPrivate *priv =
-    meta_surface_actor_get_instance_private (self);
+  cairo_region_t *unobscured_region;
 
-  return meta_shaped_texture_is_obscured (priv->texture);
+  unobscured_region = effective_unobscured_region (self);
+
+  if (unobscured_region)
+    return cairo_region_is_empty (unobscured_region);
+  else
+    return FALSE;
 }
 
 void
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
index c36b8547f..9a4b5e7c6 100644
--- a/src/meta/meta-shaped-texture.h
+++ b/src/meta/meta-shaped-texture.h
@@ -45,11 +45,12 @@ void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
                                             gboolean           create_mipmaps);
 
 META_EXPORT
-gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
-                                          int                x,
-                                          int                y,
-                                          int                width,
-                                          int                height);
+gboolean meta_shaped_texture_update_area (MetaShapedTexture     *stex,
+                                          int                    x,
+                                          int                    y,
+                                          int                    width,
+                                          int                    height,
+                                          cairo_rectangle_int_t *clip);
 
 META_EXPORT
 CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);


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