Optimizations for Winit Examples. (#686)
This optimizes examples by using `ControlFlow::Wait` instead of
`ControlFlow::Poll`. This fix was found by Micah Johnston, and this PR
implements it in both "simple" and "with_winit" examples.
- "simple" now runs at 0.1-0.2% CPU usage.
- "with_winit" now runs at 1.0-1.8%.
[You can check more info about it
here](https://xi.zulipchat.com/#narrow/stream/147921-general/topic/I've.20made.20a.20Vello.20game.20engine.20to.20prove.20that.20i.20was.20wrong.2E/near/468637207)
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
diff --git a/examples/simple/src/main.rs b/examples/simple/src/main.rs
index bbf7216..d08e7d2 100644
--- a/examples/simple/src/main.rs
+++ b/examples/simple/src/main.rs
@@ -11,7 +11,7 @@
use winit::application::ApplicationHandler;
use winit::dpi::LogicalSize;
use winit::event::*;
-use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
+use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::window::Window;
use vello::wgpu;
@@ -74,15 +74,12 @@
// Save the Window and Surface to a state variable
self.state = RenderState::Active(ActiveRenderState { window, surface });
-
- event_loop.set_control_flow(ControlFlow::Poll);
}
- fn suspended(&mut self, event_loop: &ActiveEventLoop) {
+ fn suspended(&mut self, _event_loop: &ActiveEventLoop) {
if let RenderState::Active(state) = &self.state {
self.state = RenderState::Suspended(Some(state.window.clone()));
}
- event_loop.set_control_flow(ControlFlow::Wait);
}
fn window_event(
@@ -109,7 +106,6 @@
WindowEvent::Resized(size) => {
self.context
.resize_surface(&mut render_state.surface, size.width, size.height);
- render_state.window.request_redraw();
}
// This is where all the rendering happens
diff --git a/examples/with_winit/src/lib.rs b/examples/with_winit/src/lib.rs
index 0e86781..576452d 100644
--- a/examples/with_winit/src/lib.rs
+++ b/examples/with_winit/src/lib.rs
@@ -14,7 +14,6 @@
use web_time::Instant;
use winit::application::ApplicationHandler;
use winit::event::*;
-use winit::event_loop::ControlFlow;
use winit::keyboard::*;
#[cfg(all(feature = "wgpu-profiler", not(target_arch = "wasm32")))]
@@ -226,7 +225,6 @@
});
Some(render_state)
};
- event_loop.set_control_flow(ControlFlow::Poll);
}
fn window_event(
@@ -443,6 +441,8 @@
let _rendering_span = tracing::trace_span!("Actioning Requested Redraw").entered();
let encoding_span = tracing::trace_span!("Encoding scene").entered();
+ render_state.window.request_redraw();
+
let Some(RenderState { surface, window }) = &self.state else {
return;
};
@@ -633,14 +633,13 @@
}
}
- fn suspended(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
+ fn suspended(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) {
log::info!("Suspending");
#[cfg(not(target_arch = "wasm32"))]
// When we suspend, we need to remove the `wgpu` Surface
if let Some(render_state) = self.state.take() {
self.cached_window = Some(render_state.window);
}
- event_loop.set_control_flow(ControlFlow::Wait);
}
}