aboutsummaryrefslogtreecommitdiff
path: root/src/handlers
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-09-03 14:22:04 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-09-03 14:22:04 +0400
commitcc1c9d93254df120fc1041e121cb3b5edd00ffc9 (patch)
treeb39afcd0df6d74ec10bf511aed23b16ce105fe11 /src/handlers
parent03a9fd8af3bbd8a0e6dbc33516dce83cce564166 (diff)
downloadniri-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.rs40
-rw-r--r--src/handlers/mod.rs28
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);