Skip to content

Skip Skrifa lookup for cached outlines#543

Open
valadaptive wants to merge 3 commits intolinebender:mainfrom
valadaptive:fast-draw-lookup
Open

Skip Skrifa lookup for cached outlines#543
valadaptive wants to merge 3 commits intolinebender:mainfrom
valadaptive:fast-draw-lookup

Conversation

@valadaptive
Copy link
Contributor

Stacked on #542; the last commit is the new one.

Previously, drawing a glyph performed the following lookups, in order:

  1. A skrifa::BitmapStrikes lookup
  2. If that fails (which it probably will, because most fonts are not bitmaps), a skrifa::ColorGlyphCollection lookup
  3. If that fails (which it probably will, because most fonts are not COLR), a skrifa::OutlineGlyphCollection lookup
  4. An outline cache lookup

The Skrifa lookups are somewhat slow. I believe they perform a binary search on the raw font data internally.

We can optimize this by:

  • Checking for an outline glyph first, since most glyphs are outline glyphs
  • Checking the outline cache without ever going through Skrifa

To do this, I refactored the prepare_[kind]_glyph functions to return an Option; this allows them to perform the requisite Skrifa "does the glyph exist" lookups themselves. The prepare_outline_glyph function can then check the outline cache itself, before doing a potentially-expensive Skrifa lookup. I also changed the outline cache to store Option<OutlinePath>, so we can store absent glyphs in the cache too.

Combined with the changes from #542, this is a ~10% speedup above current main, at least on my machine.

@valadaptive valadaptive requested review from conor-93 and taj-p February 8, 2026 21:30
Copy link
Contributor

@conor-93 conor-93 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find! I didn't realise the Skrifa glyph lookup was that slow.

A concern I have is that there is a behavioural change here too; I think we are selecting outline glyphs even if fonts have both outline and COLR, or outline and bitmap. The recommended behaviour seems to be selecting bitmap before outline.

This order of precedence matters in a few cases:

  • Bitmaps being used to express glyphs when font size is very small (ref)
  • Fonts which ship with outline as a backup for renderers that don't support COLR or Bitmap (you'd still want to render the bitmap if you can, and we can)

I don't think we can avoid doing the Skrifa lookup to see if a glyph has bitmap data because of this (I could be missing something though!). I do wonder if it's something that could be optimised within Skrifa though (like marking a font as being purely outline, or bitmap, or COLR once it's first loaded), but that would require considerably more work than what's in this PR.

Alternately, I think we could we treat the outline cache as an indicator that, given a font ID and glyph ID, we should be using the outline variant of that glyph (COLR/bitmap do not exist), as we would have only populated it in the prepare_outline_glyph path. So, we could skip the Skrifa lookup IFF we have a cache hit, and go straight to prepare_outline_glyph, and still get the performance win for what I imagine would be most iterations (outline glyph, cache hit).

Copy link
Contributor

@taj-p taj-p left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll defer my review to @conor-93

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments