Fix excessive GlyphTypeface allocations in SystemFontCollection when FamilyName differs from requested
What does the pull request do?
Fixes a cache miss issue in SystemFontCollection that causes repeated GlyphTypeface allocations when the platform returns a typeface with a different FamilyName than requested.
What is the current behavior?
When requesting a font, the platform may return a typeface with a different FamilyName than requested. For example:
- Request "Segoe UI Variable Text" → returns typeface with
FamilyName = "Segoe UI Variable" - Request "Microsoft YaHei" → returns typeface with
FamilyName = "Microsoft YaHei UI"
The cache stores the typeface under the actual FamilyName, but subsequent lookups use the requested name. This causes cache misses on every request, creating new GlyphTypeface instances (with underlying HarfBuzzSharp.Face native resources) repeatedly.
This causes significant memory pressure during virtualized list/panel scrolling where the same font is requested many times per second.
What is the updated/expected behavior with this PR?
Typefaces are now cached under the requested family name key, ensuring subsequent lookups hit the cache. Repeated requests return the cached instance instead of allocating new ones.
How was the solution implemented (if it's not obvious)?
The fix ensures TryAddGlyphTypeface(familyName, key, glyphTypeface) is called with the requested familyName in both code paths:
- After
base.TryGetGlyphTypefacesucceeds - After
_platformImpl.TryCreateGlyphTypefacesucceeds
Checklist
- [x] Added unit tests (if possible)?
- [ ] Added XML documentation to any related classes?
- [ ] Consider submitting a PR to https://github.com/AvaloniaUI/avalonia-docs with user documentation
Breaking changes
None
Obsoletions / Deprecations
None
Have you tried https://github.com/AvaloniaUI/Avalonia/pull/19852 ?
Have you tried #19852 ?
I haven't tried, just briefly looked at the SystemFontCollection changes it doesn't seem to cache on both requested and actual font family?
I will have a deeper look tomorrow, but I guess you plan to merge this for 12.x release, and this problem seems to happen on 11.3 as well.
For example, scrolling in Fluent Search with Segoe UI Variable Text font causing RAM spike to 1gb+ very easily, with thousands of glyphs created.
This targets 11.3 https://github.com/AvaloniaUI/Avalonia/pull/20207
This targets 11.3 #20207
This one seems to fix the issue.
I might be missing something since #19852 is a big PR, but from what I can see it still has the bug: it caches the font under what the system returns ("Segoe UI Variable") rather than what was requested ("Segoe UI Variable Text"), so the next lookup misses the cache and creates a new allocation.
I haven't tested #19852 directly, so if you can confirm it actually fixes this we can close this. Otherwise, we could keep this open if you'd like a fix in master until #19852 is merged.