summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2019-01-22 10:22:27 +0100
committerRay Strode <rstrode@redhat.com>2019-02-11 13:40:19 -0500
commit3bdfbf97b99a64f1bcc4abbdda4c50afeeb080b4 (patch)
tree3057e093302683367f4c1d219681dfe98e08358c
parenta7f2145965af7150ec0b54cdb99441f049cc44b9 (diff)
downloadmutter-3bdfbf97b99a64f1bcc4abbdda4c50afeeb080b4.tar.gz
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
-rw-r--r--src/compositor/meta-window-actor.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 396fef1ff..381d3ea85 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);