[mutter] shaped-texture: Use surface coordinates in get_image()



commit cd70595b50751669f2e0b58ae2cbfeb3c7291574
Author: Robert Mader <robert mader posteo de>
Date:   Tue Aug 27 16:38:17 2019 +0300

    shaped-texture: Use surface coordinates in get_image()
    
    There were multiple bugs present after the ClutterContent transition.
    Refactor `get_image` to:
    
    - always assume surface coordinates for the clip
    - return a cairo_surface in buffer size
    - make the offscreen path take size arguments, so we can
    easily change the assumption in get_image
    - fix some clipping bugs on the way
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/758

 src/compositor/meta-shaped-texture.c | 81 +++++++++++++++++++++---------------
 1 file changed, 48 insertions(+), 33 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 972c33606..ba0c883f0 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -1114,7 +1114,9 @@ should_get_via_offscreen (MetaShapedTexture *stex)
 
 static cairo_surface_t *
 get_image_via_offscreen (MetaShapedTexture     *stex,
-                         cairo_rectangle_int_t *clip)
+                         cairo_rectangle_int_t *clip,
+                         int                    image_width,
+                         int                    image_height)
 {
   g_autoptr (ClutterPaintNode) root_node = NULL;
   ClutterBackend *clutter_backend = clutter_get_default_backend ();
@@ -1132,16 +1134,16 @@ get_image_via_offscreen (MetaShapedTexture     *stex,
   if (!clip)
     {
       fallback_clip = (cairo_rectangle_int_t) {
-        .width = stex->dst_width,
-        .height = stex->dst_height,
+        .width = image_width,
+        .height = image_height,
       };
       clip = &fallback_clip;
     }
 
   image_texture =
     COGL_TEXTURE (cogl_texture_2d_new_with_size (cogl_context,
-                                                 stex->dst_width,
-                                                 stex->dst_height));
+                                                 image_width,
+                                                 image_height));
   cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (image_texture),
                                           FALSE);
   if (!cogl_texture_allocate (COGL_TEXTURE (image_texture), &error))
@@ -1164,11 +1166,11 @@ get_image_via_offscreen (MetaShapedTexture     *stex,
   cogl_framebuffer_push_matrix (fb);
   cogl_matrix_init_identity (&projection_matrix);
   cogl_matrix_scale (&projection_matrix,
-                     1.0 / (stex->dst_width / 2.0),
-                     -1.0 / (stex->dst_height / 2.0), 0);
+                     1.0 / (image_width / 2.0),
+                     -1.0 / (image_height / 2.0), 0);
   cogl_matrix_translate (&projection_matrix,
-                         -(stex->dst_width / 2.0),
-                         -(stex->dst_height / 2.0), 0);
+                         -(image_width / 2.0),
+                         -(image_height / 2.0), 0);
 
   cogl_framebuffer_set_projection_matrix (fb, &projection_matrix);
 
@@ -1180,8 +1182,9 @@ get_image_via_offscreen (MetaShapedTexture     *stex,
   do_paint_content (stex, root_node,
                     stex->texture,
                     &(ClutterActorBox) {
-                      clip->x, clip->y,
-                      clip->width, clip->height,
+                      0, 0,
+                      image_width,
+                      image_height,
                     },
                     255);
 
@@ -1219,7 +1222,7 @@ cairo_surface_t *
 meta_shaped_texture_get_image (MetaShapedTexture     *stex,
                                cairo_rectangle_int_t *clip)
 {
-  cairo_rectangle_int_t *transformed_clip = NULL;
+  cairo_rectangle_int_t *image_clip = NULL;
   CoglTexture *texture, *mask_texture;
   cairo_surface_t *surface;
 
@@ -1239,31 +1242,43 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
     {
       cairo_rectangle_int_t dst_rect;
 
-      transformed_clip = alloca (sizeof (cairo_rectangle_int_t));
-
-      meta_rectangle_scale_double (clip, stex->buffer_scale,
-                                   META_ROUNDING_STRATEGY_GROW,
-                                   transformed_clip);
-
+      image_clip = alloca (sizeof (cairo_rectangle_int_t));
       dst_rect = (cairo_rectangle_int_t) {
         .width = stex->dst_width,
         .height = stex->dst_height,
       };
 
-      if (!meta_rectangle_intersect (&dst_rect, transformed_clip,
-                                     transformed_clip))
+      if (!meta_rectangle_intersect (&dst_rect, clip,
+                                     image_clip))
         return NULL;
+
+      *image_clip = (MetaRectangle) {
+        .x = image_clip->x * stex->buffer_scale,
+        .y = image_clip->y * stex->buffer_scale,
+        .width = image_clip->width * stex->buffer_scale,
+        .height = image_clip->height * stex->buffer_scale,
+      };
     }
 
   if (should_get_via_offscreen (stex))
-    return get_image_via_offscreen (stex, transformed_clip);
+    {
+      int image_width;
+      int image_height;
+
+      image_width = stex->dst_width * stex->buffer_scale;
+      image_height = stex->dst_height * stex->buffer_scale;
+      return get_image_via_offscreen (stex,
+                                      image_clip,
+                                      image_width,
+                                      image_height);
+    }
 
-  if (transformed_clip)
+  if (image_clip)
     texture = cogl_texture_new_from_sub_texture (texture,
-                                                 transformed_clip->x,
-                                                 transformed_clip->y,
-                                                 transformed_clip->width,
-                                                 transformed_clip->height);
+                                                 image_clip->x,
+                                                 image_clip->y,
+                                                 image_clip->width,
+                                                 image_clip->height);
 
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                         cogl_texture_get_width (texture),
@@ -1275,7 +1290,7 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 
   cairo_surface_mark_dirty (surface);
 
-  if (transformed_clip)
+  if (image_clip)
     cogl_object_unref (texture);
 
   mask_texture = stex->mask_texture;
@@ -1284,13 +1299,13 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
       cairo_t *cr;
       cairo_surface_t *mask_surface;
 
-      if (transformed_clip)
+      if (image_clip)
         mask_texture =
           cogl_texture_new_from_sub_texture (mask_texture,
-                                             transformed_clip->x,
-                                             transformed_clip->y,
-                                             transformed_clip->width,
-                                             transformed_clip->height);
+                                             image_clip->x,
+                                             image_clip->y,
+                                             image_clip->width,
+                                             image_clip->height);
 
       mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
                                                  cogl_texture_get_width (mask_texture),
@@ -1310,7 +1325,7 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 
       cairo_surface_destroy (mask_surface);
 
-      if (transformed_clip)
+      if (image_clip)
         cogl_object_unref (mask_texture);
     }
 


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