Introduce Mode for text::Cache and trim only when switching modes
This commit is contained in:
parent
0cc85c7820
commit
98febd9a42
1 changed files with 64 additions and 18 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue