aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/tty.rs24
-rw-r--r--src/handlers/compositor.rs40
-rw-r--r--src/handlers/mod.rs28
3 files changed, 86 insertions, 6 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs
index eec796f1..2db762fc 100644
--- a/src/backend/tty.rs
+++ b/src/backend/tty.rs
@@ -12,7 +12,7 @@ use smithay::backend::drm::{DrmDevice, DrmDeviceFd, DrmEvent, DrmEventTime};
use smithay::backend::egl::{EGLContext, EGLDisplay};
use smithay::backend::libinput::{LibinputInputBackend, LibinputSessionInterface};
use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture};
-use smithay::backend::renderer::{Bind, DebugFlags, ImportEgl};
+use smithay::backend::renderer::{Bind, DebugFlags, ImportDma, ImportEgl};
use smithay::backend::session::libseat::LibSeatSession;
use smithay::backend::session::{Event as SessionEvent, Session};
use smithay::backend::udev::{self, UdevBackend, UdevEvent};
@@ -27,10 +27,11 @@ use smithay::reexports::nix::fcntl::OFlag;
use smithay::reexports::nix::libc::dev_t;
use smithay::reexports::wayland_protocols::wp::presentation_time::server::wp_presentation_feedback;
use smithay::utils::DeviceFd;
+use smithay::wayland::dmabuf::{DmabufFeedbackBuilder, DmabufGlobal, DmabufState};
use smithay_drm_extras::drm_scanner::{DrmScanEvent, DrmScanner};
use smithay_drm_extras::edid::EdidInfo;
-use crate::niri::OutputRenderElements;
+use crate::niri::{OutputRenderElements, State};
use crate::{LoopData, Niri};
const BACKGROUND_COLOR: [f32; 4] = [0.1, 0.1, 0.1, 1.];
@@ -59,6 +60,8 @@ struct OutputDevice {
formats: HashSet<DrmFormat>,
drm_scanner: DrmScanner,
surfaces: HashMap<crtc::Handle, GbmDrmCompositor>,
+ dmabuf_state: DmabufState,
+ dmabuf_global: DmabufGlobal,
}
#[derive(Debug, Clone, Copy)]
@@ -331,6 +334,13 @@ impl Tty {
let formats = Bind::<Dmabuf>::supported_formats(&gles).unwrap_or_default();
+ let mut dmabuf_state = DmabufState::new();
+ let default_feedback = DmabufFeedbackBuilder::new(device_id, gles.dmabuf_formats())
+ .build()
+ .unwrap();
+ let dmabuf_global = dmabuf_state
+ .create_global_with_default_feedback::<State>(&niri.display_handle, &default_feedback);
+
self.output_device = Some(OutputDevice {
id: device_id,
token,
@@ -340,6 +350,8 @@ impl Tty {
formats,
drm_scanner: DrmScanner::new(),
surfaces: HashMap::new(),
+ dmabuf_state,
+ dmabuf_global,
});
self.device_changed(device_id, niri);
@@ -394,7 +406,11 @@ impl Tty {
}
let mut device = self.output_device.take().unwrap();
+ device
+ .dmabuf_state
+ .destroy_global::<State>(&niri.display_handle, device.dmabuf_global);
device.gles.unbind_wl_display();
+
niri.event_loop.remove(device.token);
}
@@ -582,6 +598,10 @@ impl Tty {
}
}
}
+
+ pub fn dmabuf_state(&mut self) -> &mut DmabufState {
+ &mut self.output_device.as_mut().unwrap().dmabuf_state
+ }
}
fn refresh_interval(mode: DrmMode) -> Duration {
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);