Introduce Mode for text::Cache and trim only when switching modes

This commit is contained in:
Héctor Ramón Jiménez 2023-06-29 17:54:54 +02:00
parent 0cc85c7820
commit 98febd9a42
No known key found for this signature in database
GPG key ID: 140CC052C94F138E

View file

@ -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();
}
}
}
}