[mutter] shaped-texture: Fix use-nearest check when viewports are scaled



commit 8beef8ccd02388c213a57045504794cac0c6e52d
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Mar 13 19:31:23 2020 +0100

    shaped-texture: Fix use-nearest check when viewports are scaled
    
    We checked that the content size was appropriately painted in the stage,
    but didn't take into account that the size of the sampled texture
    region, meaning that when stage views were scaled, we'd think that we
    would draw a texture scaled, as e.g. a 200x200 sized texture with buffer
    scale 2 would have the size 100x100. When stage views were not scaled,
    we'd apply a geometry scale meaning it'd end up as 200x200 anyway, thus
    pass the check, but when stage views are scaled, it'd still be painted
    as a 100x100 shaped texture on the stage, thus failing the
    are-we-unscaled test.
    
    Fix this by comparing the transformed paint size with the sampled size,
    instead of the paint size again, when checking whether we are being
    painted scaled or not. For example, when stage views are scaled, our
    200x200 buffer with buffer scale 2, thus content size 100x100 will
    transform to a 200x200 paint command, thus passing the test. For
    non-scaled stage views, our 200x200 buffer with buffer scale 2 thus
    content size 100x100 will also transform into a 200x200 paint command,
    and will also pass the check, as the texture sample region is still
    200x200.
    
    Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/804
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1124

 src/compositor/clutter-utils.c         |  8 +++++++-
 src/compositor/clutter-utils.h         |  2 ++
 src/compositor/meta-background-actor.c |  2 ++
 src/compositor/meta-shaped-texture.c   | 31 +++++++++++++++++++++++++++++--
 src/compositor/meta-window-group.c     |  2 ++
 5 files changed, 42 insertions(+), 3 deletions(-)
---
diff --git a/src/compositor/clutter-utils.c b/src/compositor/clutter-utils.c
index d4b026e38..f05a698f5 100644
--- a/src/compositor/clutter-utils.c
+++ b/src/compositor/clutter-utils.c
@@ -115,6 +115,8 @@ meta_actor_vertices_are_untransformed (graphene_point3d_t *verts,
  * meta_actor_painting_untransformed:
  * @paint_width: the width of the painted area
  * @paint_height: the height of the painted area
+ * @sample_width: the width of the sampled area of the texture
+ * @sample_height: the height of the sampled area of the texture
  * @x_origin: if the transform is only an integer translation
  *  then the X coordinate of the location of the origin under the transformation
  *  from drawing space to screen pixel space is returned here.
@@ -133,6 +135,8 @@ gboolean
 meta_actor_painting_untransformed (CoglFramebuffer *fb,
                                    int              paint_width,
                                    int              paint_height,
+                                   int              sample_width,
+                                   int              sample_height,
                                    int             *x_origin,
                                    int             *y_origin)
 {
@@ -177,6 +181,8 @@ meta_actor_painting_untransformed (CoglFramebuffer *fb,
                                       viewport[3], viewport[1]);
     }
 
-  return meta_actor_vertices_are_untransformed (vertices, paint_width, paint_height, x_origin, y_origin);
+  return meta_actor_vertices_are_untransformed (vertices,
+                                                sample_width, sample_height,
+                                                x_origin, y_origin);
 }
 
diff --git a/src/compositor/clutter-utils.h b/src/compositor/clutter-utils.h
index a1fe6b739..8ed0e2a4d 100644
--- a/src/compositor/clutter-utils.h
+++ b/src/compositor/clutter-utils.h
@@ -32,6 +32,8 @@ gboolean meta_actor_vertices_are_untransformed (graphene_point3d_t *verts,
 gboolean meta_actor_painting_untransformed (CoglFramebuffer *fb,
                                             int              paint_width,
                                             int              paint_height,
+                                            int              sample_widthf,
+                                            int              sample_heightf,
                                             int             *x_origin,
                                             int             *y_origin);
 
diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c
index 54a6fa5f4..361fbeeb1 100644
--- a/src/compositor/meta-background-actor.c
+++ b/src/compositor/meta-background-actor.c
@@ -450,6 +450,8 @@ setup_pipeline (MetaBackgroundActor   *self,
   fb = clutter_paint_context_get_framebuffer (paint_context);
   if (!self->force_bilinear &&
       meta_actor_painting_untransformed (fb,
+                                         actor_pixel_rect->width,
+                                         actor_pixel_rect->height,
                                          actor_pixel_rect->width,
                                          actor_pixel_rect->height,
                                          NULL, NULL))
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 6f30325cd..79bb61c8f 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -507,6 +507,17 @@ texture_is_idle_and_not_mipmapped (gpointer user_data)
   return G_SOURCE_REMOVE;
 }
 
+static inline void
+flip_ints (int *x,
+           int *y)
+{
+  int tmp;
+
+  tmp = *x;
+  *x = *y;
+  *y = tmp;
+}
+
 static void
 do_paint_content (MetaShapedTexture   *stex,
                   ClutterPaintNode    *root_node,
@@ -522,6 +533,7 @@ do_paint_content (MetaShapedTexture   *stex,
   CoglContext *ctx;
   CoglPipelineFilter filter;
   CoglFramebuffer *framebuffer;
+  int sample_width, sample_height;
 
   ensure_size_valid (stex);
 
@@ -542,15 +554,30 @@ do_paint_content (MetaShapedTexture   *stex,
    * improves performance, especially with software rendering.
    */
 
-  filter = COGL_PIPELINE_FILTER_LINEAR;
-
   framebuffer = clutter_paint_node_get_framebuffer (root_node);
   if (!framebuffer)
     framebuffer = clutter_paint_context_get_framebuffer (paint_context);
+
+  if (stex->has_viewport_src_rect)
+    {
+      sample_width = stex->viewport_src_rect.size.width * stex->buffer_scale;
+      sample_height = stex->viewport_src_rect.size.height * stex->buffer_scale;
+    }
+  else
+    {
+      sample_width = cogl_texture_get_width (stex->texture);
+      sample_height = cogl_texture_get_height (stex->texture);
+    }
+  if (meta_monitor_transform_is_rotated (stex->transform))
+    flip_ints (&sample_width, &sample_height);
+
   if (meta_actor_painting_untransformed (framebuffer,
                                          dst_width, dst_height,
+                                         sample_width, sample_height,
                                          NULL, NULL))
     filter = COGL_PIPELINE_FILTER_NEAREST;
+  else
+    filter = COGL_PIPELINE_FILTER_LINEAR;
 
   ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 
diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c
index 49eb72b85..d526805fe 100644
--- a/src/compositor/meta-window-group.c
+++ b/src/compositor/meta-window-group.c
@@ -94,6 +94,8 @@ meta_window_group_paint (ClutterActor        *actor,
 
       fb = clutter_paint_context_get_framebuffer (paint_context);
       if (!meta_actor_painting_untransformed (fb,
+                                              screen_width,
+                                              screen_height,
                                               screen_width,
                                               screen_height,
                                               &paint_x_origin,


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