linux-dmabuf: intercept udmabuf buffers
This commit is contained in:
parent
0570669af2
commit
410281b13e
5 changed files with 131 additions and 32 deletions
|
|
@ -108,6 +108,7 @@ impl WlBuffer {
|
|||
stride: i32,
|
||||
format: &'static Format,
|
||||
mem: &Rc<ClientMem>,
|
||||
udmabuf: Option<(&Rc<OwnedFd>, usize)>,
|
||||
) -> Result<Self, WlBufferError> {
|
||||
let bytes = stride as u64 * height as u64;
|
||||
let required = bytes + offset as u64;
|
||||
|
|
@ -119,6 +120,26 @@ impl WlBuffer {
|
|||
if (stride as u64) < min_row_size {
|
||||
return Err(WlBufferError::StrideTooSmall);
|
||||
}
|
||||
let dmabuf_buffer_params = match udmabuf {
|
||||
None => DmabufBufferParams {
|
||||
size: bytes as usize,
|
||||
udmabuf: None,
|
||||
udmabuf_offset: 0,
|
||||
udmabuf_size: 0,
|
||||
udmabuf_impossible: !mem.pool().is_sealed_memfd(),
|
||||
host_buffer: None,
|
||||
host_buffer_impossible: !mem.pool().is_sealed_memfd(),
|
||||
},
|
||||
Some((udmabuf, size)) => DmabufBufferParams {
|
||||
size,
|
||||
udmabuf: Some(udmabuf.clone()),
|
||||
udmabuf_offset: offset,
|
||||
udmabuf_size: size,
|
||||
udmabuf_impossible: false,
|
||||
host_buffer: None,
|
||||
host_buffer_impossible: false,
|
||||
},
|
||||
};
|
||||
Ok(Self {
|
||||
id,
|
||||
destroyed: Cell::new(false),
|
||||
|
|
@ -128,15 +149,7 @@ impl WlBuffer {
|
|||
dmabuf: None,
|
||||
render_ctx_version: Cell::new(client.state.render_ctx_version.get()),
|
||||
storage: RefCell::new(Some(WlBufferStorage::Shm {
|
||||
dmabuf_buffer_params: DmabufBufferParams {
|
||||
size: bytes as usize,
|
||||
udmabuf: None,
|
||||
udmabuf_offset: 0,
|
||||
udmabuf_size: 0,
|
||||
udmabuf_impossible: !mem.pool().is_sealed_memfd(),
|
||||
host_buffer: None,
|
||||
host_buffer_impossible: !mem.pool().is_sealed_memfd(),
|
||||
},
|
||||
dmabuf_buffer_params,
|
||||
mem,
|
||||
stride,
|
||||
})),
|
||||
|
|
@ -191,9 +204,9 @@ impl WlBuffer {
|
|||
};
|
||||
let had_texture = match s {
|
||||
WlBufferStorage::Shm {
|
||||
mem,
|
||||
dmabuf_buffer_params:
|
||||
DmabufBufferParams {
|
||||
udmabuf_impossible,
|
||||
host_buffer,
|
||||
host_buffer_impossible,
|
||||
..
|
||||
|
|
@ -201,7 +214,7 @@ impl WlBuffer {
|
|||
..
|
||||
} => {
|
||||
host_buffer.take();
|
||||
*host_buffer_impossible = !mem.pool().is_sealed_memfd();
|
||||
*host_buffer_impossible = *udmabuf_impossible;
|
||||
return match surface {
|
||||
Some(s) => {
|
||||
s.shm_staging.take();
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ impl WlShmPool {
|
|||
false,
|
||||
Some(client),
|
||||
Some(&client.state.cpu_worker),
|
||||
false,
|
||||
)?)),
|
||||
fd,
|
||||
tracker: Default::default(),
|
||||
|
|
@ -68,6 +69,7 @@ impl WlShmPoolRequestHandler for WlShmPool {
|
|||
req.stride,
|
||||
format,
|
||||
&self.mem.get(),
|
||||
None,
|
||||
)?);
|
||||
track!(self.client, buffer);
|
||||
self.client.add_client_obj(&buffer)?;
|
||||
|
|
@ -92,6 +94,7 @@ impl WlShmPoolRequestHandler for WlShmPool {
|
|||
false,
|
||||
Some(&self.client),
|
||||
Some(&self.client.state.cpu_worker),
|
||||
false,
|
||||
)?));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
use {
|
||||
crate::{
|
||||
client::ClientError,
|
||||
clientmem::{ClientMem, ClientMemError},
|
||||
gfx_api::GfxError,
|
||||
ifs::{wl_buffer::WlBuffer, zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1},
|
||||
ifs::{
|
||||
wl_buffer::{WlBuffer, WlBufferError},
|
||||
zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::Object,
|
||||
utils::{errorfmt::ErrorFmt, hash_map_ext::HashMapExt},
|
||||
|
|
@ -102,25 +106,52 @@ impl ZwpLinuxBufferParamsV1 {
|
|||
fd: p.fd,
|
||||
});
|
||||
}
|
||||
let img = ctx.dmabuf_img(&dmabuf)?;
|
||||
let (is_client_id, buffer_id) = match buffer_id {
|
||||
Some(i) => (true, i),
|
||||
None => (false, self.parent.client.new_id()?),
|
||||
let get_id = || match buffer_id {
|
||||
None => self.parent.client.new_id(),
|
||||
Some(i) => Ok(i),
|
||||
};
|
||||
let buffer = if format.supports_shm
|
||||
&& let Some(size) = dmabuf.udmabuf_size()
|
||||
{
|
||||
let p = &dmabuf.planes[0];
|
||||
let client_mem = ClientMem::new(
|
||||
&p.fd,
|
||||
size,
|
||||
true,
|
||||
Some(&self.parent.client),
|
||||
Some(&self.parent.client.state.cpu_worker),
|
||||
true,
|
||||
)
|
||||
.map(Rc::new)
|
||||
.map_err(ZwpLinuxBufferParamsV1Error::CreateClientMem)?;
|
||||
Rc::new(WlBuffer::new_shm(
|
||||
get_id()?,
|
||||
&self.parent.client,
|
||||
p.offset as usize,
|
||||
dmabuf.width,
|
||||
dmabuf.height,
|
||||
p.stride as _,
|
||||
format.format,
|
||||
&client_mem,
|
||||
Some((&p.fd, size)),
|
||||
)?)
|
||||
} else {
|
||||
let img = ctx.dmabuf_img(&dmabuf)?;
|
||||
Rc::new(WlBuffer::new_dmabuf(
|
||||
get_id()?,
|
||||
&self.parent.client,
|
||||
format.format,
|
||||
dmabuf,
|
||||
&img,
|
||||
))
|
||||
};
|
||||
let buffer = Rc::new(WlBuffer::new_dmabuf(
|
||||
buffer_id,
|
||||
&self.parent.client,
|
||||
format.format,
|
||||
dmabuf,
|
||||
&img,
|
||||
));
|
||||
track!(self.parent.client, buffer);
|
||||
if is_client_id {
|
||||
if buffer_id.is_some() {
|
||||
self.parent.client.add_client_obj(&buffer)?;
|
||||
} else {
|
||||
self.parent.client.add_server_obj(&buffer);
|
||||
}
|
||||
Ok(buffer_id)
|
||||
Ok(buffer.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,5 +249,10 @@ pub enum ZwpLinuxBufferParamsV1Error {
|
|||
MissingPlane(usize),
|
||||
#[error("Could not import the buffer")]
|
||||
ImportError(#[from] GfxError),
|
||||
#[error("Could not create ClientMem")]
|
||||
CreateClientMem(#[source] ClientMemError),
|
||||
#[error(transparent)]
|
||||
WlBufferError(Box<WlBufferError>),
|
||||
}
|
||||
efrom!(ZwpLinuxBufferParamsV1Error, ClientError);
|
||||
efrom!(ZwpLinuxBufferParamsV1Error, WlBufferError);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue