1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-31 22:00:03 -04:00

Fix egui-wgpu performance regression (#3580)

Introduced in the recent multi-viewports work, we accidentally recreated
the wgpu surfaces every frame. This is now fixed.

I found this while improving the profiling of `eframe`
This commit is contained in:
Emil Ernerfeldt
2023-11-19 21:14:13 +01:00
committed by GitHub
parent 960b01b67a
commit 30ee478caf
14 changed files with 372 additions and 279 deletions

View File

@@ -174,14 +174,14 @@ impl State {
}
/// The current input state.
/// This is changed by [`Self::on_event`] and cleared by [`Self::take_egui_input`].
/// This is changed by [`Self::on_window_event`] and cleared by [`Self::take_egui_input`].
#[inline]
pub fn egui_input(&self) -> &egui::RawInput {
&self.egui_input
}
/// The current input state.
/// This is changed by [`Self::on_event`] and cleared by [`Self::take_egui_input`].
/// This is changed by [`Self::on_window_event`] and cleared by [`Self::take_egui_input`].
#[inline]
pub fn egui_input_mut(&mut self) -> &mut egui::RawInput {
&mut self.egui_input
@@ -233,13 +233,13 @@ impl State {
/// Call this when there is a new event.
///
/// The result can be found in [`Self::egui_input`] and be extracted with [`Self::take_egui_input`].
pub fn on_event(
pub fn on_window_event(
&mut self,
egui_ctx: &egui::Context,
event: &winit::event::WindowEvent<'_>,
viewport_id: ViewportId,
) -> EventResponse {
crate::profile_function!();
crate::profile_function!(short_window_event_description(event));
use winit::event::WindowEvent;
match event {
@@ -822,16 +822,14 @@ fn update_viewport_info(viewport_info: &mut ViewportInfo, window: &Window, pixel
let inner_rect = inner_rect_px.map(|r| r / pixels_per_point);
let outer_rect = outer_rect_px.map(|r| r / pixels_per_point);
let monitor = window.current_monitor().is_some();
let monitor_size = if monitor {
let size = window
.current_monitor()
.unwrap()
.size()
.to_logical::<f32>(pixels_per_point.into());
Some(egui::vec2(size.width, size.height))
} else {
None
let monitor_size = {
crate::profile_scope!("monitor_size");
if let Some(monitor) = window.current_monitor() {
let size = monitor.size().to_logical::<f32>(pixels_per_point.into());
Some(egui::vec2(size.width, size.height))
} else {
None
}
};
viewport_info.title = Some(window.title());
@@ -1339,6 +1337,76 @@ pub fn apply_viewport_builder_to_new_window(window: &Window, builder: &ViewportB
// ---------------------------------------------------------------------------
/// Short and fast description of an event.
/// Useful for logging and profiling.
pub fn short_generic_event_description<T>(event: &winit::event::Event<'_, T>) -> &'static str {
use winit::event::{DeviceEvent, Event, StartCause};
match event {
Event::Suspended => "Event::Suspended",
Event::Resumed => "Event::Resumed",
Event::MainEventsCleared => "Event::MainEventsCleared",
Event::RedrawRequested(_) => "Event::RedrawRequested",
Event::RedrawEventsCleared => "Event::RedrawEventsCleared",
Event::LoopDestroyed => "Event::LoopDestroyed",
Event::UserEvent(_) => "UserEvent",
Event::DeviceEvent { event, .. } => match event {
DeviceEvent::Added { .. } => "DeviceEvent::Added",
DeviceEvent::Removed { .. } => "DeviceEvent::Removed",
DeviceEvent::MouseMotion { .. } => "DeviceEvent::MouseMotion",
DeviceEvent::MouseWheel { .. } => "DeviceEvent::MouseWheel",
DeviceEvent::Motion { .. } => "DeviceEvent::Motion",
DeviceEvent::Button { .. } => "DeviceEvent::Button",
DeviceEvent::Key { .. } => "DeviceEvent::Key",
DeviceEvent::Text { .. } => "DeviceEvent::Text",
},
Event::NewEvents(start_cause) => match start_cause {
StartCause::ResumeTimeReached { .. } => "NewEvents::ResumeTimeReached",
StartCause::WaitCancelled { .. } => "NewEvents::WaitCancelled",
StartCause::Poll => "NewEvents::Poll",
StartCause::Init => "NewEvents::Init",
},
Event::WindowEvent { event, .. } => short_window_event_description(event),
}
}
/// Short and fast description of an event.
/// Useful for logging and profiling.
pub fn short_window_event_description(event: &winit::event::WindowEvent<'_>) -> &'static str {
use winit::event::WindowEvent;
match event {
WindowEvent::Resized { .. } => "WindowEvent::Resized",
WindowEvent::Moved { .. } => "WindowEvent::Moved",
WindowEvent::CloseRequested { .. } => "WindowEvent::CloseRequested",
WindowEvent::Destroyed { .. } => "WindowEvent::Destroyed",
WindowEvent::DroppedFile { .. } => "WindowEvent::DroppedFile",
WindowEvent::HoveredFile { .. } => "WindowEvent::HoveredFile",
WindowEvent::HoveredFileCancelled { .. } => "WindowEvent::HoveredFileCancelled",
WindowEvent::ReceivedCharacter { .. } => "WindowEvent::ReceivedCharacter",
WindowEvent::Focused { .. } => "WindowEvent::Focused",
WindowEvent::KeyboardInput { .. } => "WindowEvent::KeyboardInput",
WindowEvent::ModifiersChanged { .. } => "WindowEvent::ModifiersChanged",
WindowEvent::Ime { .. } => "WindowEvent::Ime",
WindowEvent::CursorMoved { .. } => "WindowEvent::CursorMoved",
WindowEvent::CursorEntered { .. } => "WindowEvent::CursorEntered",
WindowEvent::CursorLeft { .. } => "WindowEvent::CursorLeft",
WindowEvent::MouseWheel { .. } => "WindowEvent::MouseWheel",
WindowEvent::MouseInput { .. } => "WindowEvent::MouseInput",
WindowEvent::TouchpadMagnify { .. } => "WindowEvent::TouchpadMagnify",
WindowEvent::SmartMagnify { .. } => "WindowEvent::SmartMagnify",
WindowEvent::TouchpadRotate { .. } => "WindowEvent::TouchpadRotate",
WindowEvent::TouchpadPressure { .. } => "WindowEvent::TouchpadPressure",
WindowEvent::AxisMotion { .. } => "WindowEvent::AxisMotion",
WindowEvent::Touch { .. } => "WindowEvent::Touch",
WindowEvent::ScaleFactorChanged { .. } => "WindowEvent::ScaleFactorChanged",
WindowEvent::ThemeChanged { .. } => "WindowEvent::ThemeChanged",
WindowEvent::Occluded { .. } => "WindowEvent::Occluded",
}
}
// ---------------------------------------------------------------------------
mod profiling_scopes {
#![allow(unused_macros)]
#![allow(unused_imports)]

View File

@@ -52,6 +52,8 @@ impl WindowSettings {
&self,
mut viewport_builder: ViewportBuilder,
) -> ViewportBuilder {
crate::profile_function!();
// `WindowBuilder::with_position` expects inner position in Macos, and outer position elsewhere
// See [`winit::window::WindowBuilder::with_position`] for details.
let pos_px = if cfg!(target_os = "macos") {
@@ -127,6 +129,8 @@ fn clamp_pos_to_monitors<E>(
window_size_pts: egui::Vec2,
position_px: &mut egui::Pos2,
) {
crate::profile_function!();
let monitors = event_loop.available_monitors();
// default to primary monitor, in case the correct monitor was disconnected.