diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-08-23 11:02:34 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-08-23 11:02:34 +0300 |
| commit | 471dc714aa31243f68686fb35c2b5e44bd9be33b (patch) | |
| tree | b6aec73786be4a4123e8c6e6359052dc9f9d0dd3 /src | |
| parent | fef665df73cf4ed4e1686f1f065d03591709db42 (diff) | |
| download | niri-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.rs | 10 | ||||
| -rw-r--r-- | src/pw_utils.rs | 30 |
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; |
