diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/niri.rs | 18 | ||||
| -rw-r--r-- | src/pw_utils.rs | 38 | ||||
| -rw-r--r-- | src/render_helpers/mod.rs | 13 |
3 files changed, 51 insertions, 18 deletions
diff --git a/src/niri.rs b/src/niri.rs index c30ea255..3dc6bf79 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -1630,24 +1630,8 @@ impl State { match &cast.target { CastTarget::Nothing => { - // Matches what we create the dynamic source with. - let size = Size::from((1, 1)); - let scale = Scale::from(1.); - - match cast.ensure_size(size) { - Ok(CastSizeChange::Ready) => (), - Ok(CastSizeChange::Pending) => return, - Err(err) => { - warn!("error updating stream size, stopping screencast: {err:?}"); - let session_id = cast.session_id; - self.niri.stop_cast(session_id); - return; - } - } - self.backend.with_primary_renderer(|renderer| { - let elements: &[MonitorRenderElement<_>] = &[]; - if cast.dequeue_buffer_and_render(renderer, elements, size, scale) { + if cast.dequeue_buffer_and_clear(renderer) { cast.last_frame_time = get_monotonic_time(); } }); diff --git a/src/pw_utils.rs b/src/pw_utils.rs index f6ad4014..a518de83 100644 --- a/src/pw_utils.rs +++ b/src/pw_utils.rs @@ -45,7 +45,7 @@ use zbus::object_server::SignalEmitter; use crate::dbus::mutter_screen_cast::{self, CursorMode}; use crate::niri::{CastTarget, State}; -use crate::render_helpers::render_to_dmabuf; +use crate::render_helpers::{clear_dmabuf, render_to_dmabuf}; use crate::utils::get_monotonic_time; // Give a 0.1 ms allowance for presentation time errors. @@ -879,6 +879,42 @@ impl Cast { true } + + pub fn dequeue_buffer_and_clear(&mut self, renderer: &mut GlesRenderer) -> bool { + // Clear out the damage tracker if we're in Ready state. + if let CastState::Ready { damage_tracker, .. } = &mut *self.state.borrow_mut() { + *damage_tracker = None; + }; + + let Some(mut buffer) = self.stream.dequeue_buffer() else { + warn!("no available buffer in pw stream, skipping clear"); + return false; + }; + + let fd = buffer.datas_mut()[0].as_raw().fd; + let dmabuf = &self.dmabufs.borrow()[&fd]; + + if let Err(err) = clear_dmabuf(renderer, dmabuf.clone()) { + warn!("error clearing dmabuf: {err:?}"); + return false; + } + + for (data, (stride, offset)) in + zip(buffer.datas_mut(), zip(dmabuf.strides(), dmabuf.offsets())) + { + let chunk = data.chunk_mut(); + *chunk.size_mut() = 1; + *chunk.stride_mut() = stride as i32; + *chunk.offset_mut() = offset; + + trace!( + "pw buffer: fd = {}, stride = {stride}, offset = {offset}", + data.as_raw().fd + ); + } + + true + } } impl CastState { diff --git a/src/render_helpers/mod.rs b/src/render_helpers/mod.rs index 369ee5c2..d8799094 100644 --- a/src/render_helpers/mod.rs +++ b/src/render_helpers/mod.rs @@ -309,6 +309,19 @@ pub fn render_to_shm( .context("expected shm buffer, but didn't get one")? } +pub fn clear_dmabuf(renderer: &mut GlesRenderer, mut dmabuf: Dmabuf) -> anyhow::Result<SyncPoint> { + let size = dmabuf.size(); + let size = size.to_logical(1, Transform::Normal).to_physical(1); + let mut target = renderer.bind(&mut dmabuf).context("error binding dmabuf")?; + let mut frame = renderer + .render(&mut target, size, Transform::Normal) + .context("error starting frame")?; + frame + .clear(Color32F::TRANSPARENT, &[Rectangle::from_size(size)]) + .context("error clearing")?; + frame.finish().context("error finishing frame") +} + fn render_elements( renderer: &mut GlesRenderer, target: &mut GlesTarget, |
