From be57ee3184e047ac932057cd063f7858741d41d9 Mon Sep 17 00:00:00 2001 From: Marc Espin Date: Mon, 29 Jun 2026 21:30:29 +0200 Subject: [PATCH] fix(core): Make blur work with opacity --- crates/freya-core/src/render_pipeline.rs | 54 +++++++++++------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/crates/freya-core/src/render_pipeline.rs b/crates/freya-core/src/render_pipeline.rs index 9f5bb258c..82d3b626d 100644 --- a/crates/freya-core/src/render_pipeline.rs +++ b/crates/freya-core/src/render_pipeline.rs @@ -139,6 +139,30 @@ impl RenderPipeline<'_> { } } + // Composite the blur before the opacity layers so its backdrop samples the real content underneath rather than the still empty opacity layer. + if let Some(blur_radius) = effect_state.blur { + let style = element.style(); + + let image_filter = blur( + (blur_radius * scale_factor, blur_radius * scale_factor), + None, + None, + render_rect.rect(), + ); + if let Some(image_filter) = image_filter { + let rec = SaveLayerRec::default() + .bounds(render_rect.rect()) + .backdrop(&image_filter); + + let blur_layer = self.canvas.save(); + if style.corner_radius.is_round() { + self.canvas.clip_rrect(render_rect, ClipOp::Intersect, true); + } + self.canvas.save_layer(&rec); + self.canvas.restore_to_count(blur_layer); + } + } + for opacity in effect_state.opacities.iter() { self.canvas.save_layer_alpha_f(layer_bounds, *opacity); } @@ -170,36 +194,6 @@ impl RenderPipeline<'_> { element.render(render_context); }); - if let Some(effect_state) = effect_state { - let visible_area = layout_node.visible_area(); - let render_rect = element.render_rect(&visible_area, self.scale_factor as f32); - // Apply blur effect - if let Some(blur_radius) = effect_state.blur { - let style = element.style(); - - let image_filter = blur( - ( - blur_radius * self.scale_factor as f32, - blur_radius * self.scale_factor as f32, - ), - None, - None, - render_rect.rect(), - ); - if let Some(image_filter) = image_filter { - let rec = SaveLayerRec::default() - .bounds(render_rect.rect()) - .backdrop(&image_filter); - if style.corner_radius.is_round() { - self.canvas.clip_rrect(render_rect, ClipOp::Intersect, true); - self.canvas.save_layer(&rec); - } else { - self.canvas.save_layer(&rec); - } - } - } - } - self.canvas.restore_to_count(layer); } }