Deduplicate window resize events to remove redudant resizing of the swap chain and other render targets and to fix issues where resizing quickly can cause self reinforcing delays in tick completion

This commit is contained in:
Imbris 2021-09-29 03:56:37 -04:00
parent 44e526fbcc
commit 70f9134c3c
2 changed files with 56 additions and 24 deletions

View File

@ -39,18 +39,27 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop) {
}
}
// Get events for the ui.
if let Some(event) = ui::Event::try_from(&event, global_state.window.window()) {
global_state.window.send_event(Event::Ui(event));
}
// iced ui events
// TODO: no clone
if let winit::event::Event::WindowEvent { event, .. } = &event {
let window = &mut global_state.window;
if let Some(event) =
ui::ice::window_event(event, window.scale_factor(), window.modifiers())
{
window.send_event(Event::IcedUi(event));
// Don't pass resize events to the ui, `Window` is responsible for:
// - deduplicating them
// - generating resize events for the ui
// - ensuring consistent sizes are passed to the ui and to the renderer
if !matches!(&event, winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::Resized(_),
..
}) {
// Get events for the ui.
if let Some(event) = ui::Event::try_from(&event, global_state.window.window()) {
global_state.window.send_event(Event::Ui(event));
}
// iced ui events
// TODO: no clone
if let winit::event::Event::WindowEvent { event, .. } = &event {
let window = &mut global_state.window;
if let Some(event) =
ui::ice::window_event(event, window.scale_factor(), window.modifiers())
{
window.send_event(Event::IcedUi(event));
}
}
}

View File

@ -378,6 +378,9 @@ pub struct Window {
pub mouse_y_inversion: bool,
fullscreen: FullScreenSettings,
modifiers: winit::event::ModifiersState,
// Track if at least one Resized event has occured since the last `fetch_events` call
// Used for deduplication of resizes.
resized: bool,
scale_factor: f64,
needs_refresh_resize: bool,
keypress_map: HashMap<GameInput, winit::event::ElementState>,
@ -479,6 +482,7 @@ impl Window {
fullscreen: FullScreenSettings::default(),
modifiers: Default::default(),
scale_factor,
resized: false,
needs_refresh_resize: false,
keypress_map,
remapping_keybindings: None,
@ -539,6 +543,36 @@ impl Window {
self.needs_refresh_resize = false;
}
// Handle deduplicated resizing that occured
if self.resized {
self.resized = false;
// We don't use the size provided by the event because more resize events could
// have happened since, making the value outdated, so we must query directly
// from the window to prevent errors
let physical = self.window.inner_size();
self.renderer
.on_resize(Vec2::new(physical.width, physical.height));
// TODO: update users of this event with the fact that it is now the physical
// size
let winit::dpi::PhysicalSize { width, height } = physical;
self.events
.push(Event::Resize(Vec2::new(width as u32, height as u32)));
// Emit event for the UI
let logical_size = Vec2::from(Into::<(f64, f64)>::into(
physical.to_logical::<f64>(self.window.scale_factor()),
));
self.events
.push(Event::Ui(ui::Event::new_resize(logical_size)));
self.events.push(Event::IcedUi(iced::Event::Window(
iced::window::Event::Resized {
width: logical_size.x as u32,
height: logical_size.y as u32,
},
)));
}
// Receive any messages sent through the message channel
for message in self.message_receiver.try_iter() {
self.events.push(Event::ScreenshotMessage(message))
@ -788,18 +822,7 @@ impl Window {
match event {
WindowEvent::CloseRequested => self.events.push(Event::Close),
WindowEvent::Resized(_) => {
// We don't use the event provided size because since this event
// more could have happened making the value wrong so we query
// directly from the window, this prevents some errors
let physical = self.window.inner_size();
self.renderer
.on_resize(Vec2::new(physical.width, physical.height));
// TODO: update users of this event with the fact that it is now the physical
// size
let winit::dpi::PhysicalSize { width, height } = physical;
self.events
.push(Event::Resize(Vec2::new(width as u32, height as u32)));
self.resized = true;
},
WindowEvent::ScaleFactorChanged { scale_factor, .. } => {
// TODO: is window resized event emitted? or do we need to handle that here?