Skip to content

Commit

Permalink
drm/compositor: Introduce additional FrameFlags (instead of `FrameM…
Browse files Browse the repository at this point in the history
…ode`)
  • Loading branch information
Drakulix committed Dec 17, 2024
1 parent 0e56726 commit 06c52e6
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 34 deletions.
6 changes: 3 additions & 3 deletions anvil/src/udev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
62 changes: 35 additions & 27 deletions src/backend/drm/compositor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
//! };
Expand Down Expand Up @@ -104,7 +104,7 @@
//!
//! # let elements: Vec<WaylandSurfaceRenderElement<GlesRenderer>> = 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 {
Expand Down Expand Up @@ -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();
}
}

Expand Down Expand Up @@ -1667,15 +1671,15 @@ 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>(
&mut self,
renderer: &mut R,
elements: &'a [E],
clear_color: impl Into<Color32F>,
frame_mode: FrameMode,
frame_flags: FrameFlags,
) -> Result<RenderFrameResult<'a, A::Buffer, F::Framebuffer, E>, RenderFrameErrorType<A, F, R>>
where
E: RenderElement<R>,
Expand Down Expand Up @@ -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_ {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -2801,14 +2805,14 @@ where
output_transform: Transform,
output_geometry: Rectangle<i32, Physical>,
try_assign_primary_plane: bool,
frame_mode: FrameMode,
frame_flags: FrameFlags,
) -> Result<PlaneAssignment, Option<RenderingReason>>
where
R: Renderer + Bind<Dmabuf>,
E: RenderElement<R>,
{
// 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()
Expand All @@ -2829,7 +2833,7 @@ where
frame_state,
output_transform,
output_geometry,
frame_mode,
frame_flags,
) {
Ok(plane) => {
trace!(
Expand All @@ -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);
Expand All @@ -2870,7 +2874,7 @@ where
frame_state,
output_transform,
output_geometry,
frame_mode,
frame_flags,
) {
Ok(plane) => {
trace!(
Expand Down Expand Up @@ -2900,13 +2904,15 @@ where
frame_state: &mut CompositorFrameState<A, F>,
output_transform: Transform,
output_geometry: Rectangle<i32, Physical>,
frame_mode: FrameMode,
frame_flags: FrameFlags,
) -> Result<PlaneAssignment, Option<RenderingReason>>
where
R: Renderer,
E: RenderElement<R>,
{
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);
}

Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -2995,13 +3003,13 @@ where
frame_state: &mut CompositorFrameState<A, F>,
output_transform: Transform,
output_geometry: Rectangle<i32, Physical>,
frame_mode: FrameMode,
frame_flags: FrameFlags,
) -> Option<PlaneAssignment>
where
R: Renderer,
E: RenderElement<R>,
{
if !frame_mode.contains(FrameMode::CURSOR_PLANE_SCANOUT) {
if !frame_flags.contains(FrameFlags::ALLOW_CURSOR_PLANE_SCANOUT) {
return None;
}

Expand Down Expand Up @@ -3691,13 +3699,13 @@ where
frame_state: &mut CompositorFrameState<A, F>,
output_transform: Transform,
output_geometry: Rectangle<i32, Physical>,
frame_mode: FrameMode,
frame_flags: FrameFlags,
) -> Result<PlaneAssignment, Option<RenderingReason>>
where
R: Renderer,
E: RenderElement<R>,
{
if !frame_mode.contains(FrameMode::OVERLAY_PLANE_SCANOUT) {
if !frame_flags.contains(FrameFlags::ALLOW_OVERLAY_PLANE_SCANOUT) {
return Err(None);
}

Expand Down
8 changes: 4 additions & 4 deletions src/backend/drm/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{

use super::{
compositor::{
DrmCompositor, FrameError, FrameMode, FrameResult, RenderFrameError, RenderFrameErrorType,
DrmCompositor, FrameError, FrameFlags, FrameResult, RenderFrameError, RenderFrameErrorType,
RenderFrameResult,
},
exporter::ExportFramebuffer,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -599,7 +599,7 @@ where
renderer: &mut R,
elements: &'a [E],
clear_color: impl Into<Color32F>,
frame_mode: FrameMode,
frame_mode: FrameFlags,
) -> Result<RenderFrameResult<'a, A::Buffer, F::Framebuffer, E>, RenderFrameErrorType<A, F, R>>
where
E: RenderElement<R>,
Expand Down Expand Up @@ -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(())
Expand Down

0 comments on commit 06c52e6

Please sign in to comment.