From e34cc23549a19c219c79340f08aab39f5a3dff33 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 11 Jul 2024 20:41:29 +0200 Subject: [PATCH] scene: only skip bottom-most black rects with fractional scaling We were relying on the fact that we wouldn't paint anything on top of the black background in the region of a black rect. However when fractional scaling is used the repaint region might get expanded to nearby pixels by scale_output_damage(). As a result the neighbour scene nodes might leak into the skipped black rect's region. Avoid this by using this optimization for bottom-most black rects only when fractional scaling is used. References: https://github.com/swaywm/sway/issues/8233 --- types/scene/wlr_scene.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index e3e49584..46768aab 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -1504,6 +1504,7 @@ struct render_list_constructor_data { struct wl_array *render_list; bool calculate_visibility; bool highlight_transparent_region; + bool fractional_scale; }; static bool construct_render_list_iterator(struct wlr_scene_node *node, @@ -1514,10 +1515,12 @@ static bool construct_render_list_iterator(struct wlr_scene_node *node, return false; } - // while rendering, the background should always be black. - // If we see a black rect, we can ignore rendering everything under the rect - // and even the rect itself. - if (node->type == WLR_SCENE_NODE_RECT && data->calculate_visibility) { + // While rendering, the background should always be black. If we see a + // black rect, we can ignore rendering everything under the rect, and + // unless fractional scale is used even the rect itself (to avoid running + // into issues regarding damage region expansion). + if (node->type == WLR_SCENE_NODE_RECT && data->calculate_visibility && + (!data->fractional_scale || data->render_list->size == 0)) { struct wlr_scene_rect *rect = wlr_scene_rect_from_node(node); float *black = (float[4]){ 0.f, 0.f, 0.f, 1.f }; @@ -1773,6 +1776,7 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output, .render_list = &scene_output->render_list, .calculate_visibility = scene_output->scene->calculate_visibility, .highlight_transparent_region = scene_output->scene->highlight_transparent_region, + .fractional_scale = floor(render_data.scale) != render_data.scale, }; list_con.render_list->size = 0;