kms: Don't reschedule for high input rates

This commit is contained in:
Victoria Brekenfeld 2023-03-23 11:29:51 +01:00
parent b2414a7972
commit 486266f7bb

View file

@ -114,6 +114,7 @@ pub struct Surface {
output: Output, output: Output,
refresh_rate: u32, refresh_rate: u32,
vrr: bool, vrr: bool,
scheduled: bool,
pending: bool, pending: bool,
dirty: bool, dirty: bool,
render_timer_token: Option<RegistrationToken>, render_timer_token: Option<RegistrationToken>,
@ -284,6 +285,7 @@ pub fn init_backend(
.values_mut() .values_mut()
.flat_map(|d| d.surfaces.values_mut()) .flat_map(|d| d.surfaces.values_mut())
{ {
surface.scheduled = false;
surface.pending = false; surface.pending = false;
} }
for output in data.state.common.shell.outputs() { for output in data.state.common.shell.outputs() {
@ -314,6 +316,10 @@ pub fn init_backend(
device.drm.pause(); device.drm.pause();
for surface in device.surfaces.values_mut() { for surface in device.surfaces.values_mut() {
surface.surface = None; surface.surface = None;
if let Some(token) = surface.render_timer_token.take() {
data.state.common.event_loop_handle.remove(token);
}
surface.scheduled = false;
} }
} }
} }
@ -501,11 +507,12 @@ impl State {
.extend(output_sessions); .extend(output_sessions);
} }
let repaint_delay = std::cmp::max(avg_rendertime, MIN_RENDER_TIME); let estimated_rendertime =
std::cmp::max(avg_rendertime, MIN_RENDER_TIME);
if let Err(err) = data.state.backend.kms().schedule_render( if let Err(err) = data.state.backend.kms().schedule_render(
&data.state.common.event_loop_handle, &data.state.common.event_loop_handle,
&output, &output,
Some(repaint_delay), Some(estimated_rendertime),
scheduled_sessions, scheduled_sessions,
) { ) {
warn!(?err, "Failed to schedule render."); warn!(?err, "Failed to schedule render.");
@ -877,6 +884,7 @@ impl Device {
connector: conn, connector: conn,
vrr, vrr,
refresh_rate, refresh_rate,
scheduled: false,
pending: false, pending: false,
dirty: false, dirty: false,
render_timer_token: None, render_timer_token: None,
@ -1303,7 +1311,7 @@ impl KmsState {
&mut self, &mut self,
loop_handle: &LoopHandle<'_, Data>, loop_handle: &LoopHandle<'_, Data>,
output: &Output, output: &Output,
delay: Option<Duration>, estimated_rendertime: Option<Duration>,
mut screencopy_sessions: Option<Vec<(ScreencopySession, BufferParams)>>, mut screencopy_sessions: Option<Vec<(ScreencopySession, BufferParams)>>,
) -> Result<(), InsertError<Timer>> { ) -> Result<(), InsertError<Timer>> {
if let Some((device, crtc, surface)) = self if let Some((device, crtc, surface)) = self
@ -1322,17 +1330,20 @@ impl KmsState {
} }
return Ok(()); return Ok(());
} }
if !surface.pending { if !surface.scheduled {
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() {
loop_handle.remove(token); loop_handle.remove(token);
} }
surface.render_timer_token = Some(loop_handle.insert_source( surface.render_timer_token = Some(loop_handle.insert_source(
if surface.vrr || delay.is_none() { if surface.vrr || estimated_rendertime.is_none() {
Timer::immediate() Timer::immediate()
} else { } else {
Timer::from_duration(delay.unwrap()) Timer::from_duration(
Duration::from_secs_f64(1000.0 / surface.refresh_rate as f64)
.saturating_sub(estimated_rendertime.unwrap()),
)
}, },
move |_time, _, data| { move |_time, _, data| {
let backend = data.state.backend.kms(); let backend = data.state.backend.kms();
@ -1382,6 +1393,7 @@ impl KmsState {
Ok(_) => { Ok(_) => {
surface.dirty = false; surface.dirty = false;
surface.pending = true; surface.pending = true;
surface.scheduled = false;
return TimeoutAction::Drop; return TimeoutAction::Drop;
} }
Err(err) => { Err(err) => {
@ -1403,6 +1415,7 @@ impl KmsState {
TimeoutAction::Drop TimeoutAction::Drop
}, },
)?); )?);
surface.scheduled = true;
} else { } else {
if let Some(sessions) = screencopy_sessions { if let Some(sessions) = screencopy_sessions {
loop_handle.insert_idle(|data| { loop_handle.insert_idle(|data| {