backend-wayland: fix pixman buffer size

As wayland-backend is blitting the output decorations into the output
buffer itself, it pretends towards the pixman-renderer that there is no
decorations area. The pixman_image_create_bits() call wraps the
previously allocated buffer with an offset so that pixman-renderer will
paint in the right position.

The bug is that this pixman image was using the original buffer width
and height, instead of the composited area width and height. So the
pixman image looks too big to pixman-renderer, but the renderer didn't
care. The image being too big does risk access out of bounds in
pixman-renderer.

I found this when I was making renderers explicitly aware of the
frambuffer size and resizing, added asserts, and they surprisingly
failed. This fixes that.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen 2022-07-28 16:56:21 +03:00 committed by Daniel Stone
parent 214d48bbab
commit d4eafbaa98

View file

@ -301,7 +301,7 @@ wayland_output_get_shm_buffer(struct wayland_output *output)
struct wl_shm_pool *pool;
int width, height, stride;
int32_t fx, fy;
struct weston_geometry area;
int fd;
unsigned char *data;
@ -377,13 +377,20 @@ wayland_output_get_shm_buffer(struct wayland_output *output)
cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32,
width, height, stride);
fx = 0;
fy = 0;
if (output->frame)
frame_interior(output->frame, &fx, &fy, 0, 0);
if (output->frame) {
frame_interior(output->frame, &area.x, &area.y,
&area.width, &area.height);
} else {
area.x = 0;
area.y = 0;
area.width = output->base.current_mode->width;
area.height = output->base.current_mode->height;
}
/* Address only the interior, excluding output decorations */
sb->pm_image =
pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height,
(uint32_t *)(data + fy * stride) + fx,
pixman_image_create_bits(PIXMAN_a8r8g8b8, area.width, area.height,
(uint32_t *)(data + area.y * stride) + area.x,
stride);
return sb;