From 06c52e62dfd2894d3e31fcff27fd115ca0ef56fe Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 17 Dec 2024 13:13:08 +0100 Subject: [PATCH] drm/compositor: Introduce additional `FrameFlags` (instead of `FrameMode`) --- anvil/src/udev.rs | 6 +-- src/backend/drm/compositor/mod.rs | 62 +++++++++++++++++-------------- src/backend/drm/output.rs | 8 ++-- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 0891dac8455a..d138c53f4330 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -31,7 +31,7 @@ use smithay::{ Fourcc, }, drm::{ - compositor::{DrmCompositor, FrameMode}, + compositor::{DrmCompositor, FrameFlags}, output::{DrmOutput, DrmOutputManager, DrmOutputRenderElements}, CreateDrmNodeError, DrmAccessError, DrmDevice, DrmDeviceFd, DrmError, DrmEvent, DrmEventMetadata, DrmNode, DrmSurface, GbmBufferedSurface, NodeType, @@ -1512,9 +1512,9 @@ fn render_surface<'a>( output_elements(output, space, custom_elements, renderer, show_window_preview); let frame_mode = if surface.disable_direct_scanout { - FrameMode::COMPOSITE + FrameFlags::empty() } else { - FrameMode::ALL + FrameFlags::DEFAULT }; let (rendered, states) = surface .drm_output diff --git a/src/backend/drm/compositor/mod.rs b/src/backend/drm/compositor/mod.rs index 6dfb3296e3fc..5e04059094db 100644 --- a/src/backend/drm/compositor/mod.rs +++ b/src/backend/drm/compositor/mod.rs @@ -58,7 +58,7 @@ //! # use std::{collections::HashSet, mem::MaybeUninit}; //! # //! use smithay::{ -//! backend::drm::{compositor::{DrmCompositor, FrameMode}, DrmSurface}, +//! backend::drm::{compositor::{DrmCompositor, FrameFlags}, DrmSurface}, //! output::{Output, PhysicalProperties, Subpixel}, //! utils::Size, //! }; @@ -104,7 +104,7 @@ //! //! # let elements: Vec> = Vec::new(); //! let render_frame_result = compositor -//! .render_frame::<_, _>(&mut renderer, &elements, CLEAR_COLOR, FrameMode::ALL) +//! .render_frame::<_, _>(&mut renderer, &elements, CLEAR_COLOR, FrameFlags::DEFAULT) //! .expect("failed to render frame"); //! //! if !render_frame_result.is_empty { @@ -1014,19 +1014,23 @@ where bitflags::bitflags! { /// Possible flags for a DMA buffer #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] - pub struct FrameMode: u32 { - /// Allow to realize the frame by compositing elements on the primary plane - const COMPOSITE = 1; + pub struct FrameFlags: u32 { /// Allow to realize the frame by scanning out elements on the primary plane - const PRIMARY_PLANE_SCANOUT = 2; + /// with the same pixel format as the main swapchain + const ALLOW_PRIMARY_PLANE_SCANOUT = 1; + /// Allow to realize the frame by scanning out elements on the primary plane + /// regardless of their format + const ALLOW_PRIMARY_PLANE_SCANOUT_ANY = 2; /// Allow to realize the frame by scanning out elements on overlay planes - const OVERLAY_PLANE_SCANOUT = 4; + const ALLOW_OVERLAY_PLANE_SCANOUT = 4; /// Allow to realize the frame by scanning out elements on cursor planes - const CURSOR_PLANE_SCANOUT = 8; + const ALLOW_CURSOR_PLANE_SCANOUT = 8; + /// Return `EmptyFrame`, if only the cursor plane would have been updated + const SKIP_CURSOR_ONLY_UPDATES = 16; /// Allow to realize the frame by assigning elements on any plane - const SCANOUT = Self::PRIMARY_PLANE_SCANOUT.bits() | Self::OVERLAY_PLANE_SCANOUT.bits() | Self::CURSOR_PLANE_SCANOUT.bits(); - /// Allow all available operations to realize the frame - const ALL = Self::COMPOSITE.bits() | Self::SCANOUT.bits(); + const ALLOW_SCANOUT = Self::ALLOW_PRIMARY_PLANE_SCANOUT.bits() | Self::ALLOW_OVERLAY_PLANE_SCANOUT.bits() | Self::ALLOW_CURSOR_PLANE_SCANOUT.bits(); + /// Safe default set of flags + const DEFAULT = Self::ALLOW_SCANOUT.bits(); } } @@ -1667,7 +1671,7 @@ where /// Render the next frame /// /// - `elements` for this frame in front-to-back order - /// - `frame_mode` specifies techniques allowed to realize the frame + /// - `frame_flags` specifies techniques allowed to realize the frame #[instrument(level = "trace", parent = &self.span, skip_all)] #[profiling::function] pub fn render_frame<'a, R, E>( @@ -1675,7 +1679,7 @@ where renderer: &mut R, elements: &'a [E], clear_color: impl Into, - frame_mode: FrameMode, + frame_flags: FrameFlags, ) -> Result, RenderFrameErrorType> where E: RenderElement, @@ -2013,7 +2017,7 @@ where output_transform, output_geometry, try_assign_primary_plane, - frame_mode, + frame_flags, ) { Ok(direct_scan_out_plane) => { match direct_scan_out_plane.type_ { @@ -2355,7 +2359,7 @@ where }; // if the update only contains a cursor position update, skip it for vrr - if self.vrr_enabled() + if frame_flags.contains(FrameFlags::SKIP_CURSOR_ONLY_UPDATES) && allow_partial_update && next_frame_state.planes.iter().all(|(plane, state)| { state.skip @@ -2801,14 +2805,14 @@ where output_transform: Transform, output_geometry: Rectangle, try_assign_primary_plane: bool, - frame_mode: FrameMode, + frame_flags: FrameFlags, ) -> Result> where R: Renderer + Bind, E: RenderElement, { // Check if we have a free plane, otherwise we can exit early - if !frame_mode.intersects(FrameMode::SCANOUT) { + if !frame_flags.intersects(FrameFlags::ALLOW_SCANOUT) { trace!( "skipping direct scan-out for element {:?}, no free planes", element.id() @@ -2829,7 +2833,7 @@ where frame_state, output_transform, output_geometry, - frame_mode, + frame_flags, ) { Ok(plane) => { trace!( @@ -2852,7 +2856,7 @@ where frame_state, output_transform, output_geometry, - frame_mode, + frame_flags, ) { trace!("assigned element {:?} to cursor {:?}", element.id(), plane.handle); return Ok(plane); @@ -2870,7 +2874,7 @@ where frame_state, output_transform, output_geometry, - frame_mode, + frame_flags, ) { Ok(plane) => { trace!( @@ -2900,13 +2904,15 @@ where frame_state: &mut CompositorFrameState, output_transform: Transform, output_geometry: Rectangle, - frame_mode: FrameMode, + frame_flags: FrameFlags, ) -> Result> where R: Renderer, E: RenderElement, { - if !frame_mode.contains(FrameMode::PRIMARY_PLANE_SCANOUT) { + if !frame_flags + .intersects(FrameFlags::ALLOW_PRIMARY_PLANE_SCANOUT | FrameFlags::ALLOW_PRIMARY_PLANE_SCANOUT_ANY) + { return Err(None); } @@ -2935,7 +2941,9 @@ where .expect("We have a buffer for the primary plane") .buffer { - if slot.format() != element_config.properties.format { + if !frame_flags.contains(FrameFlags::ALLOW_PRIMARY_PLANE_SCANOUT_ANY) + && slot.format() != element_config.properties.format + { trace!( "failed to assign element {:?} to primary {:?}, format doesn't match", element.id(), @@ -2995,13 +3003,13 @@ where frame_state: &mut CompositorFrameState, output_transform: Transform, output_geometry: Rectangle, - frame_mode: FrameMode, + frame_flags: FrameFlags, ) -> Option where R: Renderer, E: RenderElement, { - if !frame_mode.contains(FrameMode::CURSOR_PLANE_SCANOUT) { + if !frame_flags.contains(FrameFlags::ALLOW_CURSOR_PLANE_SCANOUT) { return None; } @@ -3691,13 +3699,13 @@ where frame_state: &mut CompositorFrameState, output_transform: Transform, output_geometry: Rectangle, - frame_mode: FrameMode, + frame_flags: FrameFlags, ) -> Result> where R: Renderer, E: RenderElement, { - if !frame_mode.contains(FrameMode::OVERLAY_PLANE_SCANOUT) { + if !frame_flags.contains(FrameFlags::ALLOW_OVERLAY_PLANE_SCANOUT) { return Err(None); } diff --git a/src/backend/drm/output.rs b/src/backend/drm/output.rs index 345bbdb3f3aa..e4e3900cf429 100644 --- a/src/backend/drm/output.rs +++ b/src/backend/drm/output.rs @@ -25,7 +25,7 @@ use crate::{ use super::{ compositor::{ - DrmCompositor, FrameError, FrameMode, FrameResult, RenderFrameError, RenderFrameErrorType, + DrmCompositor, FrameError, FrameFlags, FrameResult, RenderFrameError, RenderFrameErrorType, RenderFrameResult, }, exporter::ExportFramebuffer, @@ -379,7 +379,7 @@ where }; // We need to render the new output once to lock in the primary plane as used with the new format, so we don't hit the bandwidth issue, - // when downstream potentially uses `FrameMode::ALL` immediately after this. + // when downstream potentially uses `FrameFlags::DEFAULT` immediately after this. let compositor = write_guard.get_mut(&crtc).unwrap(); let compositor = compositor.get_mut().unwrap(); @@ -599,7 +599,7 @@ where renderer: &mut R, elements: &'a [E], clear_color: impl Into, - frame_mode: FrameMode, + frame_mode: FrameFlags, ) -> Result, RenderFrameErrorType> where E: RenderElement, @@ -922,7 +922,7 @@ where .map(|(ref elements, ref color)| (&**elements, color)) .unwrap_or((&[], &Color32F::BLACK)); compositor - .render_frame(renderer, elements, *clear_color, FrameMode::COMPOSITE) + .render_frame(renderer, elements, *clear_color, FrameFlags::empty()) .map_err(DrmOutputManagerError::RenderFrame)?; compositor.commit_frame().map_err(DrmOutputManagerError::Frame)?; Ok(())