From 9e6d0718ddb41d73ff22fe3c295b85a7b3a8ad38 Mon Sep 17 00:00:00 2001 From: Christian Meissl Date: Thu, 14 Nov 2024 18:05:26 +0100 Subject: [PATCH] anvil: enable fifo protocol --- anvil/src/state.rs | 28 ++++++++++++++++++++++++++-- anvil/src/udev.rs | 24 ++++++++++++++++++++---- anvil/src/winit.rs | 19 ++++++++++++++++--- anvil/src/x11.rs | 19 ++++++++++++++++--- 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/anvil/src/state.rs b/anvil/src/state.rs index 28558bd109f5..ae99ed94a04f 100644 --- a/anvil/src/state.rs +++ b/anvil/src/state.rs @@ -48,6 +48,7 @@ use smithay::{ wayland::{ compositor::{get_parent, with_states, CompositorClientState, CompositorState}, dmabuf::DmabufFeedback, + fifo::{FifoBarrierCachedState, FifoManagerState}, fractional_scale::{with_fractional_scale, FractionalScaleHandler, FractionalScaleManagerState}, input_method::{InputMethodHandler, InputMethodManagerState, PopupSurface}, keyboard_shortcuts_inhibit::{ @@ -152,6 +153,7 @@ pub struct AnvilState { #[cfg(feature = "xwayland")] pub xwayland_shell_state: xwayland_shell::XWaylandShellState, pub single_pixel_buffer_state: SinglePixelBufferState, + pub fifo_manager_state: FifoManagerState, pub dnd_icon: Option, @@ -565,6 +567,8 @@ smithay::delegate_xdg_foreign!(@ AnvilState AnvilState); +smithay::delegate_fifo!(@ AnvilState); + impl AnvilState { pub fn init( display: Display>, @@ -627,6 +631,7 @@ impl AnvilState { let fractional_scale_manager_state = FractionalScaleManagerState::new::(&dh); let xdg_foreign_state = XdgForeignState::new::(&dh); let single_pixel_buffer_state = SinglePixelBufferState::new::(&dh); + let fifo_manager_state = FifoManagerState::new::(&dh); TextInputManagerState::new::(&dh); InputMethodManagerState::new::(&dh, |_client| true); VirtualKeyboardManagerState::new::(&dh, |_client| true); @@ -686,6 +691,7 @@ impl AnvilState { fractional_scale_manager_state, xdg_foreign_state, single_pixel_buffer_state, + fifo_manager_state, dnd_icon: None, suppressed_keys: Vec::new(), cursor_status: CursorImageStatus::default_named(), @@ -767,13 +773,16 @@ pub struct SurfaceDmabufFeedback<'a> { } #[profiling::function] -pub fn post_repaint( +pub fn post_repaint( output: &Output, render_element_states: &RenderElementStates, space: &Space, dmabuf_feedback: Option>, time: impl Into, -) { + mut blocker_cleared: F, +) where + F: FnMut(&WlSurface), +{ let time = time.into(); let throttle = Some(Duration::from_secs(1)); @@ -806,6 +815,21 @@ pub fn post_repaint( ) }); } + if let Some(surface) = window.wl_surface() { + let fifo_barrier = with_states(&surface, |states| { + states + .cached_state + .get::() + .current() + .barrier + .take() + }); + + if let Some(fifo_barrier) = fifo_barrier { + fifo_barrier.signal(); + blocker_cleared(&surface); + } + } } }); let map = smithay::desktop::layer_map_for_output(output); diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 76f590b26de9..dcc74d7bb761 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -74,11 +74,15 @@ use smithay::{ linux_dmabuf::zv1::server::zwp_linux_dmabuf_feedback_v1, presentation_time::server::wp_presentation_feedback, }, - wayland_server::{backend::GlobalId, protocol::wl_surface, Display, DisplayHandle}, + wayland_server::{ + backend::GlobalId, + protocol::wl_surface::{self, WlSurface}, + Display, DisplayHandle, Resource, + }, }, utils::{Clock, DeviceFd, IsAlive, Logical, Monotonic, Physical, Point, Rectangle, Scale, Transform}, wayland::{ - compositor, + compositor::{self, CompositorHandler}, dmabuf::{ DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier, }, @@ -1488,6 +1492,13 @@ impl AnvilState { &mut self.cursor_status, &self.clock, self.show_window_preview, + |surface| { + let client = surface.client().unwrap(); + self.handle.insert_idle(move |data| { + let dh = data.display_handle.clone(); + data.client_compositor_state(&client).blocker_cleared(data, &dh); + }); + }, ); let reschedule = match &result { Ok(has_rendered) => !has_rendered, @@ -1586,7 +1597,7 @@ impl AnvilState { #[allow(clippy::too_many_arguments)] #[profiling::function] -fn render_surface<'a>( +fn render_surface<'a, F>( surface: &'a mut SurfaceData, renderer: &mut UdevRenderer<'a>, space: &Space, @@ -1598,7 +1609,11 @@ fn render_surface<'a>( cursor_status: &mut CursorImageStatus, clock: &Clock, show_window_preview: bool, -) -> Result { + blocker_cleared: F, +) -> Result +where + F: FnMut(&WlSurface), +{ let output_geometry = space.output_geometry(output).unwrap(); let scale = Scale::from(output.current_scale().fractional_scale()); @@ -1697,6 +1712,7 @@ fn render_surface<'a>( scanout_feedback: &feedback.scanout_feedback, }), clock.now(), + blocker_cleared, ); if rendered { diff --git a/anvil/src/winit.rs b/anvil/src/winit.rs index 8c6c85664d6a..39141ce9f437 100644 --- a/anvil/src/winit.rs +++ b/anvil/src/winit.rs @@ -33,12 +33,12 @@ use smithay::{ reexports::{ calloop::EventLoop, wayland_protocols::wp::presentation_time::server::wp_presentation_feedback, - wayland_server::{protocol::wl_surface, Display}, + wayland_server::{protocol::wl_surface, Display, Resource}, winit::platform::pump_events::PumpStatus, }, utils::{IsAlive, Scale, Transform}, wayland::{ - compositor, + compositor::{self, CompositorHandler}, dmabuf::{ DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier, }, @@ -385,7 +385,20 @@ pub fn run_winit() { // Send frame events so that client start drawing their next frame let time = state.clock.now(); - post_repaint(&output, &render_output_result.states, &state.space, None, time); + post_repaint( + &output, + &render_output_result.states, + &state.space, + None, + time, + |surface| { + let client = surface.client().unwrap(); + state.handle.insert_idle(move |data| { + let dh = data.display_handle.clone(); + data.client_compositor_state(&client).blocker_cleared(data, &dh); + }); + }, + ); if has_rendered { let mut output_presentation_feedback = diff --git a/anvil/src/x11.rs b/anvil/src/x11.rs index 128f8a6d5385..09b4cbf85b49 100644 --- a/anvil/src/x11.rs +++ b/anvil/src/x11.rs @@ -39,11 +39,11 @@ use smithay::{ calloop::EventLoop, gbm, wayland_protocols::wp::presentation_time::server::wp_presentation_feedback, - wayland_server::{protocol::wl_surface, Display}, + wayland_server::{protocol::wl_surface, Display, Resource}, }, utils::{DeviceFd, IsAlive, Scale}, wayland::{ - compositor, + compositor::{self, CompositorHandler}, dmabuf::{ DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier, }, @@ -402,7 +402,20 @@ pub fn run_x11() { // Send frame events so that client start drawing their next frame let time = state.clock.now(); - post_repaint(&output, &render_output_result.states, &state.space, None, time); + post_repaint( + &output, + &render_output_result.states, + &state.space, + None, + time, + |surface| { + let client = surface.client().unwrap(); + state.handle.insert_idle(move |data| { + let dh = data.display_handle.clone(); + data.client_compositor_state(&client).blocker_cleared(data, &dh); + }); + }, + ); if render_output_result.damage.is_some() { let mut output_presentation_feedback =