summaryrefslogtreecommitdiffstats
path: root/wgpu/src/text.rs
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-06-29 17:54:54 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-06-29 17:54:54 +0200
commit98febd9a428f56e28112257adb72ef603fd2ddc5 (patch)
tree6f11987ed05f5af9b88d8668586d08f0c69a96a9 /wgpu/src/text.rs
parent0cc85c7820136f3ad858c287e8e35884604e7bd0 (diff)
downloadiced-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.rs82
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();
+ }
+ }
}
}