diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-08-03 13:29:48 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-08-04 14:36:34 +0200 |
| commit | 15b4acc17ee2c8ac31f7e6093df57aa66e6bc2de (patch) | |
| tree | bb80b4b84e85e1add23a78c0e7321b29348ae554 /src | |
| parent | 43577f4d97bdf00e6df47005499e74968193ff92 (diff) | |
| download | niri-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.rs | 92 |
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; +} |
