-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Glyph Atlas improvements #1923
Glyph Atlas improvements #1923
Conversation
Do glyphs ever get removed? How big is the performance benefit? |
They do not get removed - for most languages with only a few dozen glyphs this is probably desired anyway as the overhead of constantly removing and then adding them back is not worth it. I would like to benchmark this rather than just trusting my own perceived performance. For Asian character sets, I could see a potential rationale for refcounting the glyphs and removing the ones that aren't visible anymore. I have been testing around this location in Southern China: # 10.01/22.9452/113.1932 - set tilt to maximum to load as many tiles as possible, and scroll around. It does take a LOT of scrolling to get to 2048x2048, and even textures larger than that are considered safe for WebGL. To exceed the 1024x1024 limit, we would need to change how texture coordinates are packed in |
Would it be possible to refcount all glyphs added to the atlas and only cull unreferenced glyphs if the atlas would be in danger of overflowing? |
Yes, I think MRU-cache-like behavior would be optimal — remove the least used glyphs when atlas gets near overflowing. Might need some algorithmic effort though since you would have to use "holes" of different size in the atlas to place new glyphs. |
As for the PR — the code changes look great. Rebase this into a few clean commits with passing builds and we can merge — even with the overflowing problem, it's better than the current approach. |
1c3f5c6
to
d0c6b7b
Compare
Great! I squashed away the middle commits and rebased to master.. I'll open a separate issue to track follow on improvements to this. |
Looks good to me, @ansis want to give a final look? |
I understand there is a need for resizing of sprite atlas also - want me to open a PR for that? It would be pretty easy to do (at least up to 1024x1024 dimensions). |
@lucaswoj do you think have a separate glyphAtlas for each fonstack will cause problems with making text-font a data-driven property? |
Yes, it probably would. But I don't want to delay landing this bug fix for that reason. |
This will probably need to change to per-font glyph atlases with mapbox/DEPRECATED-mapbox-gl#4 if that makes a difference re data-driven styling. |
Upon further thought, I don't think this will affect data-driven styling. We render each symbol in a separate |
But this will change after we do #1898, right? |
If/when we use |
I did a quick benchmark of this... It's admittedly not great, but I cycled through a 5 glyph-heavy spots and let the map "quiesce" each time. tl;dr:
Master:This Branch: |
t.test('not enough room', function(t) { | ||
var bp = new BinPack(10, 10); | ||
t.deepEqual(bp.allocate(10, 10), {x: 0, y: 0, w: 10, h: 10 }, 'first 10x10 bin'); | ||
t.deepEqual(bp.allocate(10, 10), {x: -1, y: -1 }, 'not enough room'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be a followup task, but allocate
should return null
or undefined
rather than (-1, -1) to indicate failure.
I like it, let's merge and ticket followups. |
yeah, looks good! thanks for profiling |
Thanks! I'll cleanup & merge tonight.. |
d0c6b7b
to
4a28715
Compare
\o/ |
Improves but does not completely eliminate issues with glyph atlas overflow (#141)
GlyphSource
now manages multipleGlyphAtlases
, 1 per fontstack.GlyphAtlas
GL textures start out 128x128 and grow by power of 2 up to 1024x1024BinPack
now uses shelf best height fit algorithm, more efficient packing for things with similar heights