kathenas / rpms / mutter

Forked from rpms/mutter 5 years ago
Clone
Blob Blame History Raw
From 1587447b47130affe437acce4770f82d13176227 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 22 Jan 2019 10:22:27 +0100
Subject: [PATCH] window-actor: Use actual image size for capture

Previously, the clipping rectangle passed to
`meta_surface_actor_get_image()` was updated with the actual texture
size, but recent changes in `meta_shaped_texture_get_image()` now keep
the caller's clipping rectangle unchanged.

The implementation of `meta_window_actor_capture_into()` was relying on
the old behavior of updating the passed clipping rectangle, but now that
it's kept unchanged, the actual clipping rectangle used to copy the data
is wrong, which causes either a distorded image or worse, a crash of
mutter.

Use the resulting cairo image size to copy the data instead of the
clipping rectangle to avoid the issue and get the expected size.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/442
---
 src/compositor/meta-window-actor.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 396fef1..756e6c0 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -2260,36 +2260,38 @@ meta_window_actor_capture_into (MetaScreenCastWindow *screen_cast_window,
 {
   MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
   cairo_surface_t *image;
-  MetaRectangle clip_rect;
   uint8_t *cr_data;
   int cr_stride;
+  int cr_width;
+  int cr_height;
   int bpp = 4;
 
   if (meta_window_actor_is_destroyed (window_actor))
     return;
 
-  clip_rect = *bounds;
-  image = meta_surface_actor_get_image (window_actor->priv->surface, &clip_rect);
+  image = meta_surface_actor_get_image (window_actor->priv->surface, bounds);
   cr_data = cairo_image_surface_get_data (image);
+  cr_width = cairo_image_surface_get_width (image);
+  cr_height = cairo_image_surface_get_height (image);
   cr_stride = cairo_image_surface_get_stride (image);
 
-  if (clip_rect.width < bounds->width || clip_rect.height < bounds->height)
+  if (cr_width < bounds->width || cr_height < bounds->height)
     {
       uint8_t *src, *dst;
       src = cr_data;
       dst = data;
 
-      for (int i = 0; i < clip_rect.height; i++)
+      for (int i = 0; i < cr_height; i++)
         {
           memcpy (dst, src, cr_stride);
-          if (clip_rect.width < bounds->width)
+          if (cr_width < bounds->width)
             memset (dst + cr_stride, 0, (bounds->width * bpp) - cr_stride);
 
           src += cr_stride;
           dst += bounds->width * bpp;
         }
 
-      for (int i = clip_rect.height; i < bounds->height; i++)
+      for (int i = cr_height; i < bounds->height; i++)
         {
           memset (dst, 0, bounds->width * bpp);
           dst += bounds->width * bpp;
@@ -2297,7 +2299,7 @@ meta_window_actor_capture_into (MetaScreenCastWindow *screen_cast_window,
     }
   else
     {
-      memcpy (data, cr_data, clip_rect.height * cr_stride);
+      memcpy (data, cr_data, cr_height * cr_stride);
     }
 
   cairo_surface_destroy (image);
-- 
2.20.1