From 0187ac8fde245d6e6d4d8af7c9b706531e5346c8 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 24 Aug 2021 18:16:13 -0600 Subject: [PATCH] Share a single pool of LineWrappers across all threads Co-Authored-By: Max Brunsfeld --- zed/src/editor/display_map/line_wrapper.rs | 39 +++++++++++----------- zed/src/editor/display_map/wrap_map.rs | 6 ++-- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/zed/src/editor/display_map/line_wrapper.rs b/zed/src/editor/display_map/line_wrapper.rs index 97ac2769e72b231e85d9f55c3fc5e763e674b36c..106e55a55facba66f786ef87f5ba2e070c956d33 100644 --- a/zed/src/editor/display_map/line_wrapper.rs +++ b/zed/src/editor/display_map/line_wrapper.rs @@ -1,15 +1,16 @@ use crate::Settings; use gpui::{fonts::FontId, FontCache, FontSystem}; +use lazy_static::lazy_static; +use parking_lot::Mutex; use std::{ - cell::RefCell, collections::HashMap, iter, ops::{Deref, DerefMut}, sync::Arc, }; -thread_local! { - static WRAPPERS: RefCell> = Default::default(); +lazy_static! { + static ref POOL: Mutex> = Default::default(); } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -35,25 +36,24 @@ pub struct LineWrapper { impl LineWrapper { pub const MAX_INDENT: u32 = 256; - pub fn thread_local( + pub fn acquire( font_system: Arc, font_cache: &FontCache, settings: Settings, ) -> LineWrapperHandle { - let wrapper = - if let Some(mut wrapper) = WRAPPERS.with(|wrappers| wrappers.borrow_mut().pop()) { - let font_id = font_cache - .select_font(settings.buffer_font_family, &Default::default()) - .unwrap(); - let font_size = settings.buffer_font_size; - if wrapper.font_id != font_id || wrapper.font_size != font_size { - wrapper.cached_ascii_char_widths = [f32::NAN; 128]; - wrapper.cached_other_char_widths.clear(); - } - wrapper - } else { - LineWrapper::new(font_system, font_cache, settings) - }; + let wrapper = if let Some(mut wrapper) = POOL.lock().pop() { + let font_id = font_cache + .select_font(settings.buffer_font_family, &Default::default()) + .unwrap(); + let font_size = settings.buffer_font_size; + if wrapper.font_id != font_id || wrapper.font_size != font_size { + wrapper.cached_ascii_char_widths = [f32::NAN; 128]; + wrapper.cached_other_char_widths.clear(); + } + wrapper + } else { + LineWrapper::new(font_system, font_cache, settings) + }; LineWrapperHandle(Some(wrapper)) } @@ -163,6 +163,7 @@ impl LineWrapper { } fn compute_width_for_char(&self, c: char) -> f32 { + log::info!("cache miss {}", c); self.font_system .layout_line( &c.to_string(), @@ -178,7 +179,7 @@ pub struct LineWrapperHandle(Option); impl Drop for LineWrapperHandle { fn drop(&mut self) { let wrapper = self.0.take().unwrap(); - WRAPPERS.with(|wrappers| wrappers.borrow_mut().push(wrapper)) + POOL.lock().push(wrapper) } } diff --git a/zed/src/editor/display_map/wrap_map.rs b/zed/src/editor/display_map/wrap_map.rs index e831d800429ceab9d584626fd5827eddefae6070..1d5359eabff854d7d2e9a106b7e890f56d8b1f41 100644 --- a/zed/src/editor/display_map/wrap_map.rs +++ b/zed/src/editor/display_map/wrap_map.rs @@ -119,8 +119,7 @@ impl WrapMap { let font_cache = cx.font_cache().clone(); let settings = self.settings.clone(); let task = cx.background().spawn(async move { - let mut line_wrapper = - LineWrapper::thread_local(font_system, &font_cache, settings); + let mut line_wrapper = LineWrapper::acquire(font_system, &font_cache, settings); let tab_snapshot = new_snapshot.tab_snapshot.clone(); let range = TabPoint::zero()..tab_snapshot.max_point(); new_snapshot @@ -194,8 +193,7 @@ impl WrapMap { let font_cache = cx.font_cache().clone(); let settings = self.settings.clone(); let update_task = cx.background().spawn(async move { - let mut line_wrapper = - LineWrapper::thread_local(font_system, &font_cache, settings); + let mut line_wrapper = LineWrapper::acquire(font_system, &font_cache, settings); for (tab_snapshot, edits) in pending_edits { snapshot .update(tab_snapshot, &edits, wrap_width, &mut line_wrapper)