diff --git a/src/backends/metal/present.rs b/src/backends/metal/present.rs index 36ee87b4..4c1e93f7 100644 --- a/src/backends/metal/present.rs +++ b/src/backends/metal/present.rs @@ -257,6 +257,8 @@ impl MetalConnector { apply_change!(plane.crtc_w); apply_change!(plane.crtc_h); if let Some(fb) = present_fb { + self.presentation_is_zero_copy + .set(fb.direct_scanout_data.is_some()); if fb.direct_scanout_data.is_none() { self.next_buffer.fetch_add(1); } @@ -404,9 +406,11 @@ impl MetalConnector { if try_async_flip { res = changes.commit(FLAGS | DRM_MODE_PAGE_FLIP_ASYNC, 0); if res.is_ok() { + self.presentation_is_sync.set(false); break 'commit; } } + self.presentation_is_sync.set(true); res = changes.commit(FLAGS, 0); } res.map_err(MetalError::Commit) diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index dc84e43f..6a47b8a4 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -24,7 +24,7 @@ use { }, ifs::{ wl_output::OutputId, - wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC}, + wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC, KIND_ZERO_COPY}, }, state::State, udev::UdevDevice, @@ -472,6 +472,8 @@ pub struct MetalConnector { pub post_commit_margin_decay: GeometricDecay, pub vblank_miss_sec: Cell, pub vblank_miss_this_sec: NumCell, + pub presentation_is_sync: Cell, + pub presentation_is_zero_copy: Cell, } impl Debug for MetalConnector { @@ -1069,6 +1071,8 @@ fn create_connector( post_commit_margin: Cell::new(DEFAULT_POST_COMMIT_MARGIN), vblank_miss_sec: Cell::new(0), vblank_miss_this_sec: Default::default(), + presentation_is_sync: Cell::new(false), + presentation_is_zero_copy: Cell::new(false), }); let futures = ConnectorFutures { _present: backend @@ -1975,13 +1979,24 @@ impl MetalBackend { .set(tv_sec as u64 * 1_000_000_000 + tv_usec as u64 * 1000 + dd.refresh as u64); { let global = self.state.root.outputs.get(&connector.connector_id); + let mut flags = KIND_HW_COMPLETION; + if connector.presentation_is_sync.get() { + flags |= KIND_VSYNC; + } + if connector.presentation_is_zero_copy.get() { + flags |= KIND_ZERO_COPY; + } + let refresh = match crtc.vrr_enabled.value.get() { + true => 0, + false => dd.refresh, + }; if let Some(g) = &global { g.presented( tv_sec as _, tv_usec * 1000, - dd.refresh, + refresh, connector.sequence.get(), - KIND_VSYNC | KIND_HW_COMPLETION, + flags, ); } } diff --git a/src/ifs/wp_presentation_feedback.rs b/src/ifs/wp_presentation_feedback.rs index d926c5a8..aa9de5cc 100644 --- a/src/ifs/wp_presentation_feedback.rs +++ b/src/ifs/wp_presentation_feedback.rs @@ -22,7 +22,6 @@ pub const KIND_VSYNC: u32 = 0x1; #[expect(dead_code)] pub const KIND_HW_CLOCK: u32 = 0x2; pub const KIND_HW_COMPLETION: u32 = 0x4; -#[expect(dead_code)] pub const KIND_ZERO_COPY: u32 = 0x8; impl WpPresentationFeedback {