[mutter/gnome-3-36] shaped-texture: Reintroduce clip_region



commit 44a3358125317dbe2151cf0ac70ec2c382236881
Author: Robert Mader <robert mader posteo de>
Date:   Mon Jun 22 13:53:23 2020 +0000

    shaped-texture: Reintroduce clip_region
    
    In commit 4c1fde9d MetaCullable related code was moved out of
    MetaShapedTexture into MetaSurfaceActor. While generally desirable,
    this removed drawing optimizations in MetaShapedTexture for partial
    redraws. The common case for fully obscured actors was still supposed
    to work, but it was now discovered that it actually did not.
    
    This commit revert parts of 4c1fde9d: it reintroduces clipping
    to MetaShapedTexture but leaves all culling and actor related logic
    in MetaSurfaceActor.
    
    Thanks to Daniel van Vugt for uncovering the issue.
    
    Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/850
    Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1295
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1326
    
    
    (cherry picked from commit 3187fe8ebc73cb3907d1d02edecedc4e4ab0c689)

 src/compositor/meta-shaped-texture-private.h |  3 ++
 src/compositor/meta-shaped-texture.c         | 46 +++++++++++++++++++++++++---
 src/compositor/meta-surface-actor.c          | 34 +++++++-------------
 3 files changed, 55 insertions(+), 28 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index 85d94b7534..c415260c0b 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -66,4 +66,7 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture     *stex,
 int meta_shaped_texture_get_width (MetaShapedTexture *stex);
 int meta_shaped_texture_get_height (MetaShapedTexture *stex);
 
+void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
+                                          cairo_region_t    *clip_region);
+
 #endif
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 79bb61c8f8..32abfdf963 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -87,6 +87,9 @@ 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;
+
   gboolean size_invalid;
   MetaMonitorTransform transform;
   gboolean has_viewport_src_rect;
@@ -214,6 +217,15 @@ ensure_size_valid (MetaShapedTexture *stex)
     update_size (stex);
 }
 
+void
+meta_shaped_texture_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_reference (clip_region);
+}
+
 static void
 meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
 {
@@ -239,6 +251,7 @@ meta_shaped_texture_dispose (GObject *object)
   meta_shaped_texture_reset_pipelines (stex);
 
   g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
+  g_clear_pointer (&stex->clip_region, cairo_region_destroy);
 
   g_clear_pointer (&stex->snippet, cogl_object_unref);
 
@@ -585,12 +598,19 @@ do_paint_content (MetaShapedTexture   *stex,
 
   if (use_opaque_region)
     {
-      blended_tex_region = cairo_region_create_rectangle (&content_rect);
+      if (stex->clip_region)
+        blended_tex_region = cairo_region_copy (stex->clip_region);
+      else
+        blended_tex_region = cairo_region_create_rectangle (&content_rect);
+
       cairo_region_subtract (blended_tex_region, stex->opaque_region);
     }
   else
     {
-      blended_tex_region = NULL;
+      if (stex->clip_region)
+        blended_tex_region = cairo_region_reference (stex->clip_region);
+      else
+        blended_tex_region = NULL;
     }
 
   /* Limit to how many separate rectangles we'll draw; beyond this just
@@ -612,10 +632,21 @@ 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 (!cairo_region_is_empty (stex->opaque_region))
+      if (stex->clip_region)
+        {
+          region = cairo_region_copy (stex->clip_region);
+          cairo_region_intersect (region, stex->opaque_region);
+        }
+      else
+        {
+          region = cairo_region_reference (stex->opaque_region);
+        }
+
+      if (!cairo_region_is_empty (region))
         {
           CoglPipeline *opaque_pipeline;
 
@@ -623,16 +654,18 @@ 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 (stex->opaque_region);
+          n_rects = cairo_region_num_rectangles (region);
           for (i = 0; i < n_rects; i++)
             {
               cairo_rectangle_int_t rect;
-              cairo_region_get_rectangle (stex->opaque_region, i, &rect);
+              cairo_region_get_rectangle (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. */
@@ -757,6 +790,9 @@ 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
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index c328fab734..1052589546 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -34,7 +34,6 @@ 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 */
@@ -134,30 +133,21 @@ set_clip_region (MetaSurfaceActor *surface_actor,
 {
   MetaSurfaceActorPrivate *priv =
     meta_surface_actor_get_instance_private (surface_actor);
+  MetaShapedTexture *stex = priv->texture;
 
-  g_clear_pointer (&priv->clip_region, cairo_region_destroy);
-  if (clip_region)
+  if (clip_region && !cairo_region_is_empty (clip_region))
     {
-      if (cairo_region_is_empty (clip_region))
-        priv->clip_region = cairo_region_reference (clip_region);
-      else
-        priv->clip_region = get_scaled_region (surface_actor, clip_region);
-    }
-}
+      cairo_region_t *region;
 
-static void
-meta_surface_actor_paint (ClutterActor        *actor,
-                          ClutterPaintContext *paint_context)
-{
-  MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (actor);
-  MetaSurfaceActorPrivate *priv =
-    meta_surface_actor_get_instance_private (surface_actor);
+      region = get_scaled_region (surface_actor, clip_region);
+      meta_shaped_texture_set_clip_region (stex, region);
 
-  if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
-    return;
-
-  CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->paint (actor,
-                                                                paint_context);
+      cairo_region_destroy (region);
+    }
+  else
+    {
+      meta_shaped_texture_set_clip_region (stex, clip_region);
+    }
 }
 
 static void
@@ -227,7 +217,6 @@ meta_surface_actor_dispose (GObject *object)
   g_clear_object (&priv->texture);
 
   set_unobscured_region (self, NULL);
-  set_clip_region (self, NULL);
 
   G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
 }
@@ -239,7 +228,6 @@ 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;
 


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