From 78ad365db232e53cbdf12105e40c1dbe87a3238c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 28 Jun 2023 00:35:37 +0200 Subject: Reuse entries in `text::Cache` in `iced_wgpu` --- core/src/renderer/null.rs | 4 +-- core/src/text.rs | 6 ++-- core/src/widget/text.rs | 10 +++--- graphics/src/backend.rs | 2 +- graphics/src/renderer.rs | 2 +- renderer/src/backend.rs | 2 +- tiny_skia/src/backend.rs | 2 +- tiny_skia/src/text.rs | 4 +-- wgpu/src/backend.rs | 2 +- wgpu/src/text.rs | 81 +++++++++++++++++++++++++++++++---------------- 10 files changed, 69 insertions(+), 46 deletions(-) diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index f0cc952e..5d49699e 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -64,8 +64,8 @@ impl text::Renderer for Null { _font: Font, _bounds: Size, _shaping: text::Shaping, - ) -> (f32, f32) { - (0.0, 20.0) + ) -> Size { + Size::new(0.0, 20.0) } fn hit_test( diff --git a/core/src/text.rs b/core/src/text.rs index c154cc27..fc8aa20e 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -163,7 +163,7 @@ pub trait Renderer: crate::Renderer { font: Self::Font, bounds: Size, shaping: Shaping, - ) -> (f32, f32); + ) -> Size; /// Measures the width of the text as if it were laid out in a single line. fn measure_width( @@ -173,7 +173,7 @@ pub trait Renderer: crate::Renderer { font: Self::Font, shaping: Shaping, ) -> f32 { - let (width, _) = self.measure( + let bounds = self.measure( content, size, LineHeight::Absolute(Pixels(size)), @@ -182,7 +182,7 @@ pub trait Renderer: crate::Renderer { shaping, ); - width + bounds.width } /// Tests whether the provided point is within the boundaries of text diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index e934a2f5..79df2b02 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -5,7 +5,7 @@ use crate::mouse; use crate::renderer; use crate::text; use crate::widget::Tree; -use crate::{Color, Element, Layout, Length, Pixels, Rectangle, Size, Widget}; +use crate::{Color, Element, Layout, Length, Pixels, Rectangle, Widget}; use std::borrow::Cow; @@ -139,18 +139,16 @@ where let size = self.size.unwrap_or_else(|| renderer.default_size()); - let bounds = limits.max(); - - let (width, height) = renderer.measure( + let bounds = renderer.measure( &self.content, size, self.line_height, self.font.unwrap_or_else(|| renderer.default_font()), - bounds, + limits.max(), self.shaping, ); - let size = limits.resolve(Size::new(width, height)); + let size = limits.resolve(bounds); layout::Node::new(size) } diff --git a/graphics/src/backend.rs b/graphics/src/backend.rs index 6a082576..70ccc664 100644 --- a/graphics/src/backend.rs +++ b/graphics/src/backend.rs @@ -38,7 +38,7 @@ pub trait Text { font: Font, bounds: Size, shaping: text::Shaping, - ) -> (f32, f32); + ) -> Size; /// Tests whether the provided point is within the boundaries of [`Text`] /// laid out with the given parameters, returning information about diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 4241d45c..7e70a766 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -133,7 +133,7 @@ where font: Font, bounds: Size, shaping: text::Shaping, - ) -> (f32, f32) { + ) -> Size { self.backend().measure( content, size, diff --git a/renderer/src/backend.rs b/renderer/src/backend.rs index 18f9f3fc..3f229b52 100644 --- a/renderer/src/backend.rs +++ b/renderer/src/backend.rs @@ -42,7 +42,7 @@ impl backend::Text for Backend { font: Font, bounds: Size, shaping: text::Shaping, - ) -> (f32, f32) { + ) -> Size { delegate!( self, backend, diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index ba038052..c8999561 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -787,7 +787,7 @@ impl backend::Text for Backend { font: Font, bounds: Size, shaping: text::Shaping, - ) -> (f32, f32) { + ) -> Size { self.text_pipeline.measure( contents, size, diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 3441da8f..4f89ef52 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -138,7 +138,7 @@ impl Pipeline { font: Font, bounds: Size, shaping: Shaping, - ) -> (f32, f32) { + ) -> Size { let mut measurement_cache = self.cache.borrow_mut(); let line_height = f32::from(line_height.to_absolute(Pixels(size))); @@ -162,7 +162,7 @@ impl Pipeline { (i + 1, buffer.line_w.max(max)) }); - (max_width, line_height * total_lines as f32) + Size::new(max_width, line_height * total_lines as f32) } pub fn hit_test( diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index eecba2f1..f8829e47 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -355,7 +355,7 @@ impl backend::Text for Backend { font: Font, bounds: Size, shaping: core::text::Shaping, - ) -> (f32, f32) { + ) -> Size { self.text_pipeline.measure( contents, size, diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index c9188bd1..04943049 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -113,15 +113,13 @@ impl Pipeline { .iter() .zip(keys.iter()) .filter_map(|(section, key)| { - let buffer = cache.get(key).expect("Get cached buffer"); + let entry = cache.get(key).expect("Get cached buffer"); let x = section.bounds.x * scale_factor; let y = section.bounds.y * scale_factor; - let (max_width, total_height) = measure(buffer); - - let max_width = max_width * scale_factor; - let total_height = total_height * scale_factor; + let max_width = entry.bounds.width * scale_factor; + let total_height = entry.bounds.height * scale_factor; let left = match section.horizontal_alignment { alignment::Horizontal::Left => x, @@ -145,7 +143,7 @@ impl Pipeline { let clip_bounds = bounds.intersection(§ion_bounds)?; Some(glyphon::TextArea { - buffer, + buffer: &entry.buffer, left, top, scale: scale_factor, @@ -239,12 +237,12 @@ impl Pipeline { font: Font, bounds: Size, shaping: Shaping, - ) -> (f32, f32) { + ) -> Size { let mut measurement_cache = self.cache.borrow_mut(); let line_height = f32::from(line_height.to_absolute(Pixels(size))); - let (_, paragraph) = measurement_cache.allocate( + let (_, entry) = measurement_cache.allocate( &mut self.font_system.borrow_mut(), Key { content, @@ -256,7 +254,7 @@ impl Pipeline { }, ); - measure(paragraph) + entry.bounds } pub fn hit_test( @@ -274,7 +272,7 @@ impl Pipeline { let line_height = f32::from(line_height.to_absolute(Pixels(size))); - let (_, paragraph) = measurement_cache.allocate( + let (_, entry) = measurement_cache.allocate( &mut self.font_system.borrow_mut(), Key { content, @@ -286,20 +284,20 @@ impl Pipeline { }, ); - let cursor = paragraph.hit(point.x, point.y)?; + let cursor = entry.buffer.hit(point.x, point.y)?; Some(Hit::CharOffset(cursor.index)) } } -fn measure(buffer: &glyphon::Buffer) -> (f32, f32) { +fn measure(buffer: &glyphon::Buffer) -> Size { let (width, total_lines) = buffer .layout_runs() .fold((0.0, 0usize), |(width, total_lines), run| { (run.line_w.max(width), total_lines + 1) }); - (width, total_lines as f32 * buffer.metrics().line_height) + Size::new(width, total_lines as f32 * buffer.metrics().line_height) } fn to_family(family: font::Family) -> glyphon::Family<'static> { @@ -349,11 +347,17 @@ fn to_shaping(shaping: Shaping) -> glyphon::Shaping { } struct Cache { - entries: FxHashMap, + entries: FxHashMap, + bound_entries: FxHashMap, recently_used: FxHashSet, hasher: HashBuilder, } +struct Entry { + buffer: glyphon::Buffer, + bounds: Size, +} + #[cfg(not(target_arch = "wasm32"))] type HashBuilder = twox_hash::RandomXxHashBuilder64; @@ -364,12 +368,13 @@ impl Cache { fn new() -> Self { Self { entries: FxHashMap::default(), + bound_entries: FxHashMap::default(), recently_used: FxHashSet::default(), hasher: HashBuilder::default(), } } - fn get(&self, key: &KeyHash) -> Option<&glyphon::Buffer> { + fn get(&self, key: &KeyHash) -> Option<&Entry> { self.entries.get(key) } @@ -377,20 +382,15 @@ impl Cache { &mut self, font_system: &mut glyphon::FontSystem, key: Key<'_>, - ) -> (KeyHash, &mut glyphon::Buffer) { - let hash = { - let mut hasher = self.hasher.build_hasher(); + ) -> (KeyHash, &mut Entry) { + let hash = key.hash(self.hasher.build_hasher()); - key.content.hash(&mut hasher); - key.size.to_bits().hash(&mut hasher); - key.line_height.to_bits().hash(&mut hasher); - key.font.hash(&mut hasher); - key.bounds.width.to_bits().hash(&mut hasher); - key.bounds.height.to_bits().hash(&mut hasher); - key.shaping.hash(&mut hasher); + if let Some(bound_hash) = self.bound_entries.get(&hash) { + let _ = self.recently_used.insert(hash); + let _ = self.recently_used.insert(*bound_hash); - hasher.finish() - }; + return (*bound_hash, self.entries.get_mut(&bound_hash).unwrap()); + } if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { let metrics = glyphon::Metrics::new(key.size, key.line_height); @@ -411,7 +411,16 @@ impl Cache { to_shaping(key.shaping), ); - let _ = entry.insert(buffer); + let bounds = measure(&buffer); + + let _ = entry.insert(Entry { buffer, bounds }); + + if key.bounds != bounds { + let _ = self.bound_entries.insert( + Key { bounds, ..key }.hash(self.hasher.build_hasher()), + hash, + ); + } } let _ = self.recently_used.insert(hash); @@ -422,6 +431,8 @@ impl Cache { fn trim(&mut self) { self.entries .retain(|key, _| self.recently_used.contains(key)); + self.bound_entries + .retain(|key, _| self.recently_used.contains(key)); self.recently_used.clear(); } @@ -437,4 +448,18 @@ struct Key<'a> { shaping: Shaping, } +impl Key<'_> { + fn hash(self, mut hasher: H) -> KeyHash { + self.content.hash(&mut hasher); + self.size.to_bits().hash(&mut hasher); + self.line_height.to_bits().hash(&mut hasher); + self.font.hash(&mut hasher); + self.bounds.width.to_bits().hash(&mut hasher); + self.bounds.height.to_bits().hash(&mut hasher); + self.shaping.hash(&mut hasher); + + hasher.finish() + } +} + type KeyHash = u64; -- cgit From 73dca5e323756ad29003517587c4092e8b6a246d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 28 Jun 2023 00:44:23 +0200 Subject: Reuse entries in `text::Cache` in `iced_tiny_skia` --- tiny_skia/src/text.rs | 102 +++++++++++++++++++++++++++++++------------------- wgpu/src/text.rs | 17 +++++---- 2 files changed, 74 insertions(+), 45 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 4f89ef52..22c17507 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -66,17 +66,10 @@ impl Pipeline { shaping, }; - let (_, buffer) = self.cache.get_mut().allocate(font_system, key); + let (_, entry) = self.cache.get_mut().allocate(font_system, key); - let (total_lines, max_width) = buffer - .layout_runs() - .enumerate() - .fold((0, 0.0), |(_, max), (i, buffer)| { - (i + 1, buffer.line_w.max(max)) - }); - - let total_height = total_lines as f32 * line_height * scale_factor; - let max_width = max_width * scale_factor; + let max_width = entry.bounds.width * scale_factor; + let total_height = entry.bounds.height * scale_factor; let bounds = bounds * scale_factor; @@ -94,7 +87,7 @@ impl Pipeline { let mut swash = cosmic_text::SwashCache::new(); - for run in buffer.layout_runs() { + for run in entry.buffer.layout_runs() { for glyph in run.glyphs { let physical_glyph = glyph.physical((x, y), scale_factor); @@ -143,7 +136,7 @@ impl Pipeline { let line_height = f32::from(line_height.to_absolute(Pixels(size))); - let (_, paragraph) = measurement_cache.allocate( + let (_, entry) = measurement_cache.allocate( &mut self.font_system.borrow_mut(), Key { content, @@ -155,14 +148,7 @@ impl Pipeline { }, ); - let (total_lines, max_width) = paragraph - .layout_runs() - .enumerate() - .fold((0, 0.0), |(_, max), (i, buffer)| { - (i + 1, buffer.line_w.max(max)) - }); - - Size::new(max_width, line_height * total_lines as f32) + entry.bounds } pub fn hit_test( @@ -180,7 +166,7 @@ impl Pipeline { let line_height = f32::from(line_height.to_absolute(Pixels(size))); - let (_, paragraph) = measurement_cache.allocate( + let (_, entry) = measurement_cache.allocate( &mut self.font_system.borrow_mut(), Key { content, @@ -192,12 +178,22 @@ impl Pipeline { }, ); - let cursor = paragraph.hit(point.x, point.y)?; + let cursor = entry.buffer.hit(point.x, point.y)?; Some(Hit::CharOffset(cursor.index)) } } +fn measure(buffer: &cosmic_text::Buffer) -> Size { + let (width, total_lines) = buffer + .layout_runs() + .fold((0.0, 0usize), |(width, total_lines), run| { + (run.line_w.max(width), total_lines + 1) + }); + + Size::new(width, total_lines as f32 * buffer.metrics().line_height) +} + fn to_family(family: font::Family) -> cosmic_text::Family<'static> { match family { font::Family::Name(name) => cosmic_text::Family::Name(name), @@ -354,12 +350,18 @@ impl GlyphCache { } struct Cache { - entries: FxHashMap, + entries: FxHashMap, + measurements: FxHashMap, recently_used: FxHashSet, hasher: HashBuilder, trim_count: usize, } +struct Entry { + buffer: cosmic_text::Buffer, + bounds: Size, +} + #[cfg(not(target_arch = "wasm32"))] type HashBuilder = twox_hash::RandomXxHashBuilder64; @@ -372,6 +374,7 @@ impl Cache { fn new() -> Self { Self { entries: FxHashMap::default(), + measurements: FxHashMap::default(), recently_used: FxHashSet::default(), hasher: HashBuilder::default(), trim_count: 0, @@ -382,20 +385,18 @@ impl Cache { &mut self, font_system: &mut cosmic_text::FontSystem, key: Key<'_>, - ) -> (KeyHash, &mut cosmic_text::Buffer) { - let hash = { - let mut hasher = self.hasher.build_hasher(); - - key.content.hash(&mut hasher); - key.size.to_bits().hash(&mut hasher); - key.line_height.to_bits().hash(&mut hasher); - key.font.hash(&mut hasher); - key.bounds.width.to_bits().hash(&mut hasher); - key.bounds.height.to_bits().hash(&mut hasher); - key.shaping.hash(&mut hasher); - - hasher.finish() - }; + ) -> (KeyHash, &mut Entry) { + let hash = key.hash(self.hasher.build_hasher()); + + if let Some(measured_hash) = self.measurements.get(&hash) { + let _ = self.recently_used.insert(hash); + let _ = self.recently_used.insert(*measured_hash); + + return ( + *measured_hash, + self.entries.get_mut(&measured_hash).unwrap(), + ); + } if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { let metrics = cosmic_text::Metrics::new(key.size, key.size * 1.2); @@ -416,7 +417,16 @@ impl Cache { to_shaping(key.shaping), ); - let _ = entry.insert(buffer); + let bounds = measure(&buffer); + + let _ = entry.insert(Entry { buffer, bounds }); + + if key.bounds != bounds { + let _ = self.measurements.insert( + Key { bounds, ..key }.hash(self.hasher.build_hasher()), + hash, + ); + } } let _ = self.recently_used.insert(hash); @@ -428,6 +438,8 @@ impl Cache { if self.trim_count > Self::TRIM_INTERVAL { self.entries .retain(|key, _| self.recently_used.contains(key)); + self.measurements + .retain(|key, _| self.recently_used.contains(key)); self.recently_used.clear(); @@ -448,4 +460,18 @@ struct Key<'a> { shaping: Shaping, } +impl Key<'_> { + fn hash(self, mut hasher: H) -> KeyHash { + self.content.hash(&mut hasher); + self.size.to_bits().hash(&mut hasher); + self.line_height.to_bits().hash(&mut hasher); + self.font.hash(&mut hasher); + self.bounds.width.to_bits().hash(&mut hasher); + self.bounds.height.to_bits().hash(&mut hasher); + self.shaping.hash(&mut hasher); + + hasher.finish() + } +} + type KeyHash = u64; diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 04943049..e0484239 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -348,7 +348,7 @@ fn to_shaping(shaping: Shaping) -> glyphon::Shaping { struct Cache { entries: FxHashMap, - bound_entries: FxHashMap, + measurements: FxHashMap, recently_used: FxHashSet, hasher: HashBuilder, } @@ -368,7 +368,7 @@ impl Cache { fn new() -> Self { Self { entries: FxHashMap::default(), - bound_entries: FxHashMap::default(), + measurements: FxHashMap::default(), recently_used: FxHashSet::default(), hasher: HashBuilder::default(), } @@ -385,11 +385,14 @@ impl Cache { ) -> (KeyHash, &mut Entry) { let hash = key.hash(self.hasher.build_hasher()); - if let Some(bound_hash) = self.bound_entries.get(&hash) { + if let Some(measured_hash) = self.measurements.get(&hash) { let _ = self.recently_used.insert(hash); - let _ = self.recently_used.insert(*bound_hash); + let _ = self.recently_used.insert(*measured_hash); - return (*bound_hash, self.entries.get_mut(&bound_hash).unwrap()); + return ( + *measured_hash, + self.entries.get_mut(&measured_hash).unwrap(), + ); } if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { @@ -416,7 +419,7 @@ impl Cache { let _ = entry.insert(Entry { buffer, bounds }); if key.bounds != bounds { - let _ = self.bound_entries.insert( + let _ = self.measurements.insert( Key { bounds, ..key }.hash(self.hasher.build_hasher()), hash, ); @@ -431,7 +434,7 @@ impl Cache { fn trim(&mut self) { self.entries .retain(|key, _| self.recently_used.contains(key)); - self.bound_entries + self.measurements .retain(|key, _| self.recently_used.contains(key)); self.recently_used.clear(); -- cgit From c8d79a5cd984c23862c184f437dcbe7639fe72c0 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 28 Jun 2023 00:45:41 +0200 Subject: Fix needless borrow in `iced_wgpu` and `iced_tiny_skia` --- tiny_skia/src/text.rs | 2 +- wgpu/src/text.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 22c17507..38e9bf3a 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -394,7 +394,7 @@ impl Cache { return ( *measured_hash, - self.entries.get_mut(&measured_hash).unwrap(), + self.entries.get_mut(measured_hash).unwrap(), ); } diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index e0484239..ae780c1e 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -391,7 +391,7 @@ impl Cache { return ( *measured_hash, - self.entries.get_mut(&measured_hash).unwrap(), + self.entries.get_mut(measured_hash).unwrap(), ); } -- cgit From 975eebfc6251539d154183f7d3cc69c41a96b156 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 28 Jun 2023 00:51:40 +0200 Subject: Retain measurements for text entries even if not directly used --- tiny_skia/src/text.rs | 6 ++++-- wgpu/src/text.rs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 38e9bf3a..8b249a8f 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -438,8 +438,10 @@ impl Cache { if self.trim_count > Self::TRIM_INTERVAL { self.entries .retain(|key, _| self.recently_used.contains(key)); - self.measurements - .retain(|key, _| self.recently_used.contains(key)); + self.measurements.retain(|key, value| { + self.recently_used.contains(key) + || self.recently_used.contains(value) + }); self.recently_used.clear(); diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index ae780c1e..b11b91c1 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -434,8 +434,10 @@ impl Cache { fn trim(&mut self) { self.entries .retain(|key, _| self.recently_used.contains(key)); - self.measurements - .retain(|key, _| self.recently_used.contains(key)); + self.measurements.retain(|key, value| { + self.recently_used.contains(key) + || self.recently_used.contains(value) + }); self.recently_used.clear(); } -- cgit From 00859c25f576b399871de74f0b9399d074deea35 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 28 Jun 2023 01:27:09 +0200 Subject: Retain text measurements as long as original entries --- tiny_skia/src/text.rs | 34 ++++++++++++++++++---------------- wgpu/src/text.rs | 35 ++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 8b249a8f..8f494650 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -388,14 +388,10 @@ impl Cache { ) -> (KeyHash, &mut Entry) { let hash = key.hash(self.hasher.build_hasher()); - if let Some(measured_hash) = self.measurements.get(&hash) { - let _ = self.recently_used.insert(hash); - let _ = self.recently_used.insert(*measured_hash); + if let Some(hash) = self.measurements.get(&hash) { + let _ = self.recently_used.insert(*hash); - return ( - *measured_hash, - self.entries.get_mut(measured_hash).unwrap(), - ); + return (*hash, self.entries.get_mut(hash).unwrap()); } if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { @@ -421,11 +417,19 @@ impl Cache { let _ = entry.insert(Entry { buffer, bounds }); - if key.bounds != bounds { - let _ = self.measurements.insert( - Key { bounds, ..key }.hash(self.hasher.build_hasher()), - hash, - ); + for bounds in [ + bounds, + Size { + width: key.bounds.width, + ..bounds + }, + ] { + if key.bounds != bounds { + let _ = self.measurements.insert( + Key { bounds, ..key }.hash(self.hasher.build_hasher()), + hash, + ); + } } } @@ -438,10 +442,8 @@ impl Cache { if self.trim_count > Self::TRIM_INTERVAL { self.entries .retain(|key, _| self.recently_used.contains(key)); - self.measurements.retain(|key, value| { - self.recently_used.contains(key) - || self.recently_used.contains(value) - }); + self.measurements + .retain(|_, value| self.recently_used.contains(value)); self.recently_used.clear(); diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index b11b91c1..1b94edf6 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -385,14 +385,10 @@ impl Cache { ) -> (KeyHash, &mut Entry) { let hash = key.hash(self.hasher.build_hasher()); - if let Some(measured_hash) = self.measurements.get(&hash) { - let _ = self.recently_used.insert(hash); - let _ = self.recently_used.insert(*measured_hash); + if let Some(hash) = self.measurements.get(&hash) { + let _ = self.recently_used.insert(*hash); - return ( - *measured_hash, - self.entries.get_mut(measured_hash).unwrap(), - ); + return (*hash, self.entries.get_mut(hash).unwrap()); } if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { @@ -415,14 +411,21 @@ impl Cache { ); let bounds = measure(&buffer); - let _ = entry.insert(Entry { buffer, bounds }); - if key.bounds != bounds { - let _ = self.measurements.insert( - Key { bounds, ..key }.hash(self.hasher.build_hasher()), - hash, - ); + for bounds in [ + bounds, + Size { + width: key.bounds.width, + ..bounds + }, + ] { + if key.bounds != bounds { + let _ = self.measurements.insert( + Key { bounds, ..key }.hash(self.hasher.build_hasher()), + hash, + ); + } } } @@ -434,10 +437,8 @@ impl Cache { fn trim(&mut self) { self.entries .retain(|key, _| self.recently_used.contains(key)); - self.measurements.retain(|key, value| { - self.recently_used.contains(key) - || self.recently_used.contains(value) - }); + self.measurements + .retain(|_, value| self.recently_used.contains(value)); self.recently_used.clear(); } -- cgit