Commit 1a9eee4b3604
tarball1 file changed+18-4
@@ -78,6 +78,9 @@ struct Surface {
7878
refresh_ns: u64,7979
/// The pending render, timed to start just in time for `target_ns`.8080
scheduled: Option<RegistrationToken>,81
+ /// `scheduled` only waits out a cap or a retry, so fresh content may82
+ /// cancel it and draw at once.83
+ preemptible: bool,8184
/// The vblank the frame being drawn or queued is meant for.8285
target_ns: Option<u64>,8386
budget: crate::pacing::Budget,@@ -392,6 +395,7 @@ fn connect(state: &mut State, connector: connector::Info, crtc: crtc::Handle) {
392395
redraw: true,393396
last_vblank_ns: None,394397
scheduled: None,398
+ preemptible: false,395399
target_ns: None,396400
budget: crate::pacing::Budget::new(),397401
presented: 0,@@ -619,7 +623,7 @@ fn schedule(state: &mut State, crtc: crtc::Handle) {
619623
return;620624
}621625
let wait = Duration::from_nanos(CURSOR_FRAME_NS - since_flip);622
- arm(&drm.handle, surface, crtc, wait, move |state| {626
+ arm(&drm.handle, surface, crtc, wait, true, move |state| {623627
draw(state, crtc, now_ns());624628
});625629
return;@@ -630,7 +634,7 @@ fn schedule(state: &mut State, crtc: crtc::Handle) {
630634
};631635
surface.target_ns = Some(vblank);632636
let wait = Duration::from_nanos(start.saturating_sub(now));633
- arm(&drm.handle, surface, crtc, wait, move |state| {637
+ arm(&drm.handle, surface, crtc, wait, false, move |state| {634638
let target = state635639
.backend636640
.drm()@@ -647,6 +651,7 @@ fn arm(
647651
surface: &mut Surface,648652
crtc: crtc::Handle,649653
after: Duration,654
+ preemptible: bool,650655
mut fire: impl FnMut(&mut State) + 'static,651656
) {652657
let token = handle.insert_source(Timer::from_duration(after), move |_, _, state| {@@ -661,7 +666,10 @@ fn arm(
661666
TimeoutAction::Drop662667
});663668
match token {664
- Ok(token) => surface.scheduled = Some(token),669
+ Ok(token) => {670
+ surface.scheduled = Some(token);671
+ surface.preemptible = preemptible;672
+ }665673
Err(e) => tracing::warn!(666674
output = surface.output.name(),667675
"could not arm a render timer: {e}"@@ -687,7 +695,7 @@ fn draw(state: &mut State, crtc: crtc::Handle, target: u64) {
687695
return;688696
}689697
let wait = Duration::from_nanos(surface.refresh_ns.max(1_000_000));690
- arm(&drm.handle, surface, crtc, wait, move |state| {698
+ arm(&drm.handle, surface, crtc, wait, true, move |state| {691699
schedule(state, crtc);692700
});693701
}@@ -702,6 +710,12 @@ pub fn render(state: &mut State) {
702710
for s in drm.surfaces.values_mut() {703711
s.redraw |= all;704712
s.cursor_redraw |= cursor;713
+ if all714
+ && s.preemptible715
+ && let Some(token) = s.scheduled.take()716
+ {717
+ drm.handle.remove(token);718
+ }705719
}706720
let ready: Vec<crtc::Handle> = drm707721
.surfaces