Skip to content

Commit

Permalink
Make the refresh rate adjustable
Browse files Browse the repository at this point in the history
  • Loading branch information
fredizzimo committed Jun 27, 2023
1 parent e4fc5e1 commit 33a863d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
42 changes: 34 additions & 8 deletions src/renderer/vsync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,43 @@ use std::{
Arc, Condvar, Mutex,
},
thread::{spawn, JoinHandle},
time::Instant,
};
use winapi::um::dwmapi::DwmFlush;

use simple_moving_average::{NoSumSMA, SMA};

pub struct VSync {
should_exit: Arc<AtomicBool>,
vsync_thread: Option<JoinHandle<()>>,
vsync_count: Arc<(Mutex<usize>, Condvar)>,
vsync_count: Arc<(Mutex<(usize, f64)>, Condvar)>,
last_vsync: usize,
dt: f64,
interval: usize,
}

impl VSync {
pub fn new() -> Self {
let should_exit = Arc::new(AtomicBool::new(false));
let should_exit2 = should_exit.clone();
let vsync_count = Arc::new((Mutex::new(0), Condvar::new()));
let vsync_count = Arc::new((Mutex::new((0, 0.0)), Condvar::new()));
let vsync_count2 = vsync_count.clone();

let vsync_thread = Some(spawn(move || {
let mut frame_dt_avg = NoSumSMA::<f64, f64, 10>::new();
let mut prev_frame_start = Instant::now();

let (lock, cvar) = &*vsync_count2;
while should_exit2.load(Ordering::SeqCst) == false {
while !should_exit2.load(Ordering::SeqCst) {
unsafe {
tracy_zone!("VSyncThread");
DwmFlush();
frame_dt_avg.add_sample(prev_frame_start.elapsed().as_secs_f64());
prev_frame_start = Instant::now();
{
let mut count = lock.lock().unwrap();
*count += 1;
let mut count_dt = lock.lock().unwrap();
count_dt.0 += 1;
count_dt.1 = frame_dt_avg.get_average();
cvar.notify_one();
}
}
Expand All @@ -42,15 +53,30 @@ impl VSync {
vsync_thread,
vsync_count,
last_vsync: 0,
dt: 0.0,
interval: 1,
}
}

pub fn wait_for_vsync(&mut self) {
let (lock, cvar) = &*self.vsync_count;
let count = cvar
.wait_while(lock.lock().unwrap(), |count| *count < self.last_vsync + 2)
let count_dt = cvar
.wait_while(lock.lock().unwrap(), |count_dt| {
count_dt.0 < self.last_vsync + self.interval
})
.unwrap();
self.last_vsync = *count;
self.last_vsync = count_dt.0;
self.dt = count_dt.1;
}

pub fn set_refresh_rate(&mut self, desired_rate: u64) {
if self.dt > 0.0 {
let rate = 1.0 / self.dt;
let desired_rate = (desired_rate).max(30) as f64;
self.interval = (rate / desired_rate).round().max(1.0) as usize;
} else {
self.interval = 1;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ pub fn create_window() {
last_dt
}
.min(1.0);
vsync.set_refresh_rate(SETTINGS.get::<WindowSettings>().refresh_rate);
should_render |= window_wrapper.prepare_frame();
let num_steps = (dt / max_animation_dt).ceil();
let step = dt / num_steps;
Expand Down

0 comments on commit 33a863d

Please sign in to comment.