Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
11 changes: 9 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ tracy-client = { version = "0.18.0", default-features = false }

[workspace.dependencies.smithay]
# version = "0.4.1"
git = "https://github.com/Smithay/smithay.git"
git = "https://github.com/cmeissl/smithay.git"
rev = "3f660eddf82e6ff9d6db1666ec5ef0cbee7102ce"
# path = "../smithay"
default-features = false

[workspace.dependencies.smithay-drm-extras]
# version = "0.1.0"
git = "https://github.com/Smithay/smithay.git"
git = "https://github.com/cmeissl/smithay.git"
rev = "3f660eddf82e6ff9d6db1666ec5ef0cbee7102ce"
# path = "../smithay/smithay-drm-extras"

[package]
Expand Down
19 changes: 15 additions & 4 deletions src/backend/tty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use smithay::backend::allocator::format::FormatSet;
use smithay::backend::allocator::gbm::{GbmAllocator, GbmBufferFlags, GbmDevice};
use smithay::backend::allocator::Fourcc;
use smithay::backend::drm::compositor::{DrmCompositor, FrameFlags, PrimaryPlaneElement};
use smithay::backend::drm::exporter::gbm::GbmFramebufferExporter;
use smithay::backend::drm::{
DrmDevice, DrmDeviceFd, DrmEvent, DrmEventMetadata, DrmEventTime, DrmNode, NodeType, VrrSupport,
};
Expand Down Expand Up @@ -50,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 @@ -89,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 All @@ -114,7 +118,7 @@ pub type TtyRendererError<'render> = <TtyRenderer<'render> as RendererSuper>::Er

type GbmDrmCompositor = DrmCompositor<
GbmAllocator<DrmDeviceFd>,
GbmDevice<DrmDeviceFd>,
GbmFramebufferExporter<DrmDeviceFd>,
(OutputPresentationFeedback, Duration),
DrmDeviceFd,
>;
Expand Down Expand Up @@ -332,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 @@ -502,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 @@ -582,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());
}
}

let token = niri
Expand Down Expand Up @@ -971,7 +982,7 @@ impl Tty {
surface,
None,
allocator.clone(),
device.gbm.clone(),
GbmFramebufferExporter::new(device.gbm.clone()),
SUPPORTED_COLOR_FORMATS,
// This is only used to pick a good internal format, so it can use the surface's render
// formats, even though we only ever render on the primary GPU.
Expand Down Expand Up @@ -1001,7 +1012,7 @@ impl Tty {
surface,
None,
allocator,
device.gbm.clone(),
GbmFramebufferExporter::new(device.gbm.clone()),
SUPPORTED_COLOR_FORMATS,
render_formats,
device.drm.cursor_size(),
Expand Down
74 changes: 48 additions & 26 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 @@ -165,8 +166,6 @@ impl CompositorHandler for State {
})
.map(|(mapped, _)| mapped.window.clone());

// The mapped pre-commit hook deals with dma-bufs on its own.
self.remove_default_dmabuf_pre_commit_hook(toplevel.wl_surface());
let hook = add_mapped_toplevel_pre_commit_hook(toplevel);
let mapped = Mapped::new(window, rules, hook);
let window = mapped.window.clone();
Expand Down Expand Up @@ -249,12 +248,14 @@ impl CompositorHandler for State {
.stop_casts_for_target(CastTarget::Window { id: id.get() });

self.niri.layout.remove_window(&window, transaction.clone());
self.add_default_dmabuf_pre_commit_hook(surface);

// If this is the only instance, then this transaction will complete
// immediately, so no need to set the timer.
if !transaction.is_last() {
transaction.register_deadline_timer(&self.niri.event_loop);
transaction.register_deadline_timer(
&self.niri.event_loop,
&self.niri.display_handle,
);
}

if was_active {
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 All @@ -507,12 +537,4 @@ impl State {
remove_pre_commit_hook(surface, prev);
}
}

pub fn remove_default_dmabuf_pre_commit_hook(&mut self, surface: &WlSurface) {
if let Some(hook) = self.niri.dmabuf_pre_commit_hook.remove(surface) {
remove_pre_commit_hook(surface, hook);
} else {
error!("tried to remove dmabuf pre-commit hook but there was none");
}
}
}
28 changes: 20 additions & 8 deletions 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 @@ -65,14 +66,15 @@ use smithay::wayland::xdg_activation::{
XdgActivationHandler, XdgActivationState, XdgActivationToken, XdgActivationTokenData,
};
use smithay::{
delegate_cursor_shape, delegate_data_control, delegate_data_device, delegate_dmabuf,
delegate_drm_lease, 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,
delegate_relative_pointer, delegate_seat, delegate_security_context, delegate_session_lock,
delegate_single_pixel_buffer, delegate_tablet_manager, delegate_text_input_manager,
delegate_viewporter, delegate_virtual_keyboard_manager, delegate_xdg_activation,
delegate_commit_timing, delegate_cursor_shape, delegate_data_control, delegate_data_device,
delegate_dmabuf, delegate_drm_lease, delegate_drm_syncobj, delegate_ext_data_control,
delegate_fifo, 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, delegate_relative_pointer, delegate_seat,
delegate_security_context, delegate_session_lock, delegate_single_pixel_buffer,
delegate_tablet_manager, delegate_text_input_manager, delegate_viewporter,
delegate_virtual_keyboard_manager, delegate_xdg_activation,
};

pub use crate::handlers::xdg_shell::KdeDecorationsModeState;
Expand Down Expand Up @@ -794,3 +796,13 @@ 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);

delegate_fifo!(State);
delegate_commit_timing!(State);
Loading
Loading