feat: support renderer-validated dma-buf imports
This commit is contained in:
1 parent
d32f20dbbf
commit
05f801aee6
5 files changed
+59
-3
No files matched your search
@@ -174,6 +174,11 @@ fn open_primary_device(
|
|||||||
// SAFETY: the new context is not current on another thread and remains renderer-owned.
|
// SAFETY: the new context is not current on another thread and remains renderer-owned.
|
||||||
let renderer = unsafe { GlesRenderer::new(egl_context)? };
|
let renderer = unsafe { GlesRenderer::new(egl_context)? };
|
||||||
state.shm_state.update_formats(renderer.shm_formats());
|
state.shm_state.update_formats(renderer.shm_formats());
|
||||||
|
let dmabuf_formats = renderer.dmabuf_formats();
|
||||||
|
let display_handle = state.display_handle.clone();
|
||||||
|
state
|
||||||
|
.dmabuf_state
|
||||||
|
.create_global::<Ferese>(&display_handle, dmabuf_formats);
|
||||||
let (connector, crtc, mode) = select_output(&drm)?;
|
let (connector, crtc, mode) = select_output(&drm)?;
|
||||||
let output = create_output(state, &connector, mode);
|
let output = create_output(state, &connector, mode);
|
||||||
if let Some(backend) = state.direct_backend.as_mut() {
|
if let Some(backend) = state.direct_backend.as_mut() {
|
||||||
@@ -299,6 +304,7 @@ fn render_device(state: &mut Ferese, node: DrmNode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let rendered = (|| -> Result<bool, Box<dyn Error>> {
|
let rendered = (|| -> Result<bool, Box<dyn Error>> {
|
||||||
|
state.process_dmabuf_imports(&mut device.renderer);
|
||||||
let (mut buffer, age) = device.surface.next_buffer()?;
|
let (mut buffer, age) = device.surface.next_buffer()?;
|
||||||
let elements = animated_window_elements(state, &mut device.renderer, &device.output);
|
let elements = animated_window_elements(state, &mut device.renderer, &device.output);
|
||||||
let mut framebuffer = device.renderer.bind(&mut buffer)?;
|
let mut framebuffer = device.renderer.bind(&mut buffer)?;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::utils::on_commit_buffer_handler,
|
backend::{allocator::dmabuf::Dmabuf, renderer::utils::on_commit_buffer_handler},
|
||||||
reexports::wayland_server::{
|
reexports::wayland_server::{
|
||||||
Client,
|
Client,
|
||||||
protocol::{wl_buffer, wl_surface::WlSurface},
|
protocol::{wl_buffer, wl_surface::WlSurface},
|
||||||
@@ -10,6 +10,7 @@ use smithay::{
|
|||||||
CompositorClientState, CompositorHandler, CompositorState, get_parent,
|
CompositorClientState, CompositorHandler, CompositorState, get_parent,
|
||||||
is_sync_subsurface,
|
is_sync_subsurface,
|
||||||
},
|
},
|
||||||
|
dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier},
|
||||||
shm::{ShmHandler, ShmState},
|
shm::{ShmHandler, ShmState},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -74,6 +75,22 @@ impl BufferHandler for Ferese {
|
|||||||
fn buffer_destroyed(&mut self, _buffer: &wl_buffer::WlBuffer) {}
|
fn buffer_destroyed(&mut self, _buffer: &wl_buffer::WlBuffer) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DmabufHandler for Ferese {
|
||||||
|
fn dmabuf_state(&mut self) -> &mut DmabufState {
|
||||||
|
&mut self.dmabuf_state
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dmabuf_imported(
|
||||||
|
&mut self,
|
||||||
|
_global: &DmabufGlobal,
|
||||||
|
dmabuf: Dmabuf,
|
||||||
|
notifier: ImportNotifier,
|
||||||
|
) {
|
||||||
|
self.queue_dmabuf_import(dmabuf, notifier);
|
||||||
|
crate::backends::direct::render_all(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ShmHandler for Ferese {
|
impl ShmHandler for Ferese {
|
||||||
fn shm_state(&self) -> &ShmState {
|
fn shm_state(&self) -> &ShmState {
|
||||||
&self.shm_state
|
&self.shm_state
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ impl XdgForeignHandler for Ferese {
|
|||||||
smithay::delegate_compositor!(Ferese);
|
smithay::delegate_compositor!(Ferese);
|
||||||
smithay::delegate_cursor_shape!(Ferese);
|
smithay::delegate_cursor_shape!(Ferese);
|
||||||
smithay::delegate_data_device!(Ferese);
|
smithay::delegate_data_device!(Ferese);
|
||||||
|
smithay::delegate_dmabuf!(Ferese);
|
||||||
smithay::delegate_fractional_scale!(Ferese);
|
smithay::delegate_fractional_scale!(Ferese);
|
||||||
smithay::delegate_idle_inhibit!(Ferese);
|
smithay::delegate_idle_inhibit!(Ferese);
|
||||||
smithay::delegate_idle_notify!(Ferese);
|
smithay::delegate_idle_notify!(Ferese);
|
||||||
|
|||||||
+26
-1
@@ -11,7 +11,7 @@ use ferese_core::{WindowPlacement, WorkspaceSet};
|
|||||||
use ferese_layout::{Axis, Direction, GapConfig, LayoutResult, Rect, SizeConstraints, WindowId};
|
use ferese_layout::{Axis, Direction, GapConfig, LayoutResult, Rect, SizeConstraints, WindowId};
|
||||||
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::drm::DrmEventTime,
|
backend::{allocator::dmabuf::Dmabuf, drm::DrmEventTime, renderer::ImportDma},
|
||||||
desktop::{
|
desktop::{
|
||||||
LayerSurface, PopupManager, Space, Window, WindowSurfaceType, layer_map_for_output,
|
LayerSurface, PopupManager, Space, Window, WindowSurfaceType, layer_map_for_output,
|
||||||
utils::send_frames_surface_tree,
|
utils::send_frames_surface_tree,
|
||||||
@@ -37,6 +37,7 @@ use smithay::{
|
|||||||
wayland::{
|
wayland::{
|
||||||
compositor::{CompositorClientState, CompositorState, with_states},
|
compositor::{CompositorClientState, CompositorState, with_states},
|
||||||
cursor_shape::CursorShapeManagerState,
|
cursor_shape::CursorShapeManagerState,
|
||||||
|
dmabuf::{DmabufState, ImportNotifier},
|
||||||
fractional_scale::FractionalScaleManagerState,
|
fractional_scale::FractionalScaleManagerState,
|
||||||
idle_inhibit::IdleInhibitManagerState,
|
idle_inhibit::IdleInhibitManagerState,
|
||||||
idle_notify::IdleNotifierState,
|
idle_notify::IdleNotifierState,
|
||||||
@@ -78,6 +79,7 @@ pub struct Ferese {
|
|||||||
pub idle_inhibitors: HashMap<WlSurface, usize>,
|
pub idle_inhibitors: HashMap<WlSurface, usize>,
|
||||||
pub active_shortcuts_inhibitor: Option<KeyboardShortcutsInhibitor>,
|
pub active_shortcuts_inhibitor: Option<KeyboardShortcutsInhibitor>,
|
||||||
pub direct_backend: Option<crate::backends::direct::DirectBackendState>,
|
pub direct_backend: Option<crate::backends::direct::DirectBackendState>,
|
||||||
|
pending_dmabuf_imports: Vec<(Dmabuf, ImportNotifier)>,
|
||||||
next_window_id: u64,
|
next_window_id: u64,
|
||||||
last_animation_tick: Instant,
|
last_animation_tick: Instant,
|
||||||
pub popups: PopupManager,
|
pub popups: PopupManager,
|
||||||
@@ -86,6 +88,7 @@ pub struct Ferese {
|
|||||||
pub cursor_shape_state: CursorShapeManagerState,
|
pub cursor_shape_state: CursorShapeManagerState,
|
||||||
pub data_device_state: DataDeviceState,
|
pub data_device_state: DataDeviceState,
|
||||||
pub decoration_state: XdgDecorationState,
|
pub decoration_state: XdgDecorationState,
|
||||||
|
pub dmabuf_state: DmabufState,
|
||||||
pub fractional_scale_state: FractionalScaleManagerState,
|
pub fractional_scale_state: FractionalScaleManagerState,
|
||||||
pub idle_inhibit_state: IdleInhibitManagerState,
|
pub idle_inhibit_state: IdleInhibitManagerState,
|
||||||
pub idle_notifier_state: IdleNotifierState<Self>,
|
pub idle_notifier_state: IdleNotifierState<Self>,
|
||||||
@@ -108,6 +111,25 @@ pub struct Ferese {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ferese {
|
impl Ferese {
|
||||||
|
pub(crate) fn queue_dmabuf_import(&mut self, dmabuf: Dmabuf, notifier: ImportNotifier) {
|
||||||
|
self.pending_dmabuf_imports.push((dmabuf, notifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn process_dmabuf_imports<R>(&mut self, renderer: &mut R)
|
||||||
|
where
|
||||||
|
R: ImportDma,
|
||||||
|
{
|
||||||
|
for (dmabuf, notifier) in self.pending_dmabuf_imports.drain(..) {
|
||||||
|
if renderer.import_dmabuf(&dmabuf, None).is_ok() {
|
||||||
|
if let Err(error) = notifier.successful::<Self>() {
|
||||||
|
tracing::debug!(?error, "dma-buf client disappeared before import completed");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
notifier.failed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
event_loop: &mut EventLoop<'static, Self>,
|
event_loop: &mut EventLoop<'static, Self>,
|
||||||
display: Display<Self>,
|
display: Display<Self>,
|
||||||
@@ -117,6 +139,7 @@ impl Ferese {
|
|||||||
let cursor_shape_state = CursorShapeManagerState::new::<Self>(&display_handle);
|
let cursor_shape_state = CursorShapeManagerState::new::<Self>(&display_handle);
|
||||||
let xdg_shell_state = XdgShellState::new::<Self>(&display_handle);
|
let xdg_shell_state = XdgShellState::new::<Self>(&display_handle);
|
||||||
let decoration_state = XdgDecorationState::new::<Self>(&display_handle);
|
let decoration_state = XdgDecorationState::new::<Self>(&display_handle);
|
||||||
|
let dmabuf_state = DmabufState::new();
|
||||||
let fractional_scale_state = FractionalScaleManagerState::new::<Self>(&display_handle);
|
let fractional_scale_state = FractionalScaleManagerState::new::<Self>(&display_handle);
|
||||||
let idle_inhibit_state = IdleInhibitManagerState::new::<Self>(&display_handle);
|
let idle_inhibit_state = IdleInhibitManagerState::new::<Self>(&display_handle);
|
||||||
let idle_notifier_state = IdleNotifierState::new(&display_handle, event_loop.handle());
|
let idle_notifier_state = IdleNotifierState::new(&display_handle, event_loop.handle());
|
||||||
@@ -168,6 +191,7 @@ impl Ferese {
|
|||||||
idle_inhibitors: HashMap::new(),
|
idle_inhibitors: HashMap::new(),
|
||||||
active_shortcuts_inhibitor: None,
|
active_shortcuts_inhibitor: None,
|
||||||
direct_backend: None,
|
direct_backend: None,
|
||||||
|
pending_dmabuf_imports: Vec::new(),
|
||||||
next_window_id: 1,
|
next_window_id: 1,
|
||||||
last_animation_tick: start_time,
|
last_animation_tick: start_time,
|
||||||
popups: PopupManager::default(),
|
popups: PopupManager::default(),
|
||||||
@@ -176,6 +200,7 @@ impl Ferese {
|
|||||||
cursor_shape_state,
|
cursor_shape_state,
|
||||||
data_device_state,
|
data_device_state,
|
||||||
decoration_state,
|
decoration_state,
|
||||||
|
dmabuf_state,
|
||||||
fractional_scale_state,
|
fractional_scale_state,
|
||||||
idle_inhibit_state,
|
idle_inhibit_state,
|
||||||
idle_notifier_state,
|
idle_notifier_state,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use std::{
|
|||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
renderer::{
|
renderer::{
|
||||||
|
ImportDma,
|
||||||
damage::OutputDamageTracker,
|
damage::OutputDamageTracker,
|
||||||
element::{
|
element::{
|
||||||
AsRenderElements, Kind as RenderElementKind,
|
AsRenderElements, Kind as RenderElementKind,
|
||||||
@@ -52,7 +53,12 @@ render_elements! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<(), Box<dyn Error>> {
|
pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<(), Box<dyn Error>> {
|
||||||
let (mut backend, event_source) = winit::init()?;
|
let (mut backend, event_source) = winit::init::<GlesRenderer>()?;
|
||||||
|
let dmabuf_formats = backend.renderer().dmabuf_formats();
|
||||||
|
let display_handle = state.display_handle.clone();
|
||||||
|
state
|
||||||
|
.dmabuf_state
|
||||||
|
.create_global::<Ferese>(&display_handle, dmabuf_formats);
|
||||||
let initial_scale = normalized_scale(backend.scale_factor());
|
let initial_scale = normalized_scale(backend.scale_factor());
|
||||||
let mode = Mode {
|
let mode = Mode {
|
||||||
size: backend.window_size(),
|
size: backend.window_size(),
|
||||||
@@ -127,6 +133,7 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
|
|||||||
let rendered = (|| -> Result<(), Box<dyn Error>> {
|
let rendered = (|| -> Result<(), Box<dyn Error>> {
|
||||||
{
|
{
|
||||||
let (renderer, mut framebuffer) = backend.bind()?;
|
let (renderer, mut framebuffer) = backend.bind()?;
|
||||||
|
state.process_dmabuf_imports(renderer);
|
||||||
let elements = animated_window_elements(state, renderer, &output);
|
let elements = animated_window_elements(state, renderer, &output);
|
||||||
damage_tracker.render_output(
|
damage_tracker.render_output(
|
||||||
renderer,
|
renderer,
|
||||||
|
|||||||
Reference in new issue
Block a user