aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-08-03 13:29:48 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-08-04 14:36:34 +0200
commit15b4acc17ee2c8ac31f7e6093df57aa66e6bc2de (patch)
treebb80b4b84e85e1add23a78c0e7321b29348ae554 /src
parent43577f4d97bdf00e6df47005499e74968193ff92 (diff)
downloadniri-15b4acc17ee2c8ac31f7e6093df57aa66e6bc2de.tar.gz
niri-15b4acc17ee2c8ac31f7e6093df57aa66e6bc2de.tar.bz2
niri-15b4acc17ee2c8ac31f7e6093df57aa66e6bc2de.zip
pw_utils: Fill dmabuf strides and offsets at add_buffer()
As far as I understand, these don't change.
Diffstat (limited to 'src')
-rw-r--r--src/pw_utils.rs92
1 files changed, 37 insertions, 55 deletions
diff --git a/src/pw_utils.rs b/src/pw_utils.rs
index 939a1481..3c9a69b3 100644
--- a/src/pw_utils.rs
+++ b/src/pw_utils.rs
@@ -611,11 +611,15 @@ impl PipeWire {
let plane_count = dmabuf.num_planes();
assert_eq!((*spa_buffer).n_datas as usize, plane_count);
- for (i, fd) in dmabuf.handles().enumerate() {
+ for (i, (fd, (stride, offset))) in
+ zip(dmabuf.handles(), zip(dmabuf.strides(), dmabuf.offsets()))
+ .enumerate()
+ {
let spa_data = (*spa_buffer).datas.add(i);
assert!((*spa_data).type_ & (1 << DataType::DmaBuf.as_raw()) > 0);
(*spa_data).type_ = DataType::DmaBuf.as_raw();
+
// With DMA-BUFs, consumers should ignore the maxsize field, and
// producers are allowed to set it to 0.
//
@@ -623,6 +627,15 @@ impl PipeWire {
(*spa_data).maxsize = 1;
(*spa_data).fd = fd.as_raw_fd() as i64;
(*spa_data).flags = SPA_DATA_FLAG_READWRITE;
+
+ let chunk = (*spa_data).chunk;
+ (*chunk).stride = stride as i32;
+ (*chunk).offset = offset;
+
+ trace!(
+ "pw buffer plane: fd={}, stride={stride}, offset={offset}",
+ (*spa_data).fd
+ );
}
let fd = (*(*spa_buffer).datas).fd;
@@ -881,16 +894,15 @@ impl Cast {
};
let buffer = pw_buffer.as_ptr();
- let inner = self.inner.borrow_mut();
unsafe {
let spa_buffer = (*buffer).buffer;
let fd = (*(*spa_buffer).datas).fd;
- let dmabuf = &inner.dmabufs[&fd];
+ let dmabuf = self.inner.borrow().dmabufs[&fd].clone();
match render_to_dmabuf(
renderer,
- dmabuf.clone(),
+ dmabuf,
size,
scale,
Transform::Normal,
@@ -912,30 +924,7 @@ impl Cast {
}
}
- for (i, (stride, offset)) in zip(dmabuf.strides(), dmabuf.offsets()).enumerate() {
- let spa_data = (*spa_buffer).datas.add(i);
- let chunk = (*spa_data).chunk;
-
- // With DMA-BUFs, consumers should ignore the size field, and producers are allowed
- // to set it to 0.
- //
- // https://docs.pipewire.org/page_dma_buf.html
- //
- // However, OBS checks for size != 0 as a workaround for old compositor versions,
- // so we set it to 1.
- (*chunk).size = 1;
- // Clear the corrupted flag we may have set before.
- (*chunk).flags = SPA_CHUNK_FLAG_NONE as i32;
-
- (*chunk).stride = stride as i32;
- (*chunk).offset = offset;
-
- trace!(
- "pw buffer: fd = {}, stride = {stride}, offset = {offset}",
- (*spa_data).fd
- );
- }
-
+ mark_buffer_as_good(pw_buffer);
pw_stream_queue_buffer(self.stream.as_raw_ptr(), buffer);
}
@@ -961,14 +950,13 @@ impl Cast {
};
let buffer = pw_buffer.as_ptr();
- let inner = self.inner.borrow_mut();
unsafe {
let spa_buffer = (*buffer).buffer;
let fd = (*(*spa_buffer).datas).fd;
- let dmabuf = &inner.dmabufs[&fd];
+ let dmabuf = self.inner.borrow().dmabufs[&fd].clone();
- match clear_dmabuf(renderer, dmabuf.clone()) {
+ match clear_dmabuf(renderer, dmabuf) {
Ok(sync_point) => {
// FIXME: implement PipeWire explicit sync, and at the very least async wait.
if wait_for_sync {
@@ -985,30 +973,7 @@ impl Cast {
}
}
- for (i, (stride, offset)) in zip(dmabuf.strides(), dmabuf.offsets()).enumerate() {
- let spa_data = (*spa_buffer).datas.add(i);
- let chunk = (*spa_data).chunk;
-
- // With DMA-BUFs, consumers should ignore the size field, and producers are allowed
- // to set it to 0.
- //
- // https://docs.pipewire.org/page_dma_buf.html
- //
- // However, OBS checks for size != 0 as a workaround for old compositor versions,
- // so we set it to 1.
- (*chunk).size = 1;
- // Clear the corrupted flag we may have set before.
- (*chunk).flags = SPA_CHUNK_FLAG_NONE as i32;
-
- (*chunk).stride = stride as i32;
- (*chunk).offset = offset;
-
- trace!(
- "pw buffer: fd = {}, stride = {stride}, offset = {offset}",
- (*spa_data).fd
- );
- }
-
+ mark_buffer_as_good(pw_buffer);
pw_stream_queue_buffer(self.stream.as_raw_ptr(), buffer);
}
@@ -1194,3 +1159,20 @@ unsafe fn return_unused_buffer(stream: &Stream, pw_buffer: NonNull<pw_buffer>) {
(*chunk).flags = SPA_CHUNK_FLAG_CORRUPTED as i32;
pw_stream_queue_buffer(stream.as_raw_ptr(), pw_buffer);
}
+
+unsafe fn mark_buffer_as_good(pw_buffer: NonNull<pw_buffer>) {
+ let pw_buffer = pw_buffer.as_ptr();
+ let spa_buffer = (*pw_buffer).buffer;
+ let chunk = (*(*spa_buffer).datas).chunk;
+
+ // With DMA-BUFs, consumers should ignore the size field, and producers are allowed
+ // to set it to 0.
+ //
+ // https://docs.pipewire.org/page_dma_buf.html
+ //
+ // However, OBS checks for size != 0 as a workaround for old compositor versions,
+ // so we set it to 1.
+ (*chunk).size = 1;
+ // Clear the corrupted flag we may have set before.
+ (*chunk).flags = SPA_CHUNK_FLAG_NONE as i32;
+}