diff --git a/src/wayland/dmabuf.rs b/src/wayland/dmabuf.rs new file mode 100644 index 0000000..887c2ef --- /dev/null +++ b/src/wayland/dmabuf.rs @@ -0,0 +1,22 @@ +use super::state::WaylandState; +use smithay::{ + backend::allocator::dmabuf::Dmabuf, + delegate_dmabuf, + wayland::dmabuf::{self, DmabufGlobal, DmabufHandler, DmabufState}, +}; + +impl DmabufHandler for WaylandState { + fn dmabuf_state(&mut self) -> &mut DmabufState { + &mut self.dmabuf_state + } + + fn dmabuf_imported( + &mut self, + _global: &DmabufGlobal, + dmabuf: Dmabuf, + ) -> Result<(), dmabuf::ImportError> { + self.pending_dmabufs.push(dmabuf); + Ok(()) + } +} +delegate_dmabuf!(WaylandState); diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index 8c73a15..72e8e09 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -1,13 +1,14 @@ -pub mod compositor; +mod compositor; mod data_device; -pub mod decoration; +mod decoration; pub mod panel_item; -pub mod seat; -pub mod shaders; -pub mod state; -pub mod surface; -pub mod xdg_activation; -pub mod xdg_shell; +mod seat; +mod shaders; +mod state; +mod surface; +mod xdg_activation; +mod xdg_shell; +mod dmabuf; use self::{panel_item::PanelItem, state::WaylandState, surface::CORE_SURFACES}; use crate::wayland::state::ClientState; @@ -16,7 +17,7 @@ use once_cell::sync::OnceCell; use parking_lot::Mutex; use slog::Drain; use smithay::{ - backend::{egl::EGLContext, renderer::gles2::Gles2Renderer}, + backend::{egl::EGLContext, renderer::{gles2::Gles2Renderer, ImportDma}}, reexports::wayland_server::{backend::GlobalId, Display, ListeningSocket, Resource}, }; use tracing::info; @@ -84,7 +85,7 @@ impl Wayland { let display_handle = display.handle(); let display = Arc::new(Mutex::new(display)); - let state = WaylandState::new(log.clone(), display.clone(), display_handle); + let state = WaylandState::new(log.clone(), display.clone(), display_handle, &renderer); let (global_destroy_queue_in, global_destroy_queue) = mpsc::channel(8); GLOBAL_DESTROY_QUEUE.set(global_destroy_queue_in).unwrap(); @@ -152,7 +153,10 @@ impl Wayland { .wl_surface() .and_then(|surf| surf.client()) .map(|c| c.id()) else { continue }; - let state = self.state.lock(); + let mut state = self.state.lock(); + for dmabuf in state.pending_dmabufs.drain(1..) { + let _ = self.renderer.import_dmabuf(&dmabuf, None); + } let Some(seat_data) = state.seats.get(&client_id).cloned() else { continue }; let output = state.output.clone(); core_surface.process( diff --git a/src/wayland/state.rs b/src/wayland/state.rs index 4398c57..24c6188 100644 --- a/src/wayland/state.rs +++ b/src/wayland/state.rs @@ -3,13 +3,17 @@ use parking_lot::Mutex; use rustc_hash::FxHashMap; use slog::Logger; use smithay::{ + backend::{ + allocator::dmabuf::Dmabuf, + renderer::{gles2::Gles2Renderer, ImportDma}, + }, delegate_output, delegate_shm, output::{Mode, Output, Scale, Subpixel}, reexports::{ wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration_manager::Mode as DecorationMode, wayland_server::{ backend::{ClientData, ClientId, DisconnectReason}, - protocol::wl_data_device_manager::WlDataDeviceManager, + protocol::{wl_buffer::WlBuffer, wl_data_device_manager::WlDataDeviceManager}, Display, DisplayHandle, }, }, @@ -17,6 +21,7 @@ use smithay::{ wayland::{ buffer::BufferHandler, compositor::CompositorState, + dmabuf::{DmabufGlobal, DmabufState}, output::OutputManagerState, shell::{ kde::decoration::KdeDecorationState, @@ -55,6 +60,9 @@ pub struct WaylandState { pub kde_decoration_state: KdeDecorationState, pub xdg_shell_state: XdgShellState, pub shm_state: ShmState, + pub dmabuf_state: DmabufState, + pub dmabuf_global: DmabufGlobal, + pub pending_dmabufs: Vec, pub output_manager_state: OutputManagerState, pub output: Output, pub seats: FxHashMap, @@ -65,6 +73,7 @@ impl WaylandState { log: Logger, display: Arc>>, display_handle: DisplayHandle, + renderer: &Gles2Renderer, ) -> Arc> { let compositor_state = CompositorState::new::(&display_handle, log.clone()); let xdg_activation_state = XdgActivationState::new::(&display_handle, log.clone()); @@ -76,6 +85,12 @@ impl WaylandState { log.clone(), ); let shm_state = ShmState::new::(&display_handle, vec![], log.clone()); + let mut dmabuf_state = DmabufState::new(); + let dmabuf_global = dmabuf_state.create_global::( + &display_handle, + renderer.dmabuf_formats().cloned().collect::>(), + log.clone(), + ); let output_manager_state = OutputManagerState::new_with_xdg_output::(&display_handle); let output = Output::new( "1x".to_owned(), @@ -87,7 +102,7 @@ impl WaylandState { }, log.clone(), ); - let _global = output.create_global::(&display_handle); + let _output_global = output.create_global::(&display_handle); output.change_current_state( Some(Mode { size: (4096, 4096).into(), @@ -114,6 +129,9 @@ impl WaylandState { kde_decoration_state, xdg_shell_state, shm_state, + dmabuf_state, + dmabuf_global, + pending_dmabufs: Vec::new(), output_manager_state, output, seats: FxHashMap::default(), @@ -132,14 +150,10 @@ impl Drop for WaylandState { } } impl BufferHandler for WaylandState { - fn buffer_destroyed( - &mut self, - _buffer: &smithay::reexports::wayland_server::protocol::wl_buffer::WlBuffer, - ) { - } + fn buffer_destroyed(&mut self, _buffer: &WlBuffer) {} } impl ShmHandler for WaylandState { - fn shm_state(&self) -> &smithay::wayland::shm::ShmState { + fn shm_state(&self) -> &ShmState { &self.shm_state } }