Skip to content

Commit 7ab1d4e

Browse files
committed
fix: prevent stale blur surface after workspace switch
1 parent f192eb9 commit 7ab1d4e

3 files changed

Lines changed: 17 additions & 9 deletions

File tree

TODO.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
- Effects per window state (e.g. unfocused, focused, ...)
88
- Inner glow effects on borders
99
- Floating toplevels with mica are missing rounded border clip on their surface
10-
- Some layer surfaces with blur and a static position do not update the blur surface correctly (layer surface bar doesn't appear to track a toplevel behind it consistently; moving to an empty workspace from a non-empty workspace leaves behind some stale information in the blur surface)
1110
- Intel works perfectly but AMD has the following issues: gles2 non-protocol blur buffers render as black; vulkan has an abort when closing some toplevels, incorrectly clips surfaces with rounded borders and blur surfaces are missing
1211
- When shadow is enabled on a toplevel with rounded borders, the shadow seems to be clipped where the toplevel was clipped by the rounded border (either a layering or rendering issue)
1312

include/effects.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ typedef struct effects_output_t {
8787
uint32_t backdrop_gen;
8888
uint32_t blur_gen;
8989
uint32_t layer_blur_gen;
90+
91+
bool prev_workspace_switch;
9092
} effects_output_t;
9193

9294
typedef struct effects_state_t {

src/effects.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ static uint64_t capture_bg_to_tex1_ex(output_t *output, effects_output_t *ctx, b
519519
bool reaches_visible = damage_reaches_visible_surface(output, ctx, &ctx->scratch_region_b,
520520
hide_blur_toplevels);
521521
if (pixman_region32_empty(&ctx->scratch_region_c) && !reaches_visible) {
522+
wlr_log(WLR_DEBUG, "effects: capture_bg_tex1 EARLY-RETURN stale backdrop");
522523
wlr_scene_output_set_position(ctx->capture_scene_output, -0x7fff, -0x7fff);
523524
if (changed)
524525
*changed = false;
@@ -1078,10 +1079,6 @@ static bool rebuild_live_blur_layers(output_t *output, uint64_t bg_tex, pixman_r
10781079
if (ctx->layer_blur_buf && ctx->layer_blur_native[0] && ctx->layer_blur_gen == ctx->backdrop_gen)
10791080
return true;
10801081

1081-
if (!ensure_sized_buf(&ctx->layer_blur_buf, ctx->layer_blur_native, &ctx->layer_blur_buf_w,
1082-
&ctx->layer_blur_buf_h, ctx->blur_w, ctx->blur_h))
1083-
return false;
1084-
10851082
int n_scissor = 0;
10861083
const pixman_box32_t *scissor = blur_damage_boxes(ctx, damage, w, h, &n_scissor);
10871084
effects_backend->blur(&ctx->be_state, bg_tex, ctx->blur_w, ctx->blur_h, &bp,
@@ -2205,6 +2202,13 @@ void effects_output_frame(output_t *output, struct wlr_scene_output *scene_outpu
22052202

22062203
bool workspace_switch = animation_workspace_switch_active(output);
22072204
bool workspace_warmup = workspace_switch && workspace_effect_buffers_missing(output);
2205+
bool switch_just_ended = ctx->prev_workspace_switch && !workspace_switch;
2206+
2207+
ctx->prev_workspace_switch = workspace_switch;
2208+
if (switch_just_ended) {
2209+
ctx->shared_bg_valid = false;
2210+
ctx->combined_bg_valid = false;
2211+
}
22082212

22092213
// check if layer blur surfaces need rendering
22102214
bool has_layer_blur = false;
@@ -2265,9 +2269,9 @@ void effects_output_frame(output_t *output, struct wlr_scene_output *scene_outpu
22652269
ctx->blur_h != want_bh)
22662270
effects_output_resize(ctx, output->width, output->height, output);
22672271

2268-
bool bg_damaged = workspace_warmup || effect_regions_damaged(output,
2272+
bool bg_damaged = workspace_warmup || switch_just_ended || effect_regions_damaged(output,
22692273
scene_output) || effects_pending_update(output);
2270-
bool mica_dirty = mica_enabled && ctx->mica_dirty;
2274+
bool mica_dirty = mica_enabled && (ctx->mica_dirty || switch_just_ended);
22712275
bool effects_work = bg_damaged || mica_dirty;
22722276

22732277
if (!effects_work && !effects_border_pending(output) && !screen_shader_enabled)
@@ -2382,8 +2386,8 @@ void effects_output_frame(output_t *output, struct wlr_scene_output *scene_outpu
23822386
push_corner_masks_to_toplevels(output, any_cm_dirty);
23832387
goto cm_done;
23842388
}
2385-
bool any_layer_needs_blur = blur_enabled && layer_blur_needs_rebuild(output,
2386-
&scene_output->damage_ring.current);
2389+
bool any_layer_needs_blur = blur_enabled && (switch_just_ended || layer_blur_needs_rebuild(output,
2390+
&scene_output->damage_ring.current));
23872391

23882392
if (any_layer_needs_blur && any_cm) {
23892393
uint64_t bg_tex = capture_bg_combined(output, ctx);
@@ -2477,6 +2481,9 @@ void effects_output_frame(output_t *output, struct wlr_scene_output *scene_outpu
24772481
effects_output_resize(ctx, output->width, output->height, output);
24782482
}
24792483

2484+
ctx->shared_bg_valid = false;
2485+
ctx->combined_bg_valid = false;
2486+
24802487
effects_backend->frame_begin();
24812488

24822489
// apply corner masks and layer blur if needed

0 commit comments

Comments
 (0)