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 {
|
pub fn calculate_refresh_rate(mode: Mode) -> u32 {
|
||||||
let htotal = mode.hsync().2 as u32;
|
let htotal = mode.hsync().2 as u32;
|
||||||
let vtotal = mode.vsync().2 as u32;
|
let vtotal = mode.vsync().2 as u32;
|
||||||
|
|
|
||||||
|
|
@ -594,9 +594,10 @@ impl SurfaceThreadState {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.dmabuf_formats();
|
.dmabuf_formats();
|
||||||
|
|
||||||
self.timings.set_refresh_interval(Some(Duration::from_nanos(
|
self.timings
|
||||||
drm_helpers::calculate_refresh_rate(surface.pending_mode()) as u64,
|
.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);
|
self.timings.set_vrr(vrr);
|
||||||
|
|
||||||
match DrmCompositor::new(
|
match DrmCompositor::new(
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::{collections::VecDeque, num::NonZeroU64, time::Duration};
|
||||||
use smithay::utils::{Clock, Monotonic, Time};
|
use smithay::utils::{Clock, Monotonic, Time};
|
||||||
use tracing::error;
|
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;
|
const FRAME_TIME_WINDOW: usize = 3;
|
||||||
|
|
||||||
pub struct Timings {
|
pub struct Timings {
|
||||||
|
|
@ -37,7 +37,7 @@ impl Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frame_time(&self) -> Duration {
|
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)
|
/ (self.previous_frames.len() as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn avg_frametime(&self, window: usize) -> Duration {
|
pub fn avg_frametime(&self, window: usize) -> Option<Duration> {
|
||||||
if self.previous_frames.is_empty() || window == 0 {
|
if self.previous_frames.len() < window || window == 0 {
|
||||||
return MIN_RENDER_TIME;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.previous_frames
|
Some(
|
||||||
.iter()
|
self.previous_frames
|
||||||
.rev()
|
.iter()
|
||||||
.take(window)
|
.rev()
|
||||||
.map(|f| f.frame_time())
|
.take(window)
|
||||||
.sum::<Duration>()
|
.map(|f| f.frame_time())
|
||||||
/ (window.min(self.previous_frames.len()) as u32)
|
.sum::<Duration>()
|
||||||
|
/ (window.min(self.previous_frames.len()) as u32),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn avg_fps(&self) -> f64 {
|
pub fn avg_fps(&self) -> f64 {
|
||||||
|
|
@ -259,6 +261,10 @@ impl Timings {
|
||||||
return Duration::ZERO;
|
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 amount = avg_fps.round() as usize * 2;
|
||||||
let (max_disp, min_disp, avg_disp) = (
|
let (max_disp, min_disp, avg_disp) = (
|
||||||
timings.min_frametime(amount).as_secs_f64(),
|
|
||||||
timings.max_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(),
|
timings.avg_frametime(amount).as_secs_f64(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue