wayland_frontend only.Expand description
Linux DMABUF protocol
This module provides helper to handle the linux-dmabuf protocol, which allows clients to submit their 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.
§How to use
To setup the dmabuf global, you will need to provide 2 things:
- the default
DmabufFeedbackcontaining the main device and the formats you wish to support when creating theGlobalthroughDmabufState::create_global_with_default_feedback - an implementation of
DmabufHandlerto test if a dmabuf buffer can be imported by your renderer and optionally override the initial surface feedback
The list of supported formats is a Vec<Format>, where you will enter all the (code, modifier) pairs you
support. You can typically receive a list of supported formats for one renderer by calling
ImportDma::dmabuf_formats.
use smithay::{
delegate_dmabuf,
backend::allocator::dmabuf::{Dmabuf},
reexports::{
wayland_server::protocol::{
wl_buffer::WlBuffer,
wl_surface::WlSurface,
}
},
wayland::{
buffer::BufferHandler,
dmabuf::{DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier}
},
};
pub struct State {
dmabuf_state: DmabufState,
dmabuf_global: DmabufGlobal,
}
// Smithay's "DmabufHandler" also requires the buffer management utilities, you need to implement
// "BufferHandler".
impl BufferHandler for State {
fn buffer_destroyed(&mut self, buffer: &wayland_server::protocol::wl_buffer::WlBuffer) {
// All renderers can handle buffer destruction at this point. Some parts of window management may
// also use this function.
//
// If you need to mark a dmabuf elsewhere in your state as destroyed, you use the "get_dmabuf"
// function defined in this module to access the dmabuf associated the "Buffer".
}
}
impl DmabufHandler for State {
fn dmabuf_state(&mut self) -> &mut DmabufState {
&mut self.dmabuf_state
}
fn dmabuf_imported(&mut self, global: &DmabufGlobal, dmabuf: Dmabuf, notifier: ImportNotifier) {
// Here you should import the dmabuf into your renderer.
//
// The notifier is used to communicate whether import was successful. In this example we
// call successful to notify the client import was successful.
notifier.successful::<State>();
}
fn new_surface_feedback(
&mut self,
surface: &WlSurface,
global: &DmabufGlobal,
) -> Option<DmabufFeedback> {
// Here you can override the initial feedback sent to a client requesting feedback for a specific
// surface. Returning `None` instructs the global to return the default feedback to the client which
// is also the default implementation for this function when not overridden
None
}
}
// Delegate dmabuf handling for State to DmabufState.
delegate_dmabuf!(State);
// First a DmabufState must be created. This type is used to create some "DmabufGlobal"s
let mut dmabuf_state = DmabufState::new();
// ...identify primary render node and load dmabuf formats supported for rendering...
// Build the default feedback from the device node of the primary render node and
// the supported dmabuf formats
let default_feedback = DmabufFeedbackBuilder::new(main_device, formats).build().unwrap();
// And create the dmabuf global.
let dmabuf_global = dmabuf_state.create_global_with_default_feedback::<State>(
&display_handle,
&default_feedback,
);
let state = State {
dmabuf_state,
dmabuf_global,
};
// Rest of the compositor goes here...Accessing a Dmabuf associated with a WlBuffer
may be achieved using get_dmabuf.
§Notes on supporting per surface feedback
If a client requests DmabufFeedback for a specific WlSurface it can be used to inform the client about
sub-optimal buffer allocations. This is especially important to support direct scan-out over drm planes
that typically only support a subset of supported formats from the rendering formats.
The DmabufFeedback of a specific WlSurface can be updated by retrieving the SurfaceDmabufFeedbackState
with SurfaceDmabufFeedbackState::from_states and setting the feedback with SurfaceDmabufFeedbackState::set_feedback.
DmabufFeedback uses preference tranches to inform the client about formats that could result on more optimal buffer placement.
Preference tranches can be added to the feedback during initialization with DmabufFeedbackBuilder::add_preference_tranche.
Note that the order of formats within a tranche (target_device + flags) is undefined, if you want to communicate preference
of a specific format you have to split the formats into multiple tranches. A tranche can additionally define TrancheFlags
which can give clients additional context what the tranche represents. As an example formats gathered from drm planes
should define TrancheFlags::Scanout to communicate that buffers should be allocated so that
they support scan-out by the device specified as the target device.
Note: Surface feedback only represents an optimization and the fallback path using compositing should always be supported, so typically you do not want to announce formats in a preference tranche that are not supported by the main device for rendering.
§Notes on clients binding version 3 or lower
During instantiation the global will automatically build a format list from the provided DmabufFeedback consisting of all formats that are part of a tranche
having the target device equal the main device and defining no special TrancheFlags.
§Without feedback (v3)
It is also possible to initialize the Global without support for DmabufFeedback by using DmabufState::create_global which
will then only advertise version 3 to clients. This is mostly meant to guarantee an easy update path for compositors already
supporting dmabuf version 3 without breakage.
// define your supported formats
let formats = vec![
/* ... */
];
// And create the dmabuf global.
let dmabuf_global = dmabuf_state.create_global::<State>(
&display_handle,
formats,
);
let state = State {
dmabuf_state,
dmabuf_global,
};
// Rest of the compositor goes here...Structs§
- Dmabuf
Data - Data associated with a dmabuf global protocol object.
- Dmabuf
Feedback - Feedback for dmabuf allocation
- Dmabuf
Feedback Builder - Builder for
DmabufFeedback - Dmabuf
Feedback Data - Data associated with a dmabuf global protocol object.
- Dmabuf
Global - A handle to a registered dmabuf global.
- Dmabuf
Global Data - Data associated with a dmabuf global.
- Dmabuf
Params Data - Data associated with a pending
Dmabufimport. - Dmabuf
State - Delegate type for all dmabuf globals.
- Import
Notifier - An object to allow asynchronous creation of a
DmabufbackedWlBuffer. - Surface
Dmabuf Feedback State - Feedback state for a surface
Traits§
- Dmabuf
Handler - Handler trait for
Dmabufimport from the compositor.
Functions§
- get_
dmabuf - Gets the contents of a
DmabufbackedWlBuffer.