From db27fa483d0a56d4bb650235d4116d52b00f35de Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 14 Feb 2024 17:46:33 +0100 Subject: [PATCH] kms: Optimize frame scheduling --- src/backend/kms/mod.rs | 21 ++++++++++++--------- src/state.rs | 7 ++++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index 2e14bf61..0342bb21 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -91,7 +91,7 @@ use socket::*; use super::render::{element::AsGlowRenderer, init_shaders, CursorMode, GlMultiRenderer}; // 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)] pub struct KmsState { @@ -526,7 +526,7 @@ impl State { || { ( surface.output.clone(), - surface.fps.avg_rendertime(5), + surface.fps.avg_time_to_display(5), ) }, ) @@ -544,7 +544,7 @@ impl State { None }; - if let Some((output, avg_rendertime)) = rescheduled { + if let Some((output, avg_time)) = rescheduled { let mut scheduled_sessions = state.workspace_session_for_output(&output); let mut output_sessions = output.pending_buffers().peekable(); @@ -554,8 +554,7 @@ impl State { .extend(output_sessions); } - let estimated_rendertime = - std::cmp::max(avg_rendertime, MIN_RENDER_TIME); + let estimated_rendertime = std::cmp::max(avg_time, MIN_DISPLAY_TIME); if let Err(err) = state.backend.kms().schedule_render( &state.common.event_loop_handle, &output, @@ -1241,7 +1240,10 @@ impl Surface { } } match compositor.queue_frame(feedback) { - Ok(()) | Err(FrameError::EmptyFrame) => {} + Ok(()) => { + self.pending = true; + } + Err(FrameError::EmptyFrame) => {} Err(err) => { return Err(err).with_context(|| "Failed to submit result for display") } @@ -1629,7 +1631,7 @@ impl KmsState { } return Ok(()); } - if !surface.scheduled { + if !surface.scheduled && !surface.pending { let device = *device; let crtc = *crtc; if let Some(token) = surface.render_timer_token.take() { @@ -1689,7 +1691,6 @@ impl KmsState { Ok(_) => { trace!(?crtc, "Frame pending"); surface.dirty = false; - surface.pending = true; surface.scheduled = false; surface.render_timer_token = None; return TimeoutAction::Drop; @@ -1723,7 +1724,9 @@ impl KmsState { } }); } - surface.dirty = true; + if surface.pending { + surface.dirty = true; + } } } Ok(()) diff --git a/src/state.rs b/src/state.rs index 1d507403..4947f5c9 100644 --- a/src/state.rs +++ b/src/state.rs @@ -905,7 +905,7 @@ pub struct Frame { } impl Frame { - fn render_time(&self) -> Duration { + fn _render_time(&self) -> Duration { self.duration_elements + self.duration_render } @@ -1028,11 +1028,12 @@ impl Fps { self.frames.iter().map(|f| f.frame_time()).sum::() / (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 .iter() + .rev() .take(window) - .map(|f| f.render_time()) + .map(|f| f.time_to_display()) .sum::() / window as u32 }