Merge pull request #385 from Smithay/feature/dmabuf_filter

This commit is contained in:
Victor Brekenfeld 2021-09-30 21:47:57 +02:00 committed by GitHub
commit dd6919dd5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 69 deletions

View File

@ -22,6 +22,7 @@
- Setting the parent of a toplevel surface is now possible with the `xdg::ToplevelSurface::set_parent` function. - Setting the parent of a toplevel surface is now possible with the `xdg::ToplevelSurface::set_parent` function.
- Add support for the zxdg-foreign-v2 protocol. - Add support for the zxdg-foreign-v2 protocol.
- Support for `xdg_wm_base` protocol version 3 - Support for `xdg_wm_base` protocol version 3
- Added the option to initialize the dmabuf global with a client filter
### Bugfixes ### Bugfixes

View File

@ -54,7 +54,7 @@ use wayland_protocols::unstable::linux_dmabuf::v1::server::{
}, },
zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1,
}; };
use wayland_server::{protocol::wl_buffer, DispatchData, Display, Filter, Global, Main}; use wayland_server::{protocol::wl_buffer, Client, DispatchData, Display, Filter, Global, Main};
use slog::{o, trace}; use slog::{o, trace};
@ -63,9 +63,7 @@ use crate::backend::allocator::{
Format, Fourcc, Modifier, Format, Fourcc, Modifier,
}; };
/// Handler trait for dmabuf validation const DMABUF_VERSION: u32 = 3;
///
/// You need to provide an implementation of this trait
/// Initialize a dmabuf global. /// Initialize a dmabuf global.
/// ///
@ -77,6 +75,37 @@ pub fn init_dmabuf_global<F, L>(
handler: F, handler: F,
logger: L, logger: L,
) -> Global<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1> ) -> Global<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>
where
L: Into<Option<::slog::Logger>>,
F: for<'a> FnMut(&Dmabuf, DispatchData<'a>) -> bool + 'static,
{
display.create_global(DMABUF_VERSION, dmabuf_global(formats, handler, logger))
}
/// Initialize a dmabuf global with a client filter.
///
/// You need to provide a vector of the supported formats, as well as a closure,
/// that will validate the parameters provided by the client and tests the import as a dmabuf.
pub fn init_dmabuf_global_with_filter<H, F, L>(
display: &mut Display,
formats: Vec<Format>,
handler: H,
filter: F,
logger: L,
) -> Global<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>
where
L: Into<Option<::slog::Logger>>,
H: for<'a> FnMut(&Dmabuf, DispatchData<'a>) -> bool + 'static,
F: FnMut(Client) -> bool + 'static,
{
display.create_global_with_filter(DMABUF_VERSION, dmabuf_global(formats, handler, logger), filter)
}
fn dmabuf_global<F, L>(
formats: Vec<Format>,
handler: F,
logger: L,
) -> Filter<(Main<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>, u32)>
where where
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
F: for<'a> FnMut(&Dmabuf, DispatchData<'a>) -> bool + 'static, F: for<'a> FnMut(&Dmabuf, DispatchData<'a>) -> bool + 'static,
@ -92,72 +121,67 @@ where
formats.len() formats.len()
); );
display.create_global( Filter::new(
3, move |(dmabuf, version): (Main<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>, u32), _, _| {
Filter::new( let dma_formats = formats.clone();
move |(dmabuf, version): (Main<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>, u32), _, _| { let dma_handler = handler.clone();
let dma_formats = formats.clone(); let dma_log = log.clone();
let dma_handler = handler.clone(); dmabuf.quick_assign(move |_, req, _| {
let dma_log = log.clone(); if let zwp_linux_dmabuf_v1::Request::CreateParams { params_id } = req {
dmabuf.quick_assign(move |_, req, _| { let mut handler = ParamsHandler {
if let zwp_linux_dmabuf_v1::Request::CreateParams { params_id } = req { pending_planes: Vec::new(),
let mut handler = ParamsHandler { max_planes: 4,
pending_planes: Vec::new(), used: false,
max_planes: 4, formats: dma_formats.clone(),
used: false, handler: dma_handler.clone(),
formats: dma_formats.clone(), log: dma_log.clone(),
handler: dma_handler.clone(), };
log: dma_log.clone(), params_id.quick_assign(move |params, req, ddata| match req {
}; ParamsRequest::Add {
params_id.quick_assign(move |params, req, ddata| match req { fd,
ParamsRequest::Add { plane_idx,
fd, offset,
plane_idx, stride,
offset, modifier_hi,
stride, modifier_lo,
modifier_hi, } => handler.add(
modifier_lo, &*params,
} => handler.add( fd,
&*params, plane_idx,
fd, offset,
plane_idx, stride,
offset, ((modifier_hi as u64) << 32) + (modifier_lo as u64),
stride, ),
((modifier_hi as u64) << 32) + (modifier_lo as u64), ParamsRequest::Create {
), width,
ParamsRequest::Create { height,
width, format,
height, flags,
format, } => handler.create(&*params, width, height, format, flags, ddata),
flags, ParamsRequest::CreateImmed {
} => handler.create(&*params, width, height, format, flags, ddata), buffer_id,
ParamsRequest::CreateImmed { width,
buffer_id, height,
width, format,
height, flags,
format, } => handler.create_immed(&*params, buffer_id, width, height, format, flags, ddata),
flags, _ => {}
} => { });
handler.create_immed(&*params, buffer_id, width, height, format, flags, ddata)
}
_ => {}
});
}
});
// send the supported formats
for f in &*formats {
dmabuf.format(f.code as u32);
if version >= 3 {
dmabuf.modifier(
f.code as u32,
(Into::<u64>::into(f.modifier) >> 32) as u32,
Into::<u64>::into(f.modifier) as u32,
);
}
} }
}, });
),
// send the supported formats
for f in &*formats {
dmabuf.format(f.code as u32);
if version >= 3 {
dmabuf.modifier(
f.code as u32,
(Into::<u64>::into(f.modifier) >> 32) as u32,
Into::<u64>::into(f.modifier) as u32,
);
}
}
},
) )
} }