kms: Don't reschedule for high input rates
This commit is contained in:
parent
b2414a7972
commit
486266f7bb
1 changed files with 19 additions and 6 deletions
|
|
@ -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| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue