diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 76f590b26de9..631f1fb1c896 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -169,7 +169,9 @@ impl DmabufHandler for AnvilState { .and_then(|mut renderer| renderer.import_dmabuf(&dmabuf, None)) .is_ok() { - dmabuf.set_node(self.backend_data.primary_gpu); + if dmabuf.node().is_none() { + dmabuf.set_node(self.backend_data.primary_gpu); + } let _ = notifier.successful::>(); } else { notifier.failed(); @@ -831,17 +833,25 @@ fn get_surface_dmabuf_feedback( let builder = DmabufFeedbackBuilder::new(primary_gpu.dev_id(), primary_formats); let render_feedback = builder .clone() - .add_preference_tranche(render_node.dev_id(), None, render_formats.clone()) + .add_preference_tranche( + render_node.dev_id(), + zwp_linux_dmabuf_feedback_v1::TrancheFlags::Sampling, + render_formats.clone(), + ) .build() .unwrap(); let scanout_feedback = builder .add_preference_tranche( surface.device_fd().dev_id().unwrap(), - Some(zwp_linux_dmabuf_feedback_v1::TrancheFlags::Scanout), + zwp_linux_dmabuf_feedback_v1::TrancheFlags::Scanout, planes_formats, ) - .add_preference_tranche(render_node.dev_id(), None, render_formats) + .add_preference_tranche( + render_node.dev_id(), + zwp_linux_dmabuf_feedback_v1::TrancheFlags::Sampling, + render_formats, + ) .build() .unwrap(); diff --git a/src/wayland/dmabuf/dispatch.rs b/src/wayland/dmabuf/dispatch.rs index 93819f113cf6..66105cd95114 100644 --- a/src/wayland/dmabuf/dispatch.rs +++ b/src/wayland/dmabuf/dispatch.rs @@ -74,6 +74,7 @@ where formats: data.formats.clone(), modifier: Mutex::new(None), planes: Mutex::new(Vec::with_capacity(MAX_PLANES)), + node: Mutex::new(None), }, ); } @@ -294,6 +295,10 @@ where } } + zwp_linux_buffer_params_v1::Request::SetTargetDevice { device } => { + *data.node.lock().unwrap() = device[0..8].try_into().ok().map(u64::from_ne_bytes); + } + zwp_linux_buffer_params_v1::Request::Create { width, height, @@ -301,7 +306,9 @@ where flags, } => { // create_dmabuf performs an implicit ensure_unused function call. - if let Some(dmabuf) = data.create_dmabuf(params, width, height, format, flags, None) { + if let Some(dmabuf) = + data.create_dmabuf(params, width, height, format, flags, *data.node.lock().unwrap()) + { if state.dmabuf_state().globals.contains_key(&data.id) { let notifier = ImportNotifier::new( params.clone(), @@ -326,7 +333,9 @@ where } => { // Client is killed if the if statement is not taken. // create_dmabuf performs an implicit ensure_unused function call. - if let Some(dmabuf) = data.create_dmabuf(params, width, height, format, flags, None) { + if let Some(dmabuf) = + data.create_dmabuf(params, width, height, format, flags, *data.node.lock().unwrap()) + { if state.dmabuf_state().globals.contains_key(&data.id) { // The buffer isn't technically valid during data_init, but the client is not allowed to use the buffer until ready. let buffer = data_init.init(buffer_id, dmabuf.clone()); diff --git a/src/wayland/dmabuf/mod.rs b/src/wayland/dmabuf/mod.rs index 9270c96e3299..c8273a1e2465 100644 --- a/src/wayland/dmabuf/mod.rs +++ b/src/wayland/dmabuf/mod.rs @@ -202,7 +202,8 @@ use indexmap::{IndexMap, IndexSet}; use rustix::fs::{seek, SeekFrom}; use wayland_protocols::wp::linux_dmabuf::zv1::server::{ zwp_linux_buffer_params_v1::{self, ZwpLinuxBufferParamsV1}, - zwp_linux_dmabuf_feedback_v1, zwp_linux_dmabuf_v1, + zwp_linux_dmabuf_feedback_v1::{self, TrancheFlags}, + zwp_linux_dmabuf_v1, }; use wayland_server::{ backend::{GlobalId, InvalidId}, @@ -317,7 +318,7 @@ impl DmabufFeedbackBuilder { let feedback_formats: IndexSet = formats.into_iter().collect(); let format_indices: IndexSet = (0..feedback_formats.len()).collect(); let main_tranche = DmabufFeedbackTranche { - flags: zwp_linux_dmabuf_feedback_v1::TrancheFlags::empty(), + flags: zwp_linux_dmabuf_feedback_v1::TrancheFlags::Sampling, indices: format_indices, target_device: main_device, }; @@ -342,11 +343,9 @@ impl DmabufFeedbackBuilder { pub fn add_preference_tranche( mut self, target_device: libc::dev_t, - flags: Option, + flags: zwp_linux_dmabuf_feedback_v1::TrancheFlags, formats: impl IntoIterator, ) -> Self { - let flags = flags.unwrap_or(zwp_linux_dmabuf_feedback_v1::TrancheFlags::empty()); - let mut tranche = DmabufFeedbackTranche { target_device, flags, @@ -448,7 +447,9 @@ impl PartialEq for DmabufFeedback { impl DmabufFeedback { /// Send this feedback to the provided [`ZwpLinuxDmabufFeedbackV1`](zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1) pub fn send(&self, feedback: &zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1) { - feedback.main_device(self.0.main_device.to_ne_bytes().to_vec()); + if feedback.version() <= 5 { + feedback.main_device(self.0.main_device.to_ne_bytes().to_vec()); + } feedback.format_table( self.0.format_table.file.as_fd(), self.0.format_table.file.size() as u32, @@ -456,7 +457,11 @@ impl DmabufFeedback { for tranche in self.0.tranches.iter() { feedback.tranche_target_device(tranche.target_device.to_ne_bytes().to_vec()); - feedback.tranche_flags(tranche.flags); + if feedback.version() <= 5 && tranche.flags.contains(TrancheFlags::Scanout) { + feedback.tranche_flags(TrancheFlags::Scanout); + } else { + feedback.tranche_flags(tranche.flags); + } feedback.tranche_formats( tranche .indices @@ -718,7 +723,7 @@ impl DmabufState { ); let formats = Arc::new(formats); - let version = if default_feedback.is_some() { 5 } else { 3 }; + let version = if default_feedback.is_some() { 6 } else { 3 }; let known_default_feedbacks = Arc::new(Mutex::new(Vec::new())); let default_feedback = default_feedback.map(|f| Arc::new(Mutex::new(f.clone()))); @@ -837,6 +842,8 @@ pub struct DmabufParamsData { /// Pending planes for the params. modifier: Mutex>, planes: Mutex>, + + node: Mutex>, } /// A handle to a registered dmabuf global.