From b264f63a1861fdbd47ff577a5c575d8d4bcc8cf6 Mon Sep 17 00:00:00 2001 From: "bjorge@framework" Date: Sat, 13 Jun 2026 14:43:43 +0200 Subject: [PATCH] dirty the blur buffer during animation/resize Fixes issue #560 On my machine (integrated graphics: AMD Ryzen 5 7640U w/ Radeon 760M Graphics), I have rendering artifacts when two blurred surfaces pass over each other. This commit manually marks the blur buffer as dirty during client resizing and animation, fixing the artifact issue. --- src/animation/client.h | 4 ++++ src/mango.c | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/animation/client.h b/src/animation/client.h index f988651e..52279123 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -1243,6 +1243,10 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) { if (!c->mon) return; + if (config.blur && c->mon->blur) { + wlr_scene_optimized_blur_mark_dirty(c->mon->blur); + } + c->need_output_flush = true; c->dirty = true; diff --git a/src/mango.c b/src/mango.c index 731c0ac3..d39a2fa5 100644 --- a/src/mango.c +++ b/src/mango.c @@ -5045,6 +5045,7 @@ void rendermon(struct wl_listener *listener, void *data) { bool frame_allow_tearing = false; struct timespec now; bool need_more_frames = false; + bool need_blur_dirty = false; // dirty the blur buffer if (session && !session->active) { return; @@ -5060,20 +5061,24 @@ void rendermon(struct wl_listener *listener, void *data) { layer_list = &m->layers[i]; wl_list_for_each_safe(l, tmpl, layer_list, link) { need_more_frames = layer_draw_frame(l) || need_more_frames; + if (l->animation.running) need_blur_dirty = true; } } wl_list_for_each_safe(c, tmp, &fadeout_clients, fadeout_link) { need_more_frames = client_draw_fadeout_frame(c) || need_more_frames; + if (l->animation.running) need_blur_dirty = true; } wl_list_for_each_safe(l, tmpl, &fadeout_layers, fadeout_link) { need_more_frames = layer_draw_fadeout_frame(l) || need_more_frames; + if (l->animation.running) need_blur_dirty = true; } // 绘制客户端 wl_list_for_each(c, &clients, link) { need_more_frames = client_draw_frame(c) || need_more_frames; + if (l->animation.running) need_blur_dirty = true; if (!config.animations && !grabc && c->configure_serial && client_is_rendered_on_mon(c, m)) { monitor_check_skip_frame_timeout(m); @@ -5085,6 +5090,10 @@ void rendermon(struct wl_listener *listener, void *data) { monitor_stop_skip_frame_timer(m); } + if (config.blur && m->blur && (need_blur_dirty || need_more_frames)) { + wlr_scene_optimized_blur_mark_dirty(m->blur); + } + // 只有在需要帧时才构建和提交状态 if (config.allow_tearing && frame_allow_tearing) { apply_tear_state(m);