diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-03-01 09:45:57 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-03-10 07:59:14 +0300 |
| commit | 266c6c3878ba6f0c08f45c025dddc8dc8a1b2f0e (patch) | |
| tree | 1470c27a9c832e751907f6ceac16abca2062b0a4 | |
| parent | 7b033aa7c6ed4b634224b001b3514276b9c06c64 (diff) | |
| download | niri-266c6c3878ba6f0c08f45c025dddc8dc8a1b2f0e.tar.gz niri-266c6c3878ba6f0c08f45c025dddc8dc8a1b2f0e.tar.bz2 niri-266c6c3878ba6f0c08f45c025dddc8dc8a1b2f0e.zip | |
offscreen: Don't recreate if size decreased
| -rw-r--r-- | src/render_helpers/offscreen.rs | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/src/render_helpers/offscreen.rs b/src/render_helpers/offscreen.rs index 5d33f8e8..1a4cc2c8 100644 --- a/src/render_helpers/offscreen.rs +++ b/src/render_helpers/offscreen.rs @@ -52,6 +52,7 @@ pub struct OffscreenRenderElement { scale: Scale<f64>, damage: DamageSnapshot<i32, Buffer>, offset: Point<f64, Logical>, + src_size: Size<i32, Buffer>, alpha: f32, kind: Kind, } @@ -70,7 +71,8 @@ impl OffscreenBuffer { RelocateRenderElement::from_element(ele, geo.loc.upscale(-1), Relocate::Relative) })); - let buffer_size = geo.size.to_logical(1).to_buffer(1, Transform::Normal); + let src_size = geo.size; + let src_size = src_size.to_logical(1).to_buffer(1, Transform::Normal); let offset = geo.loc.to_f64().to_logical(scale); let mut inner = self.inner.borrow_mut(); @@ -85,10 +87,10 @@ impl OffscreenBuffer { }) = inner.as_mut() { let old_size = texture.size(); - if old_size != buffer_size { + if old_size.w < src_size.w || old_size.h < src_size.h { size_string = format!( - "size changed from {} × {} to {} × {}", - old_size.w, old_size.h, buffer_size.w, buffer_size.h + "size increased from {} × {} to {} × {}", + old_size.w, old_size.h, src_size.w, src_size.h ); reason = &size_string; @@ -114,10 +116,11 @@ impl OffscreenBuffer { span.emit_text(reason); let texture: GlesTexture = renderer - .create_buffer(Fourcc::Abgr8888, buffer_size) + .create_buffer(Fourcc::Abgr8888, src_size) .context("error creating texture")?; - let damage = OutputDamageTracker::new(geo.size, scale, Transform::Normal); + let buffer_size = src_size.to_logical(1, Transform::Normal).to_physical(1); + let damage = OutputDamageTracker::new(buffer_size, scale, Transform::Normal); inner.insert(Inner { texture, @@ -128,13 +131,17 @@ impl OffscreenBuffer { }) }; + // When leaving the old texture as is, its size might be bigger than src_size. + let texture_size = inner.texture.size(); + let buffer_size = texture_size.to_logical(1, Transform::Normal).to_physical(1); + // Recreate the damage tracker if the scale changes. We already recreate it for buffer size // changes, and transform is always Normal. if inner.scale != scale { inner.scale = scale; trace!("recreating damage tracker due to scale change"); - inner.damage = OutputDamageTracker::new(geo.size, scale, Transform::Normal); + inner.damage = OutputDamageTracker::new(buffer_size, scale, Transform::Normal); inner.outer_damage = DamageBag::default(); } @@ -153,7 +160,7 @@ impl OffscreenBuffer { if let Some(damage) = res.damage { // OutputDamageTracker gives us Physical coordinate space, but it's actually the Buffer // space because we were rendering to a texture. - let size = geo.size.to_logical(1); + let size = buffer_size.to_logical(1); let damage = damage .iter() .map(|rect| rect.to_logical(1).to_buffer(1, Transform::Normal, &size)); @@ -167,6 +174,7 @@ impl OffscreenBuffer { scale, damage: inner.outer_damage.snapshot(), offset, + src_size, alpha: 1., kind: Kind::Unspecified, }; @@ -199,8 +207,7 @@ impl OffscreenRenderElement { } pub fn logical_size(&self) -> Size<f64, Logical> { - self.texture - .size() + self.src_size .to_f64() .to_logical(self.scale, Transform::Normal) } @@ -231,7 +238,7 @@ impl Element for OffscreenRenderElement { } fn src(&self) -> Rectangle<f64, Buffer> { - Rectangle::from_size(self.texture.size()).to_f64() + Rectangle::from_size(self.src_size).to_f64() } fn damage_since( @@ -240,13 +247,18 @@ impl Element for OffscreenRenderElement { commit: Option<CommitCounter>, ) -> DamageSet<i32, Physical> { let texture_size = self.texture.size().to_f64(); + let src = self.src(); self.damage_since(commit) .into_iter() - .map(|rect| { - rect.to_f64() - .to_logical(self.scale, Transform::Normal, &texture_size) - .to_physical_precise_up(scale) + .filter_map(|region| { + let mut region = region.to_f64().intersection(src)?; + + region.loc -= src.loc; + region.upscale(texture_size / src.size); + + let logical = region.to_logical(self.scale, Transform::Normal, &src.size); + Some(logical.to_physical_precise_up(scale)) }) .collect() } |
