Change summary
crates/gpui/src/app.rs | 8 ++++++
crates/gpui/src/platform.rs | 1
crates/gpui/src/platform/mac/metal_atlas.rs | 29 +++++++++++++++++++++++
crates/gpui/src/platform/test/window.rs | 7 +++++
crates/theme/src/settings.rs | 1
5 files changed, 46 insertions(+)
Detailed changes
@@ -447,6 +447,14 @@ impl App {
self.pending_effects.push_back(Effect::RefreshWindows);
}
+ /// Clears cache of rasterized glyphs.
+ pub fn clear_glyph_atlases(&mut self) {
+ if let Some(window) = self.windows.values().find_map(|window| window.as_ref()) {
+ let atlas = window.platform_window.sprite_atlas();
+ atlas.clear_glyphs();
+ }
+ }
+
pub(crate) fn update<R>(&mut self, update: impl FnOnce(&mut Self) -> R) -> R {
self.start_update();
let result = update(self);
@@ -743,6 +743,7 @@ pub(crate) trait PlatformAtlas: Send + Sync {
build: &mut dyn FnMut() -> Result<Option<(Size<DevicePixels>, Cow<'a, [u8]>)>>,
) -> Result<Option<AtlasTile>>;
fn remove(&self, key: &AtlasKey);
+ fn clear_glyphs(&self);
}
struct AtlasTextureList<T> {
@@ -57,6 +57,35 @@ impl PlatformAtlas for MetalAtlas {
}
}
+ fn clear_glyphs(&self) {
+ let mut lock = self.0.lock();
+ let mut tile_ids_by_texture = FxHashMap::default();
+ lock.tiles_by_key.retain(|key, tile| {
+ if matches!(key, AtlasKey::Glyph(_)) {
+ tile_ids_by_texture
+ .entry(tile.texture_id)
+ .or_insert_with(Vec::new)
+ .push(tile.tile_id);
+ false
+ } else {
+ true
+ }
+ });
+
+ for (texture_id, tile_ids) in tile_ids_by_texture {
+ let texture_slot = &mut lock.monochrome_textures.textures[texture_id.index as usize];
+ if let Some(texture) = texture_slot {
+ texture.live_atlas_keys -= tile_ids.len() as u32;
+ if texture.is_unreferenced() {
+ texture_slot.take();
+ lock.monochrome_textures
+ .free_list
+ .push(texture_id.index as usize);
+ }
+ }
+ }
+ }
+
fn remove(&self, key: &AtlasKey) {
let mut lock = self.0.lock();
let Some(id) = lock.tiles_by_key.get(key).map(|v| v.texture_id) else {
@@ -359,4 +359,11 @@ impl PlatformAtlas for TestAtlas {
let mut state = self.0.lock();
state.tiles.remove(key);
}
+
+ fn clear_glyphs(&self) {
+ let mut state = self.0.lock();
+ state
+ .tiles
+ .retain(|key, _| !matches!(key, AtlasKey::Glyph(_)))
+ }
}
@@ -722,6 +722,7 @@ pub fn adjust_buffer_font_size(cx: &mut App, mut f: impl FnMut(&mut Pixels)) {
f(&mut adjusted_size);
cx.set_global(BufferFontSize(clamp_font_size(adjusted_size)));
+ cx.clear_glyph_atlases();
cx.refresh_windows();
}