diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2023-09-03 14:22:04 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-09-03 14:22:04 +0400 |
| commit | cc1c9d93254df120fc1041e121cb3b5edd00ffc9 (patch) | |
| tree | b39afcd0df6d74ec10bf511aed23b16ce105fe11 /src/handlers | |
| parent | 03a9fd8af3bbd8a0e6dbc33516dce83cce564166 (diff) | |
| download | niri-cc1c9d93254df120fc1041e121cb3b5edd00ffc9.tar.gz niri-cc1c9d93254df120fc1041e121cb3b5edd00ffc9.tar.bz2 niri-cc1c9d93254df120fc1041e121cb3b5edd00ffc9.zip | |
Add initial dmabuf feedback implementation
Diffstat (limited to 'src/handlers')
| -rw-r--r-- | src/handlers/compositor.rs | 40 | ||||
| -rw-r--r-- | src/handlers/mod.rs | 28 |
2 files changed, 64 insertions, 4 deletions
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs index 035daafc..5f7bf71d 100644 --- a/src/handlers/compositor.rs +++ b/src/handlers/compositor.rs @@ -2,13 +2,16 @@ use std::collections::hash_map::Entry; use smithay::backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state}; use smithay::desktop::find_popup_root_surface; +use smithay::reexports::calloop::Interest; use smithay::reexports::wayland_server::protocol::wl_buffer; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; -use smithay::reexports::wayland_server::Client; +use smithay::reexports::wayland_server::{Client, Resource}; use smithay::wayland::buffer::BufferHandler; use smithay::wayland::compositor::{ - get_parent, is_sync_subsurface, CompositorClientState, CompositorHandler, CompositorState, + add_blocker, add_pre_commit_hook, get_parent, is_sync_subsurface, with_states, + BufferAssignment, CompositorClientState, CompositorHandler, CompositorState, SurfaceAttributes, }; +use smithay::wayland::dmabuf::get_dmabuf; use smithay::wayland::shm::{ShmHandler, ShmState}; use smithay::{delegate_compositor, delegate_shm}; @@ -24,6 +27,39 @@ impl CompositorHandler for State { &client.get_data::<ClientState>().unwrap().compositor_state } + fn new_surface(&mut self, surface: &WlSurface) { + add_pre_commit_hook::<Self, _>(surface, move |state, _dh, surface| { + let maybe_dmabuf = with_states(surface, |surface_data| { + surface_data + .cached_state + .pending::<SurfaceAttributes>() + .buffer + .as_ref() + .and_then(|assignment| match assignment { + BufferAssignment::NewBuffer(buffer) => get_dmabuf(buffer).ok(), + _ => None, + }) + }); + if let Some(dmabuf) = maybe_dmabuf { + if let Ok((blocker, source)) = dmabuf.generate_blocker(Interest::READ) { + let client = surface.client().unwrap(); + let res = state + .niri + .event_loop + .insert_source(source, move |_, _, data| { + data.state + .client_compositor_state(&client) + .blocker_cleared(&mut data.state, &data.display.handle()); + Ok(()) + }); + if res.is_ok() { + add_blocker(surface, blocker); + } + } + } + }) + } + fn commit(&mut self, surface: &WlSurface) { let _span = tracy_client::span!("CompositorHandler::commit"); diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 7e643d5d..0e330322 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -2,6 +2,8 @@ mod compositor; mod layer_shell; mod xdg_shell; +use smithay::backend::allocator::dmabuf::Dmabuf; +use smithay::backend::renderer::ImportDma; use smithay::input::pointer::CursorImageStatus; use smithay::input::{Seat, SeatHandler, SeatState}; use smithay::reexports::wayland_server::protocol::wl_data_source::WlDataSource; @@ -11,9 +13,10 @@ use smithay::wayland::data_device::{ set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState, ServerDndGrabHandler, }; +use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportError}; use smithay::{ - delegate_data_device, delegate_output, delegate_pointer_gestures, delegate_presentation, - delegate_seat, delegate_tablet_manager, + delegate_data_device, delegate_dmabuf, delegate_output, delegate_pointer_gestures, + delegate_presentation, delegate_seat, delegate_tablet_manager, }; use crate::niri::State; @@ -75,3 +78,24 @@ delegate_data_device!(State); delegate_output!(State); delegate_presentation!(State); + +impl DmabufHandler for State { + fn dmabuf_state(&mut self) -> &mut DmabufState { + self.backend.tty().dmabuf_state() + } + + fn dmabuf_imported( + &mut self, + _global: &DmabufGlobal, + dmabuf: Dmabuf, + ) -> Result<(), ImportError> { + match self.backend.renderer().import_dmabuf(&dmabuf, None) { + Ok(_texture) => Ok(()), + Err(err) => { + warn!("error importing dmabuf: {err:?}"); + Err(ImportError::Failed) + } + } + } +} +delegate_dmabuf!(State); |
