[mutter] window-actor: Ensure clipping in `capture_into()`



commit 840c50b00d2f7d8a8f9620872eae1ecbb81e1f3f
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Tue Feb 4 14:58:30 2020 +0100

    window-actor: Ensure clipping in `capture_into()`
    
    The clip bounds passed in `meta_window_actor_capture_into()` represent
    the actual allocated buffer size where the window actor image will be
    eventually copied.
    
    As such, it is completely agnostic to the scaling factors that might
    affect the different surface actors which compose the window actor.
    
    So instead of trying to compute the scale factor by which the given
    clipping bounds need to be adjusted, simply clip the resulting image
    based on the given bounds to make sure we never overflow the destination
    buffer.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/1022

 src/compositor/meta-window-actor.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 9f4568662..8ce6bc609 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1259,32 +1259,36 @@ meta_window_actor_capture_into (MetaScreenCastWindow *screen_cast_window,
   cr_height = cairo_image_surface_get_height (image);
   cr_stride = cairo_image_surface_get_stride (image);
 
-  if (cr_width < bounds->width || cr_height < bounds->height)
+  if (cr_width == bounds->width && cr_height == bounds->height)
     {
+      memcpy (data, cr_data, cr_height * cr_stride);
+    }
+  else
+    {
+      int width = MIN (bounds->width, cr_width);
+      int height = MIN (bounds->height, cr_height);
+      int stride = width * bpp;
       uint8_t *src, *dst;
+
       src = cr_data;
       dst = data;
 
-      for (int i = 0; i < cr_height; i++)
+      for (int i = 0; i < height; i++)
         {
-          memcpy (dst, src, cr_stride);
-          if (cr_width < bounds->width)
-            memset (dst + cr_stride, 0, (bounds->width * bpp) - cr_stride);
+          memcpy (dst, src, stride);
+          if (width < bounds->width)
+            memset (dst + stride, 0, (bounds->width * bpp) - stride);
 
           src += cr_stride;
           dst += bounds->width * bpp;
         }
 
-      for (int i = cr_height; i < bounds->height; i++)
+      for (int i = height; i < bounds->height; i++)
         {
           memset (dst, 0, bounds->width * bpp);
           dst += bounds->width * bpp;
         }
     }
-  else
-    {
-      memcpy (data, cr_data, cr_height * cr_stride);
-    }
 
   cairo_surface_destroy (image);
 }


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