LibGfx: Cache code point -> glyph ID lookups in TypefaceSkia

This brings back the optimization we had in the old OpenType
implementation where we cache lookup tables for code point / glyph ID
mappings.

This noticeably improves performance on https://tailwindcss.com/ by
knocking an 8% profile item down to 0.2%. :^)
This commit is contained in:
Andreas Kling 2024-09-10 10:02:27 +02:00 committed by Andreas Kling
parent 2aa07e0e65
commit 84ec690d90
Notes: github-actions[bot] 2024-09-10 09:04:43 +00:00
2 changed files with 45 additions and 1 deletions

View file

@ -82,7 +82,36 @@ u16 TypefaceSkia::units_per_em() const
u32 TypefaceSkia::glyph_id_for_code_point(u32 code_point) const
{
return impl().skia_typeface->unicharToGlyph(code_point);
return glyph_page(code_point / GlyphPage::glyphs_per_page).glyph_ids[code_point % GlyphPage::glyphs_per_page];
}
TypefaceSkia::GlyphPage const& TypefaceSkia::glyph_page(size_t page_index) const
{
if (page_index == 0) {
if (!m_glyph_page_zero) {
m_glyph_page_zero = make<GlyphPage>();
populate_glyph_page(*m_glyph_page_zero, 0);
}
return *m_glyph_page_zero;
}
if (auto it = m_glyph_pages.find(page_index); it != m_glyph_pages.end()) {
return *it->value;
}
auto glyph_page = make<GlyphPage>();
populate_glyph_page(*glyph_page, page_index);
auto const* glyph_page_ptr = glyph_page.ptr();
m_glyph_pages.set(page_index, move(glyph_page));
return *glyph_page_ptr;
}
void TypefaceSkia::populate_glyph_page(GlyphPage& glyph_page, size_t page_index) const
{
u32 first_code_point = page_index * GlyphPage::glyphs_per_page;
for (size_t i = 0; i < GlyphPage::glyphs_per_page; ++i) {
u32 code_point = first_code_point + i;
glyph_page.glyph_ids[i] = impl().skia_typeface->unicharToGlyph(code_point);
}
}
String TypefaceSkia::family() const

View file

@ -38,6 +38,21 @@ private:
ReadonlyBytes m_buffer;
unsigned m_ttc_index { 0 };
// This cache stores information per code point.
// It's segmented into pages with data about 256 code points each.
struct GlyphPage {
static constexpr size_t glyphs_per_page = 256;
u16 glyph_ids[glyphs_per_page];
};
// Fast cache for GlyphPage #0 (code points 0-255) to avoid hash lookups for all of ASCII and Latin-1.
OwnPtr<GlyphPage> mutable m_glyph_page_zero;
HashMap<size_t, NonnullOwnPtr<GlyphPage>> mutable m_glyph_pages;
[[nodiscard]] GlyphPage const& glyph_page(size_t page_index) const;
void populate_glyph_page(GlyphPage&, size_t page_index) const;
};
}