From aeaa54aab1266fa04b2b47fbf160b66966ff6cd1 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sun, 28 Mar 2021 22:13:41 +0200 Subject: [PATCH] optimization: don't compare font data each frame --- egui/src/context.rs | 39 +++++++++++++++++++++++++-------------- egui/src/memory.rs | 5 +++-- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/egui/src/context.rs b/egui/src/context.rs index 2db63db32..fe1bc9b1f 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -407,7 +407,14 @@ impl Context { /// Will become active at the start of the next frame. pub fn set_fonts(&self, font_definitions: FontDefinitions) { - self.memory().options.font_definitions = font_definitions; + if let Some(current_fonts) = &self.fonts { + // NOTE: this comparison is expensive since it checks TTF data for equality + if current_fonts.definitions() == &font_definitions { + return; // no change - save us from reloading font textures + } + } + + self.memory().new_font_definitions = Some(font_definitions); } /// The [`Style`] used by all subsequent windows, panels etc. @@ -531,20 +538,24 @@ impl Context { self.input = input.begin_frame(new_raw_input); self.frame_state.lock().begin_frame(&self.input); - let font_definitions = self.memory().options.font_definitions.clone(); - let pixels_per_point = self.input.pixels_per_point(); - let same_as_current = match &self.fonts { - None => false, - Some(fonts) => { - *fonts.definitions() == font_definitions - && (fonts.pixels_per_point() - pixels_per_point).abs() < 1e-3 + { + // Load new fonts if required: + let new_font_definitions = self.memory().new_font_definitions.take(); + let pixels_per_point = self.input.pixels_per_point(); + + let pixels_per_point_changed = match &self.fonts { + None => true, + Some(current_fonts) => { + (current_fonts.pixels_per_point() - pixels_per_point).abs() > 1e-3 + } + }; + + if self.fonts.is_none() || new_font_definitions.is_some() || pixels_per_point_changed { + self.fonts = Some(Arc::new(Fonts::from_definitions( + pixels_per_point, + new_font_definitions.unwrap_or_default(), + ))); } - }; - if !same_as_current { - self.fonts = Some(Arc::new(Fonts::from_definitions( - pixels_per_point, - font_definitions, - ))); } // Ensure we register the background area so panels and background ui can catch clicks: diff --git a/egui/src/memory.rs b/egui/src/memory.rs index 7c140eccb..4377718a0 100644 --- a/egui/src/memory.rs +++ b/egui/src/memory.rs @@ -23,6 +23,9 @@ pub struct Memory { /// new scale that will be applied at the start of the next frame pub(crate) new_pixels_per_point: Option, + /// new fonts that will be applied at the start of the next frame + pub(crate) new_font_definitions: Option, + #[cfg_attr(feature = "persistence", serde(skip))] pub(crate) interaction: Interaction, @@ -71,8 +74,6 @@ pub struct Options { pub(crate) style: std::sync::Arc