aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-08-23 11:02:34 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-08-23 11:02:34 +0300
commit471dc714aa31243f68686fb35c2b5e44bd9be33b (patch)
treeb6aec73786be4a4123e8c6e6359052dc9f9d0dd3 /src
parentfef665df73cf4ed4e1686f1f065d03591709db42 (diff)
downloadniri-471dc714aa31243f68686fb35c2b5e44bd9be33b.tar.gz
niri-471dc714aa31243f68686fb35c2b5e44bd9be33b.tar.bz2
niri-471dc714aa31243f68686fb35c2b5e44bd9be33b.zip
Add damage check to PW screencasts
Avoids unnecessary frames.
Diffstat (limited to 'src')
-rw-r--r--src/niri.rs10
-rw-r--r--src/pw_utils.rs30
2 files changed, 32 insertions, 8 deletions
diff --git a/src/niri.rs b/src/niri.rs
index 27696749..431a42f8 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -3657,9 +3657,8 @@ impl Niri {
let elements = elements.get_or_insert_with(|| {
self.render(renderer, output, true, RenderTarget::Screencast)
});
- let elements = elements.iter().rev();
- if cast.dequeue_buffer_and_render(renderer, elements, size, scale) {
+ if cast.dequeue_buffer_and_render(renderer, &elements, size, scale) {
cast.last_frame_time = target_presentation_time;
}
}
@@ -3717,9 +3716,9 @@ impl Niri {
}
// FIXME: pointer.
- let elements = mapped.render_for_screen_cast(renderer, scale).rev();
+ let elements: Vec<_> = mapped.render_for_screen_cast(renderer, scale).collect();
- if cast.dequeue_buffer_and_render(renderer, elements, bbox.size, scale) {
+ if cast.dequeue_buffer_and_render(renderer, &elements, bbox.size, scale) {
cast.last_frame_time = target_presentation_time;
}
}
@@ -3802,9 +3801,8 @@ impl Niri {
.rev()
.collect::<Vec<_>>()
});
- let elements = elements.iter();
- if cast.dequeue_buffer_and_render(renderer, elements, bbox.size, scale) {
+ if cast.dequeue_buffer_and_render(renderer, &elements, bbox.size, scale) {
cast.last_frame_time = target_presentation_time;
}
}
diff --git a/src/pw_utils.rs b/src/pw_utils.rs
index 281fb3a9..d7c3c44d 100644
--- a/src/pw_utils.rs
+++ b/src/pw_utils.rs
@@ -31,6 +31,7 @@ use smithay::backend::allocator::format::FormatSet;
use smithay::backend::allocator::gbm::{GbmBuffer, GbmBufferFlags, GbmDevice};
use smithay::backend::allocator::{Format, Fourcc};
use smithay::backend::drm::DrmDeviceFd;
+use smithay::backend::renderer::damage::OutputDamageTracker;
use smithay::backend::renderer::element::RenderElement;
use smithay::backend::renderer::gles::GlesRenderer;
use smithay::output::WeakOutput;
@@ -87,6 +88,8 @@ pub enum CastState {
alpha: bool,
modifier: Modifier,
plane_count: i32,
+ // Lazily-initialized to keep the initialization to a single place.
+ damage_tracker: Option<OutputDamageTracker>,
},
}
@@ -417,6 +420,7 @@ impl PipeWire {
alpha,
modifier,
plane_count,
+ ..
} if *alpha == format_has_alpha
&& *modifier == Modifier::from(format.modifier()) =>
{
@@ -425,6 +429,13 @@ impl PipeWire {
let modifier = *modifier;
let plane_count = *plane_count;
+ let damage_tracker =
+ if let CastState::Ready { damage_tracker, .. } = &mut *state {
+ damage_tracker.take()
+ } else {
+ None
+ };
+
debug!("pw stream: moving to ready state");
*state = CastState::Ready {
@@ -432,6 +443,7 @@ impl PipeWire {
alpha,
modifier,
plane_count,
+ damage_tracker,
};
plane_count
@@ -464,6 +476,7 @@ impl PipeWire {
alpha: format_has_alpha,
modifier,
plane_count: plane_count as i32,
+ damage_tracker: None,
};
plane_count as i32
@@ -733,10 +746,23 @@ impl Cast {
pub fn dequeue_buffer_and_render(
&mut self,
renderer: &mut GlesRenderer,
- elements: impl Iterator<Item = impl RenderElement<GlesRenderer>>,
+ elements: &[impl RenderElement<GlesRenderer>],
size: Size<i32, Physical>,
scale: Scale<f64>,
) -> bool {
+ let CastState::Ready { damage_tracker, .. } = &mut *self.state.borrow_mut() else {
+ error!("cast must be in Ready state to render");
+ return false;
+ };
+ let damage_tracker = damage_tracker
+ .get_or_insert_with(|| OutputDamageTracker::new(size, scale, Transform::Normal));
+
+ let (damage, _states) = damage_tracker.damage_output(1, elements).unwrap();
+ if damage.is_none() {
+ trace!("no damage, skipping frame");
+ return false;
+ }
+
let mut buffer = match self.stream.dequeue_buffer() {
Some(buffer) => buffer,
None => {
@@ -754,7 +780,7 @@ impl Cast {
size,
scale,
Transform::Normal,
- elements,
+ elements.iter().rev(),
) {
warn!("error rendering to dmabuf: {err:?}");
return false;