kms: Optimize frame scheduling

This commit is contained in:
Victoria Brekenfeld 2024-02-14 17:46:33 +01:00 committed by Victoria Brekenfeld
parent 96518a9f29
commit db27fa483d
2 changed files with 16 additions and 12 deletions

View file

@ -91,7 +91,7 @@ use socket::*;
use super::render::{element::AsGlowRenderer, init_shaders, CursorMode, GlMultiRenderer}; use super::render::{element::AsGlowRenderer, init_shaders, CursorMode, GlMultiRenderer};
// for now we assume we need at least 3ms // for now we assume we need at least 3ms
const MIN_RENDER_TIME: Duration = Duration::from_millis(3); const MIN_DISPLAY_TIME: Duration = Duration::from_millis(3);
#[derive(Debug)] #[derive(Debug)]
pub struct KmsState { pub struct KmsState {
@ -526,7 +526,7 @@ impl State {
|| { || {
( (
surface.output.clone(), surface.output.clone(),
surface.fps.avg_rendertime(5), surface.fps.avg_time_to_display(5),
) )
}, },
) )
@ -544,7 +544,7 @@ impl State {
None None
}; };
if let Some((output, avg_rendertime)) = rescheduled { if let Some((output, avg_time)) = rescheduled {
let mut scheduled_sessions = let mut scheduled_sessions =
state.workspace_session_for_output(&output); state.workspace_session_for_output(&output);
let mut output_sessions = output.pending_buffers().peekable(); let mut output_sessions = output.pending_buffers().peekable();
@ -554,8 +554,7 @@ impl State {
.extend(output_sessions); .extend(output_sessions);
} }
let estimated_rendertime = let estimated_rendertime = std::cmp::max(avg_time, MIN_DISPLAY_TIME);
std::cmp::max(avg_rendertime, MIN_RENDER_TIME);
if let Err(err) = state.backend.kms().schedule_render( if let Err(err) = state.backend.kms().schedule_render(
&state.common.event_loop_handle, &state.common.event_loop_handle,
&output, &output,
@ -1241,7 +1240,10 @@ impl Surface {
} }
} }
match compositor.queue_frame(feedback) { match compositor.queue_frame(feedback) {
Ok(()) | Err(FrameError::EmptyFrame) => {} Ok(()) => {
self.pending = true;
}
Err(FrameError::EmptyFrame) => {}
Err(err) => { Err(err) => {
return Err(err).with_context(|| "Failed to submit result for display") return Err(err).with_context(|| "Failed to submit result for display")
} }
@ -1629,7 +1631,7 @@ impl KmsState {
} }
return Ok(()); return Ok(());
} }
if !surface.scheduled { if !surface.scheduled && !surface.pending {
let device = *device; let device = *device;
let crtc = *crtc; let crtc = *crtc;
if let Some(token) = surface.render_timer_token.take() { if let Some(token) = surface.render_timer_token.take() {
@ -1689,7 +1691,6 @@ impl KmsState {
Ok(_) => { Ok(_) => {
trace!(?crtc, "Frame pending"); trace!(?crtc, "Frame pending");
surface.dirty = false; surface.dirty = false;
surface.pending = true;
surface.scheduled = false; surface.scheduled = false;
surface.render_timer_token = None; surface.render_timer_token = None;
return TimeoutAction::Drop; return TimeoutAction::Drop;
@ -1723,7 +1724,9 @@ impl KmsState {
} }
}); });
} }
surface.dirty = true; if surface.pending {
surface.dirty = true;
}
} }
} }
Ok(()) Ok(())

View file

@ -905,7 +905,7 @@ pub struct Frame {
} }
impl Frame { impl Frame {
fn render_time(&self) -> Duration { fn _render_time(&self) -> Duration {
self.duration_elements + self.duration_render self.duration_elements + self.duration_render
} }
@ -1028,11 +1028,12 @@ impl Fps {
self.frames.iter().map(|f| f.frame_time()).sum::<Duration>() / (self.frames.len() as u32) self.frames.iter().map(|f| f.frame_time()).sum::<Duration>() / (self.frames.len() as u32)
} }
pub fn avg_rendertime(&self, window: usize) -> Duration { pub fn avg_time_to_display(&self, window: usize) -> Duration {
self.frames self.frames
.iter() .iter()
.rev()
.take(window) .take(window)
.map(|f| f.render_time()) .map(|f| f.time_to_display())
.sum::<Duration>() .sum::<Duration>()
/ window as u32 / window as u32
} }