Skip to content

Commit

Permalink
drm: Add vrr property helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Nov 18, 2024
1 parent 5e137dc commit d8b3de8
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 15 deletions.
38 changes: 37 additions & 1 deletion src/backend/drm/compositor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ use crate::{
wayland::{shm, single_pixel_buffer},
};

use super::{error::AccessError, DrmDeviceFd, DrmSurface, Framebuffer, PlaneClaim, PlaneInfo, Planes};
use super::{
error::AccessError, surface::VrrSupport, DrmDeviceFd, DrmSurface, Framebuffer, PlaneClaim, PlaneInfo,
Planes,
};

pub mod dumb;
mod elements;
Expand Down Expand Up @@ -1582,6 +1585,7 @@ where
primary_plane_damage_bag: DamageBag<i32, BufferCoords>,
supports_fencing: bool,
direct_scanout: bool,
vrr: bool,
reset_pending: bool,
signaled_fence: Option<Arc<OwnedFd>>,

Expand Down Expand Up @@ -1769,6 +1773,7 @@ where
primary_plane_damage_bag: DamageBag::new(4),
primary_is_opaque: is_opaque,
direct_scanout: true,
vrr: false,
reset_pending: true,
signaled_fence,
current_frame,
Expand Down Expand Up @@ -2357,6 +2362,17 @@ where
}
}

// If we only have a cursor update and vrr is enabled,
// don't update to not artificially increase the framerate
if self.vrr
&& cursor_plane_element.is_some()
&& overlay_plane_elements.is_empty()
&& primary_plane_scanout_element.is_none()
&& primary_plane_elements.is_empty()
{
let _ = cursor_plane_element.take();
}

// Cleanup old state (e.g. old dmabuffers)
for element_state in element_states.values_mut() {
element_state.fb_cache.cleanup();
Expand Down Expand Up @@ -2930,6 +2946,26 @@ where
Ok(())
}

/// Returns if Variable Refresh Rate is advertised as supported by the given connector.
///
/// See [`DrmSurface::vrr_supported`] for more details.
pub fn vrr_supported(&self, conn: connector::Handle) -> FrameResult<VrrSupport, A, F> {
self.surface.vrr_supported(conn).map_err(FrameError::DrmError)
}

/// Tries to set variable refresh rate (VRR) for the next frame.
///
/// Doing so might cause the next frame to trigger a modeset.
/// Check [`DrmCompositor::vrr_supported`], which indicates if VRR can be
/// used without a modeset on the attached connectors.
pub fn use_vrr(&mut self, vrr: bool) -> FrameResult<(), A, F> {
let res = self.surface.use_vrr(vrr).map_err(FrameError::DrmError);
if res.is_ok() {
self.vrr = vrr;
}
res
}

/// Set the [`DebugFlags`] to use
///
/// Note: This will reset the primary plane swapchain if
Expand Down
2 changes: 1 addition & 1 deletion src/backend/drm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub use error::Error as DrmError;
use indexmap::IndexSet;
#[cfg(feature = "backend_gbm")]
pub use surface::gbm::{Error as GbmBufferedSurfaceError, GbmBufferedSurface};
pub use surface::{DrmSurface, PlaneConfig, PlaneDamageClips, PlaneState};
pub use surface::{DrmSurface, PlaneConfig, PlaneDamageClips, PlaneState, VrrSupport};

use drm::{
control::{crtc, framebuffer, plane, Device as ControlDevice, PlaneType},
Expand Down
Loading

0 comments on commit d8b3de8

Please sign in to comment.