// SPDX-License-Identifier: GPL-3.0-only use crate::{ state::{BackendData, State}, wayland::handlers::compositor::frame_time_filter_fn, }; use smithay::{ backend::{allocator::dmabuf::Dmabuf, renderer::element::Kind}, desktop::WindowSurfaceType, reexports::wayland_server::protocol::wl_surface::WlSurface, wayland::{ compositor::with_states, dmabuf::{DmabufFeedback, DmabufGlobal, DmabufHandler, DmabufState, ImportNotifier}, }, }; impl DmabufHandler for State { fn dmabuf_state(&mut self) -> &mut DmabufState { &mut self.common.dmabuf_state } fn dmabuf_imported( &mut self, global: &DmabufGlobal, dmabuf: Dmabuf, import_notifier: ImportNotifier, ) { let client = import_notifier.client(); match self.backend.dmabuf_imported(client.clone(), global, dmabuf) { Err(err) => { tracing::debug!(?err, "dmabuf import failed"); import_notifier.failed() } Ok(_) => { let _ = import_notifier.successful::(); } } } 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_surfaces .iter() .any(|f| { f.ended_at.is_none() && 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 } })) } }