wayland.dmabuf: API improvements

This commit is contained in:
Victor Berger 2019-05-19 19:32:08 +02:00 committed by Victor Berger
parent c1f759aa00
commit 04dc563ea0
4 changed files with 31 additions and 15 deletions

View File

@ -15,6 +15,7 @@ wayland-server = { version = "0.23.2", optional = true }
wayland-commons = { version = "0.23.3", optional = true } wayland-commons = { version = "0.23.3", optional = true }
wayland-sys = { version = "0.23", optional = true } wayland-sys = { version = "0.23", optional = true }
calloop = "0.4.2" calloop = "0.4.2"
bitflags = "1"
nix = "0.13" nix = "0.13"
xkbcommon = "0.4.0" xkbcommon = "0.4.0"
tempfile = "3.0" tempfile = "3.0"

View File

@ -16,6 +16,8 @@ extern crate slog;
extern crate error_chain; extern crate error_chain;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
#[macro_use]
extern crate bitflags;
pub mod backend; pub mod backend;
pub mod utils; pub mod utils;

View File

@ -4,6 +4,8 @@
//! contents as dmabuf file descriptors. These handlers automate the aggregation of the metadata associated //! contents as dmabuf file descriptors. These handlers automate the aggregation of the metadata associated
//! with a dma buffer, and do some basic checking of the sanity of what the client sends. //! with a dma buffer, and do some basic checking of the sanity of what the client sends.
//! //!
//! This module is only available if the `backend_drm` cargo feature is enabled.
//!
//! ## How to use //! ## How to use
//! //!
//! To setup the dmabuf global, you will need to provide 2 things: //! To setup the dmabuf global, you will need to provide 2 things:
@ -15,9 +17,9 @@
//! couples you support. //! couples you support.
//! //!
//! The implementation of the `DmabufHandler` trait will be called whenever a client has finished setting up //! The implementation of the `DmabufHandler` trait will be called whenever a client has finished setting up
//! a dma buffer. You will be handled the full details of the sclient's submission as a `BufferInfo` struct, //! a dma buffer. You will be handled the full details of the client's submission as a `BufferInfo` struct,
//! and you need to validate it and maybe import it into your rendered. The `BufferData` associated type //! and you need to validate it and maybe import it into your renderer. The `BufferData` associated type
//! allows you to store any metadata of handle to the resource you need into the created `wl_buffer`, //! allows you to store any metadata or handle to the resource you need into the created `wl_buffer`,
//! user data, to then retrieve it when it is attached to a surface to re-identify the dmabuf. //! user data, to then retrieve it when it is attached to a surface to re-identify the dmabuf.
//! //!
//! ``` //! ```
@ -35,7 +37,7 @@
//! fn drop(&mut self) { //! fn drop(&mut self) {
//! // This is called when all handles to this buffer have been dropped, //! // This is called when all handles to this buffer have been dropped,
//! // both client-side and server side. //! // both client-side and server side.
//! // You can now free the associated resource in your renderer. //! // You can now free the associated resources in your renderer.
//! } //! }
//! } //! }
//! //!
@ -79,10 +81,7 @@ use wayland_server::{protocol::wl_buffer, Display, Global, NewResource};
/// Representation of a Dmabuf format, as advertized to the client /// Representation of a Dmabuf format, as advertized to the client
pub struct Format { pub struct Format {
/// The format identifier. /// The format identifier.
/// pub format: ::drm::buffer::PixelFormat,
/// It must be a `DRM_FORMAT` code, as defined by the libdrm's drm_fourcc.h. The Linux kernel's DRM
/// sub-system is the authoritative source on how the format codes should work.
pub format: u32,
/// The supported dmabuf layout modifier. /// The supported dmabuf layout modifier.
/// ///
/// This is an opaque token. Drivers use this token to express tiling, compression, etc. driver-specific /// This is an opaque token. Drivers use this token to express tiling, compression, etc. driver-specific
@ -106,6 +105,17 @@ pub struct Plane {
pub modifier: u64, pub modifier: u64,
} }
bitflags! {
pub struct BufferFlags: u32 {
/// The buffer content is Y-inverted
const YInvert = 1;
/// The buffer content is interlaced
const Interlaced = 2;
/// The buffer content if interlaced is bottom-field first
const BottomFirst = 4;
}
}
/// The complete information provided by the client to create a dmabuf buffer /// The complete information provided by the client to create a dmabuf buffer
pub struct BufferInfo { pub struct BufferInfo {
/// The submitted planes /// The submitted planes
@ -119,7 +129,7 @@ pub struct BufferInfo {
/// The flags applied to it /// The flags applied to it
/// ///
/// This is a bitflag, to be compared with the `Flags` enum reexported by this module. /// This is a bitflag, to be compared with the `Flags` enum reexported by this module.
pub flags: u32, pub flags: BufferFlags,
} }
/// Handler trait for dmabuf validation /// Handler trait for dmabuf validation
@ -213,9 +223,9 @@ where
// send the supported formats // send the supported formats
for f in &*formats { for f in &*formats {
dmabuf.format(f.format); dmabuf.format(f.format.as_raw());
if version >= 3 { if version >= 3 {
dmabuf.modifier(f.format, (f.modifier >> 32) as u32, f.modifier as u32); dmabuf.modifier(f.format.as_raw(), (f.modifier >> 32) as u32, f.modifier as u32);
} }
} }
}) })
@ -303,7 +313,7 @@ impl<H: DmabufHandler> ParamRequestHandler for ParamsHandler<H> {
width, width,
height, height,
format, format,
flags, flags: BufferFlags::from_bits_truncate(flags),
}; };
let mut handler = self.handler.borrow_mut(); let mut handler = self.handler.borrow_mut();
if let Ok(data) = handler.validate_dmabuf(info) { if let Ok(data) = handler.validate_dmabuf(info) {
@ -356,7 +366,7 @@ impl<H: DmabufHandler> ParamRequestHandler for ParamsHandler<H> {
width, width,
height, height,
format, format,
flags, flags: BufferFlags::from_bits_truncate(flags),
}; };
let mut handler = self.handler.borrow_mut(); let mut handler = self.handler.borrow_mut();
if let Ok(data) = handler.validate_dmabuf(info) { if let Ok(data) = handler.validate_dmabuf(info) {
@ -385,7 +395,7 @@ fn buffer_basic_checks(
) -> bool { ) -> bool {
// protocol_checks: // protocol_checks:
// This must be a known format // This must be a known format
let format = match formats.iter().find(|f| f.format == format) { let format = match formats.iter().find(|f| f.format.as_raw() == format) {
Some(f) => f, Some(f) => f,
None => { None => {
params.as_ref().post_error( params.as_ref().post_error(
@ -401,7 +411,7 @@ fn buffer_basic_checks(
params.as_ref().post_error( params.as_ref().post_error(
ParamError::Incomplete as u32, ParamError::Incomplete as u32,
format!( format!(
"Format {:x} requires {} planes but got {}.", "Format {:?} requires {} planes but got {}.",
format.format, format.plane_count, max_plane_set format.format, format.plane_count, max_plane_set
), ),
); );
@ -433,6 +443,8 @@ fn buffer_basic_checks(
Some(e) => e, Some(e) => e,
}; };
if let Ok(size) = ::nix::unistd::lseek(plane.fd, 0, ::nix::unistd::Whence::SeekEnd) { if let Ok(size) = ::nix::unistd::lseek(plane.fd, 0, ::nix::unistd::Whence::SeekEnd) {
// reset the seek point
let _ = ::nix::unistd::lseek(plane.fd, 0, ::nix::unistd::Whence::SeekSet);
if plane.offset as i64 > size { if plane.offset as i64 > size {
params.as_ref().post_error( params.as_ref().post_error(
ParamError::OutOfBounds as u32, ParamError::OutOfBounds as u32,

View File

@ -16,6 +16,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
pub mod compositor; pub mod compositor;
pub mod data_device; pub mod data_device;
#[cfg(feature = "backend_drm")]
pub mod dmabuf; pub mod dmabuf;
pub mod output; pub mod output;
pub mod seat; pub mod seat;