From 35785dbf01d92a113bbdcac13881e57993447720 Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Thu, 14 Nov 2024 20:51:23 -0400 Subject: [PATCH] Redraw continuously instead of busy-waiting at 100% CPU Previously, Pteropus would only redraw when the window was resized, but it would continuously poll for events, keeping a CPU core at 100% even when not doing anything. It now automatically queues a new RedrawRequested event after each draw finishes. The view() call will also limit the frame rate to the video refresh rate and block when there are more than three frames queued up, so we're not busywaiting any more. --- src/app/mod.rs | 1 + src/native/mod.rs | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index e0587e7..3804172 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -106,6 +106,7 @@ impl MvuApp for App { let mut config = surface .get_default_config(&adapter, size.width, size.height) .unwrap(); + config.present_mode = wgpu::PresentMode::AutoVsync; config.view_formats.push(config.format); surface.configure(&device, &config); diff --git a/src/native/mod.rs b/src/native/mod.rs index 0ab9759..f19f9d2 100644 --- a/src/native/mod.rs +++ b/src/native/mod.rs @@ -45,6 +45,10 @@ where block_on(self.app.init(&instance, surface, Size2i { width, height })); } + + // TODO: The idea with these `block_on()` calls is that eventually I'll + // write an async executor that runs on top of the winit even loop and then + // this stuff can be properly async. fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) { match event { WindowEvent::Resized(new_size) => block_on(self.app.resize(Size2i { @@ -55,7 +59,10 @@ where println!("The close button was pressed; stopping"); event_loop.exit(); } - WindowEvent::RedrawRequested => block_on(self.app.view(self.model.clone())).unwrap(), + WindowEvent::RedrawRequested => { + block_on(self.app.view(self.model.clone())).unwrap(); + self.window.as_ref().unwrap().request_redraw(); + }, WindowEvent::DroppedFile(file_path) => { self.model = block_on( self.app