From 2b69bc08112bb66877fdfd90944f8f9c4c794773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Maillart?= Date: Mon, 17 Feb 2025 11:16:22 +0100 Subject: [PATCH] gl-renderer: clip subimage dimensions to its buffer ones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A window freeze can occur in specific use cases like when using a kiosk shell. It scales surfaces to fit the compositor size and the transformation to buffer space can, in some cases, round the size one pixel higher than the texture size, making glTexSubImage2D() refuse the size argument and generate a GL_INVALID_VALUE without updating the texture. This commit ensures the GL renderer doesn't exceed the texture size. Here is how the issue was reproduced: $ weston --renderer=gl --backend=wayland --width=1920 --height=1080 --shell=kiosk $ gst-launch-1.0 videotestsrc ! video/x-raw,height=590,width=500 ! waylandsink display=wayland-1 Signed-off-by: Théo Maillart --- libweston/renderer-gl/gl-renderer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index cf6ae2b3c..56b34bacd 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -2745,15 +2745,18 @@ gl_renderer_flush_damage(struct weston_paint_node *pnode) for (j = 0; j < gb->num_textures; j++) { int hsub = pixel_format_hsub(buffer->pixel_format, j); int vsub = pixel_format_vsub(buffer->pixel_format, j); + int width = r.x2 - r.x1, height = r.y2 - r.y1; + width = MIN(width, buffer->width); + height = MIN(height, buffer->height); glBindTexture(GL_TEXTURE_2D, gb->textures[j]); glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, gb->pitch / hsub); glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, r.x1 / hsub); glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, r.y1 / vsub); gl_texture_2d_store(gr, 0, r.x1 / hsub, r.y1 / vsub, - (r.x2 - r.x1) / hsub, - (r.y2 - r.y1) / vsub, + width / hsub, + height / vsub, gb->texture_format[j].external, gb->texture_format[j].type, data + gb->offset[j]);