From edbf10212b377485cbde3eadac75d2cf8894163d Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Fri, 6 Oct 2023 20:23:59 -0600 Subject: [PATCH] rework frame limiter --- src/device.rs | 1 + src/device/vi.rs | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/device.rs b/src/device.rs index df12329b..9ba82247 100644 --- a/src/device.rs +++ b/src/device.rs @@ -262,6 +262,7 @@ impl Device { clock: 0, field: 0, delay: 0, + holdover: std::time::Duration::from_secs(0), count_per_scanline: 0, last_vi_time: std::time::Instant::now(), vi_period: std::time::Duration::from_secs_f64(0.0), diff --git a/src/device/vi.rs b/src/device/vi.rs index f87b1832..5f8864a5 100644 --- a/src/device/vi.rs +++ b/src/device/vi.rs @@ -22,6 +22,7 @@ pub struct Vi { pub clock: u64, pub delay: u64, pub field: u32, + pub holdover: std::time::Duration, pub count_per_scanline: u64, pub last_vi_time: std::time::Instant, pub vi_period: std::time::Duration, @@ -123,9 +124,22 @@ pub fn vertical_interrupt_event(device: &mut device::Device) { */ let elapsed = device.vi.last_vi_time.elapsed(); - if elapsed < device.vi.vi_period { - let diff = device.vi.vi_period - elapsed; - std::thread::sleep(diff); + if elapsed <= device.vi.vi_period { + let sleep_time = device.vi.vi_period - elapsed; + let remaining_holdover_space = device.vi.vi_period - device.vi.holdover; // holdover can't exceed the vi period + if sleep_time <= remaining_holdover_space { + device.vi.holdover += sleep_time; // donate all time to the holdover + } else { + device.vi.holdover += remaining_holdover_space; // max out holdover + std::thread::sleep(sleep_time - remaining_holdover_space); // sleep the rest of the time + } + } else { + let over_time = elapsed - device.vi.vi_period; // this is how much we overshot the vi period + if over_time <= device.vi.holdover { + device.vi.holdover -= over_time; // consume some holdover + } else { + device.vi.holdover -= device.vi.holdover; // consume all holdover + } } device.vi.last_vi_time = std::time::Instant::now();