aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-03-01 09:45:57 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-03-10 07:59:14 +0300
commit266c6c3878ba6f0c08f45c025dddc8dc8a1b2f0e (patch)
tree1470c27a9c832e751907f6ceac16abca2062b0a4
parent7b033aa7c6ed4b634224b001b3514276b9c06c64 (diff)
downloadniri-266c6c3878ba6f0c08f45c025dddc8dc8a1b2f0e.tar.gz
niri-266c6c3878ba6f0c08f45c025dddc8dc8a1b2f0e.tar.bz2
niri-266c6c3878ba6f0c08f45c025dddc8dc8a1b2f0e.zip
offscreen: Don't recreate if size decreased
-rw-r--r--src/render_helpers/offscreen.rs42
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()
}