From d6a5c8b6bfec7b920269cb3264debd9d584e2244 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 7 Nov 2023 10:24:56 +0100 Subject: [PATCH] Introduce `ViewportIdSet` --- crates/eframe/src/native/run.rs | 26 ++++++++--------- crates/egui-wgpu/src/winit.rs | 8 +++--- crates/egui/src/context.rs | 50 ++++++++++++++++----------------- crates/egui/src/memory.rs | 8 +++--- crates/egui/src/viewport.rs | 5 +++- 5 files changed, 50 insertions(+), 47 deletions(-) diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 179f4dd50..3aecb03f1 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -459,7 +459,7 @@ fn run_and_exit(event_loop: EventLoop, mut winit_app: impl WinitApp + mod glow_integration { use egui::{ - epaint::ahash::HashMap, NumExt as _, ViewportIdPair, ViewportMap, ViewportOutput, + epaint::ahash::HashMap, NumExt as _, ViewportIdMap, ViewportIdPair, ViewportOutput, ViewportUiCallback, }; use egui_winit::{ @@ -533,11 +533,11 @@ mod glow_integration { current_gl_context: Option, not_current_gl_context: Option, - viewports: ViewportMap>>, + viewports: ViewportIdMap>>, viewport_maps: HashMap, - window_maps: ViewportMap, + window_maps: ViewportIdMap, - builders: ViewportMap, + builders: ViewportIdMap, } impl GlutinWindowContext { @@ -660,13 +660,13 @@ mod glow_integration { let not_current_gl_context = Some(gl_context); let mut viewport_maps = HashMap::default(); - let mut window_maps = ViewportMap::default(); + let mut window_maps = ViewportIdMap::default(); if let Some(window) = &window { viewport_maps.insert(window.id(), ViewportId::ROOT); window_maps.insert(ViewportId::ROOT, window.id()); } - let mut windows = ViewportMap::default(); + let mut windows = ViewportIdMap::default(); windows.insert( ViewportId::ROOT, Rc::new(RefCell::new(Viewport { @@ -678,7 +678,7 @@ mod glow_integration { })), ); - let mut builders = ViewportMap::default(); + let mut builders = ViewportIdMap::default(); builders.insert(ViewportId::ROOT, window_builder); // the fun part with opengl gl is that we never know whether there is an error. the context creation might have failed, but @@ -1888,7 +1888,7 @@ pub use glow_integration::run_glow; #[cfg(feature = "wgpu")] mod wgpu_integration { - use egui::{ViewportIdPair, ViewportMap, ViewportOutput, ViewportUiCallback}; + use egui::{ViewportIdMap, ViewportIdPair, ViewportOutput, ViewportUiCallback}; use egui_winit::create_winit_window_builder; use parking_lot::Mutex; @@ -1907,10 +1907,10 @@ mod wgpu_integration { } #[derive(Clone, Default)] - pub struct Viewports(ViewportMap); + pub struct Viewports(ViewportIdMap); impl std::ops::Deref for Viewports { - type Target = ViewportMap; + type Target = ViewportIdMap; fn deref(&self) -> &Self::Target { &self.0 @@ -1931,7 +1931,7 @@ mod wgpu_integration { integration: Rc>, app: Box, viewports: Rc>, - builders: Rc>>, + builders: Rc>>, viewport_maps: Rc>>, } @@ -2178,7 +2178,7 @@ mod wgpu_integration { }, ); - let builders = Rc::new(RefCell::new(ViewportMap::default())); + let builders = Rc::new(RefCell::new(ViewportIdMap::default())); builders.borrow_mut().insert(ViewportId::ROOT, builder); let painter = Rc::new(RefCell::new(painter)); @@ -2243,7 +2243,7 @@ mod wgpu_integration { id_pair: ViewportIdPair, viewport_ui_cb: Box, viewports: &RefCell, - builders: &RefCell>, + builders: &RefCell>, beginning: Instant, painter: &RefCell, viewport_maps: &RefCell>, diff --git a/crates/egui-wgpu/src/winit.rs b/crates/egui-wgpu/src/winit.rs index d3ad80ca8..2cebfa410 100644 --- a/crates/egui-wgpu/src/winit.rs +++ b/crates/egui-wgpu/src/winit.rs @@ -1,6 +1,6 @@ use std::{num::NonZeroU32, sync::Arc}; -use egui::{ViewportId, ViewportMap}; +use egui::{ViewportId, ViewportIdMap}; use crate::{renderer, RenderState, SurfaceErrorAction, WgpuConfiguration}; @@ -79,13 +79,13 @@ pub struct Painter { msaa_samples: u32, support_transparent_backbuffer: bool, depth_format: Option, - depth_texture_view: ViewportMap, - msaa_texture_view: ViewportMap, + depth_texture_view: ViewportIdMap, + msaa_texture_view: ViewportIdMap, screen_capture_state: Option, instance: wgpu::Instance, render_state: Option, - surfaces: ViewportMap, + surfaces: ViewportIdMap, } unsafe impl Send for Painter {} diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 1c5c101c1..847f9f607 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -59,13 +59,13 @@ struct Repaint { /// The current frame number. /// /// Incremented at the end of each frame. - viewports_frame_nr: ViewportMap, + viewports_frame_nr: ViewportIdMap, /// While positive, keep requesting repaints. Decrement at the start of each frame. - repaint_request: ViewportMap, + repaint_request: ViewportIdMap, request_repaint_callback: Option>, - requested_repaint_last_frame: ViewportMap, + requested_repaint_last_frame: ViewportIdMap, } impl Repaint { @@ -110,7 +110,7 @@ impl Repaint { } // returns what is needed to be repainted - fn end_frame(&mut self, viewport_id: ViewportId, viewports: &[ViewportId]) { + fn end_frame(&mut self, viewport_id: ViewportId, viewports: &ViewportIdSet) { *self.viewports_frame_nr.entry(viewport_id).or_default() += 1; self.requested_repaint_last_frame @@ -154,32 +154,32 @@ struct ContextImpl { os: OperatingSystem, - input: ViewportMap, + input: ViewportIdMap, /// State that is collected during a frame and then cleared - frame_state: ViewportMap, + frame_state: ViewportIdMap, /// How deeply nested are we? viewport_stack: Vec, // The output of a frame: - graphics: ViewportMap, - output: ViewportMap, + graphics: ViewportIdMap, + output: ViewportIdMap, paint_stats: PaintStats, repaint: Repaint, - viewports: ViewportMap, + viewports: ViewportIdMap, viewport_commands: Vec<(ViewportId, ViewportCommand)>, embed_viewports: bool, /// Written to during the frame. - layer_rects_this_frame: ViewportMap>>, + layer_rects_this_frame: ViewportIdMap>>, /// Read - layer_rects_prev_frame: ViewportMap>>, + layer_rects_prev_frame: ViewportIdMap>>, #[cfg(feature = "accesskit")] is_accesskit_enabled: bool, @@ -1534,13 +1534,13 @@ impl Context { let shapes = self.drain_paint_lists(); - // If there are no viewport that contains the current viewport that viewport needs to be destroyed! - let available_viewports = self.read(|ctx| { - let mut available_viewports = vec![ViewportId::ROOT]; + let all_viewport_ids = self.read(|ctx| { + let mut all_viewport_ids = ViewportIdSet::default(); + all_viewport_ids.insert(ViewportId::ROOT); for vp in ctx.viewports.values() { - available_viewports.push(vp.id_pair.this); + all_viewport_ids.insert(vp.id_pair.this); } - available_viewports + all_viewport_ids }); let viewport_id = self.viewport_id(); @@ -1559,8 +1559,9 @@ impl Context { id_pair: viewport.id_pair, viewport_ui_cb: viewport.viewport_ui_cb.clone(), }); + (was_used || viewport_id != viewport.id_pair.parent) - && available_viewports.contains(&viewport.id_pair.parent) + && all_viewport_ids.contains(&viewport.id_pair.parent) }); }); @@ -1573,16 +1574,15 @@ impl Context { if is_last { // Context Cleanup self.write(|ctx| { - ctx.input.retain(|id, _| available_viewports.contains(id)); + ctx.input.retain(|id, _| all_viewport_ids.contains(id)); ctx.layer_rects_prev_frame - .retain(|id, _| available_viewports.contains(id)); + .retain(|id, _| all_viewport_ids.contains(id)); ctx.layer_rects_this_frame - .retain(|id, _| available_viewports.contains(id)); - ctx.output.retain(|id, _| available_viewports.contains(id)); + .retain(|id, _| all_viewport_ids.contains(id)); + ctx.output.retain(|id, _| all_viewport_ids.contains(id)); ctx.frame_state - .retain(|id, _| available_viewports.contains(id)); - ctx.graphics - .retain(|id, _| available_viewports.contains(id)); + .retain(|id, _| all_viewport_ids.contains(id)); + ctx.graphics.retain(|id, _| all_viewport_ids.contains(id)); }); } else { let viewport_id = self.viewport_id(); @@ -1591,7 +1591,7 @@ impl Context { }); } - self.write(|ctx| ctx.repaint.end_frame(viewport_id, &available_viewports)); + self.write(|ctx| ctx.repaint.end_frame(viewport_id, &all_viewport_ids)); FullOutput { platform_output, diff --git a/crates/egui/src/memory.rs b/crates/egui/src/memory.rs index b4993474f..f87c61f2e 100644 --- a/crates/egui/src/memory.rs +++ b/crates/egui/src/memory.rs @@ -4,7 +4,7 @@ use epaint::{emath::Rangef, vec2, Vec2}; use crate::{ area, window, EventFilter, Id, IdMap, InputState, LayerId, Pos2, Rect, Style, ViewportId, - ViewportMap, + ViewportIdMap, }; // ---------------------------------------------------------------------------- @@ -78,7 +78,7 @@ pub struct Memory { pub(crate) new_font_definitions: Option, #[cfg_attr(feature = "persistence", serde(skip))] - pub(crate) interactions: ViewportMap, + pub(crate) interactions: ViewportIdMap, #[cfg_attr(feature = "persistence", serde(skip))] pub(crate) interaction: Interaction, @@ -91,7 +91,7 @@ pub struct Memory { pub(crate) window_interaction: Option, #[cfg_attr(feature = "persistence", serde(skip))] - pub(crate) window_interactions: ViewportMap, + pub(crate) window_interactions: ViewportIdMap, #[cfg_attr(feature = "persistence", serde(skip))] pub(crate) drag_value: crate::widgets::drag_value::MonoState, @@ -100,7 +100,7 @@ pub struct Memory { pub(crate) areas: Areas, #[cfg_attr(feature = "persistence", serde(skip))] - pub(crate) viewports_areas: ViewportMap, + pub(crate) viewports_areas: ViewportIdMap, /// Which popup-window is open (if any)? /// Could be a combo box, color picker, menu etc. diff --git a/crates/egui/src/viewport.rs b/crates/egui/src/viewport.rs index 64abf1d81..01533dd9b 100644 --- a/crates/egui/src/viewport.rs +++ b/crates/egui/src/viewport.rs @@ -51,8 +51,11 @@ impl From for Id { impl nohash_hasher::IsEnabled for ViewportId {} +/// A fast hash set of [`ViewportId`]. +pub type ViewportIdSet = nohash_hasher::IntSet; + /// A fast hash map from [`ViewportId`] to `T`. -pub type ViewportMap = nohash_hasher::IntMap; +pub type ViewportIdMap = nohash_hasher::IntMap; // ----------------------------------------------------------------------------