Have .mmap member for Buffer for both shm and dmabuf

This commit is contained in:
Ian Douglas Scott 2024-01-26 14:21:58 -08:00
parent 2164c1ea5a
commit d869a29be7

View file

@ -9,7 +9,7 @@ use cctk::{
}; };
use cosmic::cctk; use cosmic::cctk;
use cosmic::iced::widget::image; use cosmic::iced::widget::image;
use memmap2::MmapMut; use memmap2::Mmap;
use rustix::{io::Errno, shm::ShmOFlags}; use rustix::{io::Errno, shm::ShmOFlags};
use std::{ use std::{
os::fd::{AsFd, OwnedFd}, os::fd::{AsFd, OwnedFd},
@ -68,7 +68,6 @@ fn create_memfile() -> rustix::io::Result<OwnedFd> {
enum BufferBacking { enum BufferBacking {
Shm { Shm {
fd: OwnedFd, fd: OwnedFd,
mmap: MmapMut,
}, },
Dmabuf { Dmabuf {
fd: OwnedFd, fd: OwnedFd,
@ -81,10 +80,14 @@ pub struct Buffer {
backing: BufferBacking, backing: BufferBacking,
pub buffer: wl_buffer::WlBuffer, pub buffer: wl_buffer::WlBuffer,
pub buffer_info: BufferInfo, pub buffer_info: BufferInfo,
mmap: Mmap,
} }
impl AppData { impl AppData {
fn create_shm_backing(&self, buffer_info: &BufferInfo) -> (BufferBacking, wl_buffer::WlBuffer) { fn create_shm_backing(
&self,
buffer_info: &BufferInfo,
) -> (BufferBacking, Mmap, wl_buffer::WlBuffer) {
let fd = create_memfile().unwrap(); // XXX? let fd = create_memfile().unwrap(); // XXX?
rustix::fs::ftruncate(&fd, buffer_info.stride as u64 * buffer_info.height as u64); rustix::fs::ftruncate(&fd, buffer_info.stride as u64 * buffer_info.height as u64);
@ -106,9 +109,9 @@ impl AppData {
(), (),
); );
let mmap = unsafe { MmapMut::map_mut(&fd).unwrap() }; let mmap = unsafe { Mmap::map(&fd).unwrap() };
(BufferBacking::Shm { fd, mmap }, buffer) (BufferBacking::Shm { fd }, mmap, buffer)
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -116,7 +119,7 @@ impl AppData {
&self, &self,
buffer_info: &BufferInfo, buffer_info: &BufferInfo,
needs_linear: bool, needs_linear: bool,
) -> anyhow::Result<Option<(BufferBacking, wl_buffer::WlBuffer)>> { ) -> anyhow::Result<Option<(BufferBacking, Mmap, wl_buffer::WlBuffer)>> {
let (Some((node, gbm)), Some(feedback)) = let (Some((node, gbm)), Some(feedback)) =
(self.gbm.as_ref(), self.dmabuf_feedback.as_ref()) (self.gbm.as_ref(), self.dmabuf_feedback.as_ref())
else { else {
@ -179,12 +182,16 @@ impl AppData {
) )
.0; .0;
// Is there any cost to mmapping dma memory if it isn't accessed?
let mmap = unsafe { Mmap::map(&fd).unwrap() };
Ok(Some(( Ok(Some((
BufferBacking::Dmabuf { BufferBacking::Dmabuf {
fd, fd,
node: node.clone(), node: node.clone(),
stride, stride,
}, },
mmap,
buffer, buffer,
))) )))
} }
@ -199,9 +206,10 @@ impl AppData {
.find(|x| x.type_ == WEnum::Value(BufferType::Dmabuf) && x.format == format) .find(|x| x.type_ == WEnum::Value(BufferType::Dmabuf) && x.format == format)
{ {
match self.create_gbm_backing(buffer_info, true) { match self.create_gbm_backing(buffer_info, true) {
Ok(Some((backing, buffer))) => { Ok(Some((backing, mmap, buffer))) => {
return Buffer { return Buffer {
backing, backing,
mmap,
buffer, buffer,
buffer_info: buffer_info.clone(), buffer_info: buffer_info.clone(),
}; };
@ -218,9 +226,10 @@ impl AppData {
.iter() .iter()
.find(|x| x.type_ == WEnum::Value(BufferType::WlShm) && x.format == format) .find(|x| x.type_ == WEnum::Value(BufferType::WlShm) && x.format == format)
.unwrap(); .unwrap();
let (backing, buffer) = self.create_shm_backing(buffer_info); let (backing, mmap, buffer) = self.create_shm_backing(buffer_info);
Buffer { Buffer {
backing, backing,
mmap,
buffer, buffer,
buffer_info: buffer_info.clone(), buffer_info: buffer_info.clone(),
} }
@ -232,18 +241,16 @@ impl Buffer {
// XXX is this at all a performance issue? // XXX is this at all a performance issue?
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
pub unsafe fn to_image(&mut self) -> image::Handle { pub unsafe fn to_image(&mut self) -> image::Handle {
let pixels = match &mut self.backing { let pixels = match &self.backing {
BufferBacking::Shm { mmap, .. } => mmap.to_vec(), BufferBacking::Shm { .. } => self.mmap.to_vec(),
// NOTE: Only will work with linear modifier // NOTE: Only will work with linear modifier
BufferBacking::Dmabuf { BufferBacking::Dmabuf {
fd, fd,
node: _, node: _,
stride, stride,
} => { } => {
// XXX Error handling?
let mmap = memmap2::Mmap::map(&*fd).unwrap();
if self.buffer_info.stride == self.buffer_info.width * 4 { if self.buffer_info.stride == self.buffer_info.width * 4 {
mmap.to_vec() self.mmap.to_vec()
} else { } else {
let width = self.buffer_info.width as usize; let width = self.buffer_info.width as usize;
let height = self.buffer_info.height as usize; let height = self.buffer_info.height as usize;
@ -252,7 +259,7 @@ impl Buffer {
let mut pixels = vec![0; height * output_stride]; let mut pixels = vec![0; height * output_stride];
for y in 0..height { for y in 0..height {
pixels[y * output_stride..y * output_stride + output_stride] pixels[y * output_stride..y * output_stride + output_stride]
.copy_from_slice(&mmap[y * stride..y * stride + output_stride]); .copy_from_slice(&self.mmap[y * stride..y * stride + output_stride]);
} }
pixels pixels
} }