diff options
author | 2023-06-29 17:54:54 +0200 | |
---|---|---|
committer | 2023-06-29 17:54:54 +0200 | |
commit | 98febd9a428f56e28112257adb72ef603fd2ddc5 (patch) | |
tree | 6f11987ed05f5af9b88d8668586d08f0c69a96a9 /wgpu/src/text.rs | |
parent | 0cc85c7820136f3ad858c287e8e35884604e7bd0 (diff) | |
download | iced-98febd9a428f56e28112257adb72ef603fd2ddc5.tar.gz iced-98febd9a428f56e28112257adb72ef603fd2ddc5.tar.bz2 iced-98febd9a428f56e28112257adb72ef603fd2ddc5.zip |
Introduce `Mode` for `text::Cache` and trim only when switching modes
Diffstat (limited to 'wgpu/src/text.rs')
-rw-r--r-- | wgpu/src/text.rs | 82 |
1 files changed, 64 insertions, 18 deletions
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 1b94edf6..c87b94a8 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -80,6 +80,11 @@ impl Pipeline { let renderer = &mut self.renderers[self.prepare_layer]; let cache = self.cache.get_mut(); + if self.prepare_layer == 0 { + let _ = cache.switch(Mode::Drawing); + cache.trim(); + } + let keys: Vec<_> = sections .iter() .map(|section| { @@ -224,7 +229,6 @@ impl Pipeline { pub fn end_frame(&mut self) { self.atlas.trim(); - self.cache.get_mut().trim(); self.prepare_layer = 0; } @@ -238,11 +242,15 @@ impl Pipeline { bounds: Size, shaping: Shaping, ) -> Size { - let mut measurement_cache = self.cache.borrow_mut(); + let mut cache = self.cache.borrow_mut(); let line_height = f32::from(line_height.to_absolute(Pixels(size))); - let (_, entry) = measurement_cache.allocate( + if cache.switch(Mode::Measuring) { + cache.trim(); + } + + let (_, entry) = cache.allocate( &mut self.font_system.borrow_mut(), Key { content, @@ -268,11 +276,15 @@ impl Pipeline { point: Point, _nearest_only: bool, ) -> Option<Hit> { - let mut measurement_cache = self.cache.borrow_mut(); + let mut cache = self.cache.borrow_mut(); let line_height = f32::from(line_height.to_absolute(Pixels(size))); - let (_, entry) = measurement_cache.allocate( + if cache.switch(Mode::Measuring) { + cache.trim(); + } + + let (_, entry) = cache.allocate( &mut self.font_system.borrow_mut(), Key { content, @@ -348,9 +360,11 @@ fn to_shaping(shaping: Shaping) -> glyphon::Shaping { struct Cache { entries: FxHashMap<KeyHash, Entry>, - measurements: FxHashMap<KeyHash, KeyHash>, - recently_used: FxHashSet<KeyHash>, + aliases: FxHashMap<KeyHash, KeyHash>, + recently_measured: FxHashSet<KeyHash>, + recently_drawn: FxHashSet<KeyHash>, hasher: HashBuilder, + mode: Mode, } struct Entry { @@ -358,6 +372,12 @@ struct Entry { bounds: Size, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Mode { + Measuring, + Drawing, +} + #[cfg(not(target_arch = "wasm32"))] type HashBuilder = twox_hash::RandomXxHashBuilder64; @@ -368,9 +388,11 @@ impl Cache { fn new() -> Self { Self { entries: FxHashMap::default(), - measurements: FxHashMap::default(), - recently_used: FxHashSet::default(), + aliases: FxHashMap::default(), + recently_measured: FxHashSet::default(), + recently_drawn: FxHashSet::default(), hasher: HashBuilder::default(), + mode: Mode::Measuring, } } @@ -378,6 +400,14 @@ impl Cache { self.entries.get(key) } + fn switch(&mut self, mode: Mode) -> bool { + let has_changed = self.mode != mode; + + self.mode = mode; + + has_changed + } + fn allocate( &mut self, font_system: &mut glyphon::FontSystem, @@ -385,8 +415,13 @@ impl Cache { ) -> (KeyHash, &mut Entry) { let hash = key.hash(self.hasher.build_hasher()); - if let Some(hash) = self.measurements.get(&hash) { - let _ = self.recently_used.insert(*hash); + let recently_used = match self.mode { + Mode::Measuring => &mut self.recently_measured, + Mode::Drawing => &mut self.recently_drawn, + }; + + if let Some(hash) = self.aliases.get(&hash) { + let _ = recently_used.insert(*hash); return (*hash, self.entries.get_mut(hash).unwrap()); } @@ -421,7 +456,7 @@ impl Cache { }, ] { if key.bounds != bounds { - let _ = self.measurements.insert( + let _ = self.aliases.insert( Key { bounds, ..key }.hash(self.hasher.build_hasher()), hash, ); @@ -429,18 +464,29 @@ impl Cache { } } - let _ = self.recently_used.insert(hash); + let _ = recently_used.insert(hash); (hash, self.entries.get_mut(&hash).unwrap()) } fn trim(&mut self) { - self.entries - .retain(|key, _| self.recently_used.contains(key)); - self.measurements - .retain(|_, value| self.recently_used.contains(value)); + self.entries.retain(|key, _| { + self.recently_measured.contains(key) + || self.recently_drawn.contains(key) + }); + self.aliases.retain(|_, value| { + self.recently_measured.contains(value) + || self.recently_drawn.contains(value) + }); - self.recently_used.clear(); + match self.mode { + Mode::Measuring => { + self.recently_measured.clear(); + } + Mode::Drawing => { + self.recently_drawn.clear(); + } + } } } |