kms: Optimize frame scheduling
This commit is contained in:
parent
96518a9f29
commit
db27fa483d
2 changed files with 16 additions and 12 deletions
|
|
@ -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(())
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue