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};
|
||||
// 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(())
|
||||
|
|
|
|||
|
|
@ -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::<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
|
||||
.iter()
|
||||
.rev()
|
||||
.take(window)
|
||||
.map(|f| f.render_time())
|
||||
.map(|f| f.time_to_display())
|
||||
.sum::<Duration>()
|
||||
/ window as u32
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue