fix(text): don't reload cache every redraw

I have >1000 fonts installed. COSMIC has always been somewhat laggy for me, but I had assumed it was just like that for everyone, or was the fault of my T480s. Eventually, when trying to diagnose some hitching, I ended up discovering that cosmic-launcher was consuming on average ~5% total CPU over time, which led me to discover that it was fetching all the fonts from disk and software rendering the fonts, every redraw, causing the high cpu usage *and* the stutters (as a result of hammering disk I/O). Oops.

The fix is simple: just persist the cache across redraws.
This commit is contained in:
Gavin John 2026-05-29 10:47:32 -07:00 committed by Michael Murphy
parent 9c748f1656
commit 590e093086
2 changed files with 12 additions and 4 deletions

View file

@ -15,6 +15,7 @@ use std::collections::hash_map;
pub struct Pipeline {
glyph_cache: GlyphCache,
cache: RefCell<Cache>,
swash_cache: cosmic_text::SwashCache,
}
impl Pipeline {
@ -22,6 +23,7 @@ impl Pipeline {
Pipeline {
glyph_cache: GlyphCache::new(),
cache: RefCell::new(Cache::new()),
swash_cache: cosmic_text::SwashCache::new(),
}
}
@ -54,6 +56,7 @@ impl Pipeline {
draw(
font_system.raw(),
&mut self.glyph_cache,
&mut self.swash_cache,
paragraph.buffer(),
position,
color,
@ -81,6 +84,7 @@ impl Pipeline {
draw(
font_system.raw(),
&mut self.glyph_cache,
&mut self.swash_cache,
editor.buffer(),
position,
color,
@ -142,6 +146,7 @@ impl Pipeline {
draw(
font_system,
&mut self.glyph_cache,
&mut self.swash_cache,
&entry.buffer,
Point::new(x, y),
color,
@ -165,6 +170,7 @@ impl Pipeline {
draw(
font_system.raw(),
&mut self.glyph_cache,
&mut self.swash_cache,
buffer,
position,
color,
@ -183,6 +189,7 @@ impl Pipeline {
fn draw(
font_system: &mut cosmic_text::FontSystem,
glyph_cache: &mut GlyphCache,
swash_cache: &mut cosmic_text::SwashCache,
buffer: &cosmic_text::Buffer,
position: Point,
color: Color,
@ -192,8 +199,6 @@ fn draw(
) {
let position = position * transformation;
let mut swash = cosmic_text::SwashCache::new();
for run in buffer.layout_runs() {
for glyph in run.glyphs {
let physical_glyph = glyph.physical(
@ -205,7 +210,7 @@ fn draw(
physical_glyph.cache_key,
glyph.color_opt.map(from_color).unwrap_or(color),
font_system,
&mut swash,
swash_cache,
) {
let pixmap = tiny_skia::PixmapRef::from_bytes(
buffer,