Skip to content

Commit

Permalink
Implement request redraw
Browse files Browse the repository at this point in the history
  • Loading branch information
fredizzimo committed Dec 18, 2023
1 parent 00cf621 commit 812c126
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
11 changes: 8 additions & 3 deletions src/renderer/vsync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,14 @@ impl VSync {
}
}

pub fn request_redraw(&self, context: &WindowedContext) {
if let VSync::WinitThrottling(..) = self {
context.window().request_redraw();
pub fn request_redraw(&mut self, context: &WindowedContext) {
match self {
VSync::WinitThrottling(..) => context.window().request_redraw(),
#[cfg(target_os = "windows")]
VSync::Windows(vsync) => vsync.request_redraw(),
#[cfg(target_os = "macos")]
VSync::Macos(vsync) => vsync.request_redraw(),
_ => {}
}
}
}
17 changes: 16 additions & 1 deletion src/renderer/vsync/vsync_macos.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use log::{error, trace, warn};
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};

use winit::event_loop::EventLoopProxy;

Expand All @@ -10,27 +14,33 @@ use super::macos_display_link::{

struct VSyncMacosDisplayLinkUserData {
proxy: EventLoopProxy<UserEvent>,
redraw_requested: Arc<AtomicBool>,
}

fn vsync_macos_display_link_callback(
_args: &mut MacosDisplayLinkCallbackArgs,
user_data: &mut VSyncMacosDisplayLinkUserData,
) {
let _ = user_data.proxy.send_event(UserEvent::RedrawRequested);
if user_data.redraw_requested.swap(false, Ordering::Relaxed) {
let _ = user_data.proxy.send_event(UserEvent::RedrawRequested);
}
}

pub struct VSyncMacos {
old_display: core_video::CGDirectDisplayID,
display_link: Option<MacosDisplayLink<VSyncMacosDisplayLinkUserData>>,
proxy: EventLoopProxy<UserEvent>,
redraw_requested: Arc<AtomicBool>,
}

impl VSyncMacos {
pub fn new(context: &WindowedContext, proxy: EventLoopProxy<UserEvent>) -> VSyncMacos {
let redraw_requested = AtomicBool::new(false).into();
let mut vsync = VSyncMacos {
old_display: 0,
display_link: None,
proxy,
redraw_requested,
};

vsync.create_display_link(context);
Expand All @@ -46,6 +56,7 @@ impl VSyncMacos {
vsync_macos_display_link_callback,
VSyncMacosDisplayLinkUserData {
proxy: self.proxy.clone(),
redraw_requested: Arc::clone(&self.redraw_requested),
},
) {
Ok(display_link) => {
Expand Down Expand Up @@ -75,6 +86,10 @@ impl VSyncMacos {

pub fn wait_for_vsync(&mut self) {}

pub fn request_redraw(&mut self) {
self.redraw_requested.store(true, Ordering::Relaxed);
}

pub fn update(&mut self, context: &WindowedContext) {
let new_display = get_display_id_of_window(context.window());
if new_display != self.old_display {
Expand Down
15 changes: 13 additions & 2 deletions src/renderer/vsync/vsync_win.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::{
pub struct VSyncWin {
should_exit: Arc<AtomicBool>,
vsync_thread: Option<JoinHandle<()>>,
redraw_requested: Arc<AtomicBool>,
}

/// Calculates the time until the vblank, taking into account that the vblank is cyclic, so this
Expand All @@ -48,13 +49,15 @@ impl VSyncWin {
// Everything else is very jerky
pub fn new(proxy: EventLoopProxy<UserEvent>) -> Self {
let should_exit = Arc::new(AtomicBool::new(false));
let redraw_requested = Arc::new(AtomicBool::new(false));

// When using OpenGL on Windows in windowed mode, swap_buffers does not seem to be
// synchronized with the Desktop Window Manager. So work around that by manually waiting
// for the middle of the vblank. Experimentally that seems to be optimal with the least
// amount of stutter.
let vsync_thread = {
let should_exit = should_exit.clone();
let should_exit = Arc::clone(&should_exit);
let redraw_requested = Arc::clone(&redraw_requested);
Some(spawn(move || {
let performance_frequency = unsafe {
let mut performance_frequency: LARGE_INTEGER = std::mem::zeroed();
Expand Down Expand Up @@ -88,18 +91,26 @@ impl VSyncWin {
};
tracy_plot!("Vblank_delay", _vblank_delay);
tracy_plot!("sleep_time", _sleep_time);
let _ = proxy.send_event(UserEvent::RedrawRequested);

if redraw_requested.swap(false, Ordering::Relaxed) {
let _ = proxy.send_event(UserEvent::RedrawRequested);
}
}
}))
};

Self {
should_exit,
vsync_thread,
redraw_requested,
}
}

pub fn wait_for_vsync(&mut self) {}

pub fn request_redraw(&mut self) {
self.redraw_requested.store(true, Ordering::Relaxed);
}
}

impl Drop for VSyncWin {
Expand Down
6 changes: 2 additions & 4 deletions src/window/update_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,8 @@ impl UpdateLoop {
..
})
| Ok(Event::UserEvent(UserEvent::RedrawRequested)) => {
if self.pending_render {
tracy_zone!("render (redraw requested)");
self.render(window_wrapper);
}
tracy_zone!("render (redraw requested)");
self.render(window_wrapper);
}
_ => {}
}
Expand Down

0 comments on commit 812c126

Please sign in to comment.