Commit 8f974106aae3
tarball1 file changed+28-2
@@ -520,10 +520,36 @@ fn schedule(state: &mut State, crtc: crtc::Handle) {
520520
surface.scheduled = token.ok();521521
}522522
523
+/// An animation whose frame had nothing to show, like one hidden behind a524
+/// fullscreen window, has no flip to wait for. Under VRR scheduling again525
+/// would draw at once and recurse until the stack overflowed, so the next526
+/// try waits a refresh.523527
fn draw(state: &mut State, crtc: crtc::Handle, target: u64) {524
- if render_surface(state, crtc, target) {525
- schedule(state, crtc);528
+ if !render_surface(state, crtc, target) {529
+ return;530
+ }531
+ let Some(drm) = state.backend.drm_mut() else {532
+ return;533
+ };534
+ let Some(surface) = drm.surfaces.get_mut(&crtc) else {535
+ return;536
+ };537
+ if surface.scheduled.is_some() {538
+ return;526539
}540
+ let wait = Timer::from_duration(Duration::from_nanos(surface.refresh_ns.max(1_000_000)));541
+ let token = drm.handle.insert_source(wait, move |_, _, state| {542
+ if let Some(s) = state543
+ .backend544
+ .drm_mut()545
+ .and_then(|d| d.surfaces.get_mut(&crtc))546
+ {547
+ s.scheduled = None;548
+ }549
+ schedule(state, crtc);550
+ TimeoutAction::Drop551
+ });552
+ surface.scheduled = token.ok();527553
}528554
529555
/// Renders every output that has something new and no frame in flight.