kms: Fix frame scheduling
This commit is contained in:
parent
5617f3228b
commit
8da3ac6d75
4 changed files with 25 additions and 17 deletions
|
|
@ -316,6 +316,7 @@ fn get_manufacturer(vendor: &[char; 3]) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns refresh rate in milliherz
|
||||
pub fn calculate_refresh_rate(mode: Mode) -> u32 {
|
||||
let htotal = mode.hsync().2 as u32;
|
||||
let vtotal = mode.vsync().2 as u32;
|
||||
|
|
|
|||
|
|
@ -594,9 +594,10 @@ impl SurfaceThreadState {
|
|||
.unwrap()
|
||||
.dmabuf_formats();
|
||||
|
||||
self.timings.set_refresh_interval(Some(Duration::from_nanos(
|
||||
drm_helpers::calculate_refresh_rate(surface.pending_mode()) as u64,
|
||||
)));
|
||||
self.timings
|
||||
.set_refresh_interval(Some(Duration::from_secs_f64(
|
||||
1_000.0 / drm_helpers::calculate_refresh_rate(surface.pending_mode()) as f64,
|
||||
)));
|
||||
self.timings.set_vrr(vrr);
|
||||
|
||||
match DrmCompositor::new(
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{collections::VecDeque, num::NonZeroU64, time::Duration};
|
|||
use smithay::utils::{Clock, Monotonic, Time};
|
||||
use tracing::error;
|
||||
|
||||
const MIN_RENDER_TIME: Duration = Duration::from_millis(5);
|
||||
const FRAME_TIME_BUFFER: Duration = Duration::from_millis(1);
|
||||
const FRAME_TIME_WINDOW: usize = 3;
|
||||
|
||||
pub struct Timings {
|
||||
|
|
@ -37,7 +37,7 @@ impl Frame {
|
|||
}
|
||||
|
||||
fn frame_time(&self) -> Duration {
|
||||
Time::elapsed(&self.render_start, self.presentation_submitted)
|
||||
Time::elapsed(&self.render_start, self.presentation_presented)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -179,18 +179,20 @@ impl Timings {
|
|||
/ (self.previous_frames.len() as u32)
|
||||
}
|
||||
|
||||
pub fn avg_frametime(&self, window: usize) -> Duration {
|
||||
if self.previous_frames.is_empty() || window == 0 {
|
||||
return MIN_RENDER_TIME;
|
||||
pub fn avg_frametime(&self, window: usize) -> Option<Duration> {
|
||||
if self.previous_frames.len() < window || window == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.previous_frames
|
||||
.iter()
|
||||
.rev()
|
||||
.take(window)
|
||||
.map(|f| f.frame_time())
|
||||
.sum::<Duration>()
|
||||
/ (window.min(self.previous_frames.len()) as u32)
|
||||
Some(
|
||||
self.previous_frames
|
||||
.iter()
|
||||
.rev()
|
||||
.take(window)
|
||||
.map(|f| f.frame_time())
|
||||
.sum::<Duration>()
|
||||
/ (window.min(self.previous_frames.len()) as u32),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn avg_fps(&self) -> f64 {
|
||||
|
|
@ -259,6 +261,10 @@ impl Timings {
|
|||
return Duration::ZERO;
|
||||
}
|
||||
|
||||
estimated_presentation_time.saturating_sub(self.avg_frametime(FRAME_TIME_WINDOW))
|
||||
let Some(avg_frametime) = self.avg_frametime(FRAME_TIME_WINDOW) else {
|
||||
return Duration::ZERO;
|
||||
};
|
||||
|
||||
estimated_presentation_time.saturating_sub(avg_frametime + FRAME_TIME_BUFFER)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ pub fn fps_ui<'a>(
|
|||
|
||||
let amount = avg_fps.round() as usize * 2;
|
||||
let (max_disp, min_disp, avg_disp) = (
|
||||
timings.min_frametime(amount).as_secs_f64(),
|
||||
timings.max_frametime(amount).as_secs_f64(),
|
||||
timings.min_frametime(amount).as_secs_f64(),
|
||||
timings.avg_frametime(amount).as_secs_f64(),
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue