From 4800991f28b220f07d30be12c040aeb11356e321 Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Wed, 24 Jan 2024 10:38:38 +0100 Subject: [PATCH] Cache font-missing result to avoid unnecessary lookups This fixes the performance problem we saw in https://github.com/zed-industries/community/issues/2405. In a trace we could see that if a font is missing we'd constantly look it up and never cache that it's missing. This changes that and does cache the font-is-missing result. Drawback is that one would need to restart Zed after installing a missing font that was configured in settings. That seems acceptable for now, though. Co-authored-by: Antonio --- crates/gpui/src/text_system.rs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/crates/gpui/src/text_system.rs b/crates/gpui/src/text_system.rs index 6cc56e306b..15042cbf59 100644 --- a/crates/gpui/src/text_system.rs +++ b/crates/gpui/src/text_system.rs @@ -41,7 +41,7 @@ pub(crate) const SUBPIXEL_VARIANTS: u8 = 4; pub struct TextSystem { line_layout_cache: Arc, platform_text_system: Arc, - font_ids_by_font: RwLock>, + font_ids_by_font: RwLock>>, font_metrics: RwLock>, raster_bounds: RwLock>>, wrapper_pool: Mutex>>, @@ -91,13 +91,26 @@ impl TextSystem { /// Get the FontId for the configure font family and style. pub fn font_id(&self, font: &Font) -> Result { - let font_id = self.font_ids_by_font.read().get(font).copied(); + fn clone_font_id_result(font_id: &Result) -> Result { + match font_id { + Ok(font_id) => Ok(*font_id), + Err(err) => Err(anyhow!("{}", err)), + } + } + + let font_id = self + .font_ids_by_font + .read() + .get(font) + .map(clone_font_id_result); if let Some(font_id) = font_id { - Ok(font_id) + font_id } else { - let font_id = self.platform_text_system.font_id(font)?; - self.font_ids_by_font.write().insert(font.clone(), font_id); - Ok(font_id) + let font_id = self.platform_text_system.font_id(font); + self.font_ids_by_font + .write() + .insert(font.clone(), clone_font_id_result(&font_id)); + font_id } }