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.
This commit is contained in:
bjorge@framework 2026-06-13 14:43:43 +02:00
parent 792bfac475
commit b264f63a18
2 changed files with 13 additions and 0 deletions

View file

@ -1243,6 +1243,10 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
if (!c->mon) if (!c->mon)
return; return;
if (config.blur && c->mon->blur) {
wlr_scene_optimized_blur_mark_dirty(c->mon->blur);
}
c->need_output_flush = true; c->need_output_flush = true;
c->dirty = true; c->dirty = true;

View file

@ -5045,6 +5045,7 @@ void rendermon(struct wl_listener *listener, void *data) {
bool frame_allow_tearing = false; bool frame_allow_tearing = false;
struct timespec now; struct timespec now;
bool need_more_frames = false; bool need_more_frames = false;
bool need_blur_dirty = false; // dirty the blur buffer
if (session && !session->active) { if (session && !session->active) {
return; return;
@ -5060,20 +5061,24 @@ void rendermon(struct wl_listener *listener, void *data) {
layer_list = &m->layers[i]; layer_list = &m->layers[i];
wl_list_for_each_safe(l, tmpl, layer_list, link) { wl_list_for_each_safe(l, tmpl, layer_list, link) {
need_more_frames = layer_draw_frame(l) || need_more_frames; 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) { wl_list_for_each_safe(c, tmp, &fadeout_clients, fadeout_link) {
need_more_frames = client_draw_fadeout_frame(c) || need_more_frames; 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) { wl_list_for_each_safe(l, tmpl, &fadeout_layers, fadeout_link) {
need_more_frames = layer_draw_fadeout_frame(l) || need_more_frames; 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) { wl_list_for_each(c, &clients, link) {
need_more_frames = client_draw_frame(c) || need_more_frames; 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 && if (!config.animations && !grabc && c->configure_serial &&
client_is_rendered_on_mon(c, m)) { client_is_rendered_on_mon(c, m)) {
monitor_check_skip_frame_timeout(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); 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) { if (config.allow_tearing && frame_allow_tearing) {
apply_tear_state(m); apply_tear_state(m);