renderer/blur: Fix incorrectly offset blur region

This commit is contained in:
Victoria Brekenfeld 2026-04-10 17:50:58 +02:00 committed by Victoria Brekenfeld
parent 6868c24501
commit 667414bd92

View file

@ -148,10 +148,11 @@ pub struct BlurElement {
id: Id, id: Id,
commit: CommitCounter, commit: CommitCounter,
src: Size<f64, Buffer>, src: Size<f64, Buffer>,
extended_offset: Point<f64, Logical>,
geometry: Rectangle<f64, Logical>, geometry: Rectangle<f64, Logical>,
scaling_shaders: BlurShaders, scaling_shaders: BlurShaders,
render_shader: GlesTexProgram, render_shader: GlesTexProgram,
region: Vec<Rectangle<i32, Physical>>, region: Vec<Rectangle<i32, Logical>>,
offset: f64, offset: f64,
passes: usize, passes: usize,
uniforms: Vec<Uniform<'static>>, uniforms: Vec<Uniform<'static>>,
@ -223,6 +224,7 @@ impl BlurElement {
Ok(Some(Self::from_state( Ok(Some(Self::from_state(
renderer, renderer,
extended_geo.to_logical(output_scale), extended_geo.to_logical(output_scale),
Point::<f64, Physical>::new(radius, radius).to_logical(output_scale),
region, region,
output_scale, output_scale,
&mut state.lock().unwrap(), &mut state.lock().unwrap(),
@ -234,6 +236,7 @@ impl BlurElement {
fn from_state<R: AsGlowRenderer>( fn from_state<R: AsGlowRenderer>(
renderer: &mut R, renderer: &mut R,
geometry: Rectangle<f64, Logical>, geometry: Rectangle<f64, Logical>,
extended_offset: Point<f64, Logical>,
region: &Vec<Rectangle<i32, Logical>>, region: &Vec<Rectangle<i32, Logical>>,
output_scale: f64, output_scale: f64,
state: &mut BlurState, state: &mut BlurState,
@ -267,13 +270,18 @@ impl BlurElement {
commit: state.commit, commit: state.commit,
src, src,
geometry, geometry,
extended_offset,
scaling_shaders: BlurShaders::get(renderer), scaling_shaders: BlurShaders::get(renderer),
render_shader: ClippingShader::get(renderer), render_shader: ClippingShader::get(renderer),
offset: state.offset, offset: state.offset,
passes: state.passes, passes: state.passes,
region: region region: region
.iter() .iter()
.map(|rect| rect.to_physical_precise_round(output_scale)) .cloned()
.map(|mut rect| {
rect.loc += extended_offset.to_i32_round();
rect
})
.collect(), .collect(),
uniforms, uniforms,
}) })
@ -307,7 +315,15 @@ impl Element for BlurElement {
commit: Option<CommitCounter>, commit: Option<CommitCounter>,
) -> DamageSet<i32, Physical> { ) -> DamageSet<i32, Physical> {
if self.commit.distance(commit).is_none_or(|d| d > 0) { if self.commit.distance(commit).is_none_or(|d| d > 0) {
DamageSet::from_slice(&[self.geometry.to_physical_precise_round(scale)]) DamageSet::from_slice(&[Rectangle::new(
self.extended_offset.to_physical_precise_round(scale),
self.geometry.size.to_physical_precise_round(scale)
- self
.extended_offset
.to_size()
.upscale(2.)
.to_physical_precise_round(scale),
)])
} else { } else {
DamageSet::default() DamageSet::default()
} }
@ -391,10 +407,21 @@ impl<R: Renderer + AsGlowRenderer> RenderElement<R> for BlurElement {
cache: Option<&UserDataMap>, cache: Option<&UserDataMap>,
) -> Result<(), R::Error> { ) -> Result<(), R::Error> {
let glow_frame = <R as AsGlowRenderer>::glow_frame_mut(frame); let glow_frame = <R as AsGlowRenderer>::glow_frame_mut(frame);
let src_to_geo = self.geometry.size / self.src;
let src_log = src
.upscale(src_to_geo)
.to_logical(1., Transform::Normal, &Size::default());
let scale = dst.size.to_f64() / src_log.size;
let damage = self let damage = self
.region .region
.iter() .iter()
.flat_map(|rect| damage.iter().flat_map(|r| r.intersection(*rect))) .flat_map(|rect| {
let mut rect = rect.to_f64().intersection(src_log)?;
rect.loc -= src_log.loc;
Some(rect.to_physical_precise_round(scale))
})
.flat_map(|rect| damage.iter().flat_map(move |r| r.intersection(rect)))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let cache = cache.expect("Framebuffer element without cache?"); let cache = cache.expect("Framebuffer element without cache?");
let Some(texture) = cache.get::<BlurTexture>() else { let Some(texture) = cache.get::<BlurTexture>() else {