aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/niri.rs18
-rw-r--r--src/pw_utils.rs38
-rw-r--r--src/render_helpers/mod.rs13
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,