From 7b8fca9ece53a2169daf16684437212fa73bad1c Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 23 Dec 2025 16:38:26 +0100 Subject: [PATCH] wayland/dmabuf: Send initial surface feedback --- src/backend/kms/surface/mod.rs | 2 +- src/wayland/handlers/dmabuf.rs | 67 ++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/backend/kms/surface/mod.rs b/src/backend/kms/surface/mod.rs index 46865bd3..63873b64 100644 --- a/src/backend/kms/surface/mod.rs +++ b/src/backend/kms/surface/mod.rs @@ -118,7 +118,7 @@ pub struct Surface { known_nodes: HashSet, active: Arc, - pub(super) feedback: HashMap, + pub feedback: HashMap, pub(super) primary_plane_formats: FormatSet, overlay_plane_formats: Option, diff --git a/src/wayland/handlers/dmabuf.rs b/src/wayland/handlers/dmabuf.rs index baae1df4..294aab2b 100644 --- a/src/wayland/handlers/dmabuf.rs +++ b/src/wayland/handlers/dmabuf.rs @@ -1,10 +1,18 @@ // SPDX-License-Identifier: GPL-3.0-only -use crate::state::State; +use crate::{ + state::{BackendData, State}, + wayland::handlers::compositor::frame_time_filter_fn, +}; use smithay::{ - backend::allocator::dmabuf::Dmabuf, + backend::{allocator::dmabuf::Dmabuf, renderer::element::Kind}, delegate_dmabuf, - wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier}, + desktop::WindowSurfaceType, + reexports::wayland_server::protocol::wl_surface::WlSurface, + wayland::{ + compositor::with_states, + dmabuf::{DmabufFeedback, DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier}, + }, }; impl DmabufHandler for State { @@ -29,6 +37,59 @@ impl DmabufHandler for State { } } } + + fn new_surface_feedback( + &mut self, + surface: &WlSurface, + global: &DmabufGlobal, + ) -> Option { + let BackendData::Kms(kms) = &self.backend else { + return None; + }; + let shell = self.common.shell.read(); + + let (handle, output) = shell.workspace_for_surface(surface)?; + let is_fullscreen = shell + .workspaces + .space_for_handle(&handle)? + .fullscreen + .as_ref() + .is_some_and(|f| f.surface.has_surface(surface, WindowSurfaceType::all())); + + let node = kms + .drm_devices + .values() + .find(|device| { + device + .socket + .as_ref() + .map(|s| &s.dmabuf_global == global) + .unwrap_or(false) + })? + .inner + .render_node; + let kms_surface = kms + .drm_devices + .values() + .find_map(|device| device.inner.surfaces.values().find(|s| s.output == output))?; + let feedback = kms_surface.feedback.get(&node)?.clone(); + + Some(with_states(surface, |data| { + if is_fullscreen { + feedback + .primary_scanout_feedback + .unwrap_or(feedback.render_feedback) + } else { + if frame_time_filter_fn(data) == Kind::ScanoutCandidate { + feedback + .overlay_scanout_feedback + .unwrap_or(feedback.render_feedback) + } else { + feedback.render_feedback + } + } + })) + } } delegate_dmabuf!(State);