Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/backend/tty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use smithay::wayland::dmabuf::{DmabufFeedback, DmabufFeedbackBuilder, DmabufGlob
use smithay::wayland::drm_lease::{
DrmLease, DrmLeaseBuilder, DrmLeaseRequest, DrmLeaseState, LeaseRejected,
};
use smithay::wayland::drm_syncobj::{supports_syncobj_eventfd, DrmSyncobjState};
use smithay::wayland::presentation::Refresh;
use smithay_drm_extras::drm_scanner::{DrmScanEvent, DrmScanner};
use wayland_protocols::wp::linux_dmabuf::zv1::server::zwp_linux_dmabuf_feedback_v1::TrancheFlags;
Expand Down Expand Up @@ -90,6 +91,8 @@ pub struct Tty {
dmabuf_global: Option<DmabufGlobal>,
// The output config had changed, but the session is paused, so we need to update it on resume.
update_output_config_on_resume: bool,
// The sync object state when available
pub(crate) syncobj_state: Option<DrmSyncobjState>,
// Whether the debug tinting is enabled.
debug_tint: bool,
ipc_outputs: Arc<Mutex<IpcOutputMap>>,
Expand Down Expand Up @@ -333,6 +336,7 @@ impl Tty {
devices: HashMap::new(),
dmabuf_global: None,
update_output_config_on_resume: false,
syncobj_state: None,
debug_tint: false,
ipc_outputs: Arc::new(Mutex::new(HashMap::new())),
})
Expand Down Expand Up @@ -503,7 +507,7 @@ impl Tty {
let device_fd = DrmDeviceFd::new(DeviceFd::from(fd));

let (drm, drm_notifier) = DrmDevice::new(device_fd.clone(), true)?;
let gbm = GbmDevice::new(device_fd)?;
let gbm = GbmDevice::new(device_fd.clone())?;

let display = unsafe { EGLDisplay::new(gbm.clone())? };
let egl_device = EGLDevice::device_for_display(&display)?;
Expand Down Expand Up @@ -583,6 +587,12 @@ impl Tty {
}
}
}

// Expose syncobj protocol if supported by primary GPU
if supports_syncobj_eventfd(&device_fd) {
let syncobj_state = DrmSyncobjState::new::<State>(&niri.display_handle, device_fd);
assert!(self.syncobj_state.replace(syncobj_state).is_none());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guess this should be removed once the primary node is removed?

}
}

let token = niri
Expand Down
58 changes: 44 additions & 14 deletions src/handlers/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use smithay::wayland::compositor::{
SurfaceAttributes,
};
use smithay::wayland::dmabuf::get_dmabuf;
use smithay::wayland::drm_syncobj::DrmSyncobjCachedState;
use smithay::wayland::shell::xdg::XdgToplevelSurfaceData;
use smithay::wayland::shm::{ShmHandler, ShmState};
use smithay::{delegate_compositor, delegate_shm};
Expand Down Expand Up @@ -466,7 +467,19 @@ delegate_shm!(State);
impl State {
pub fn add_default_dmabuf_pre_commit_hook(&mut self, surface: &WlSurface) {
let hook = add_pre_commit_hook::<Self, _>(surface, move |state, _dh, surface| {
let Some(client) = surface.client() else {
return;
};

let mut acquire_point = None;
let maybe_dmabuf = with_states(surface, |surface_data| {
acquire_point.clone_from(
&surface_data
.cached_state
.get::<DrmSyncobjCachedState>()
.pending()
.acquire_point,
);
surface_data
.cached_state
.get::<SurfaceAttributes>()
Expand All @@ -479,25 +492,42 @@ impl State {
})
});
if let Some(dmabuf) = maybe_dmabuf {
if let Ok((blocker, source)) = dmabuf.generate_blocker(Interest::READ) {
if let Some(client) = surface.client() {
let res =
state
.niri
.event_loop
.insert_source(source, move |_, _, state| {
let display_handle = state.niri.display_handle.clone();
state
.client_compositor_state(&client)
.blocker_cleared(state, &display_handle);
Ok(())
});
if let Some(acquire_point) = acquire_point {
if let Ok((blocker, source)) = acquire_point.generate_blocker() {
let res = state.niri.event_loop.insert_source(source, {
let client = client.clone();
move |_, _, state| {
let display_handle = state.niri.display_handle.clone();
state
.client_compositor_state(&client)
.blocker_cleared(state, &display_handle);
Ok(())
}
});
if res.is_ok() {
add_blocker(surface, blocker);
trace!("added default dmabuf blocker");
trace!("added acquire point blocker");
return;
}
}
}

if let Ok((blocker, source)) = dmabuf.generate_blocker(Interest::READ) {
let res = state
.niri
.event_loop
.insert_source(source, move |_, _, state| {
let display_handle = state.niri.display_handle.clone();
state
.client_compositor_state(&client)
.blocker_cleared(state, &display_handle);
Ok(())
});
if res.is_ok() {
add_blocker(surface, blocker);
trace!("added dmabuf blocker");
}
}
}
});

Expand Down
10 changes: 9 additions & 1 deletion src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use smithay::wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportN
use smithay::wayland::drm_lease::{
DrmLease, DrmLeaseBuilder, DrmLeaseHandler, DrmLeaseRequest, DrmLeaseState, LeaseRejected,
};
use smithay::wayland::drm_syncobj::{DrmSyncobjHandler, DrmSyncobjState};
use smithay::wayland::fractional_scale::FractionalScaleHandler;
use smithay::wayland::idle_inhibit::IdleInhibitHandler;
use smithay::wayland::idle_notify::{IdleNotifierHandler, IdleNotifierState};
Expand Down Expand Up @@ -66,7 +67,7 @@ use smithay::wayland::xdg_activation::{
};
use smithay::{
delegate_cursor_shape, delegate_data_control, delegate_data_device, delegate_dmabuf,
delegate_drm_lease, delegate_ext_data_control, delegate_fractional_scale,
delegate_drm_lease, delegate_drm_syncobj, delegate_ext_data_control, delegate_fractional_scale,
delegate_idle_inhibit, delegate_idle_notify, delegate_input_method_manager,
delegate_keyboard_shortcuts_inhibit, delegate_output, delegate_pointer_constraints,
delegate_pointer_gestures, delegate_presentation, delegate_primary_selection,
Expand Down Expand Up @@ -794,3 +795,10 @@ impl MutterX11InteropHandler for State {}
delegate_mutter_x11_interop!(State);

delegate_single_pixel_buffer!(State);

impl DrmSyncobjHandler for State {
fn drm_syncobj_state(&mut self) -> &mut DrmSyncobjState {
self.backend.tty().syncobj_state.as_mut().unwrap()
}
}
delegate_drm_syncobj!(State);