-
Notifications
You must be signed in to change notification settings - Fork 45
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
ImGuiIntegration: use single-channel format for font texture atlas, if available #115
base: master
Are you sure you want to change the base?
Conversation
48d7bee
to
2e45f10
Compare
This may seem like a silly optimization, but for UI that supports things like Chinese characters, you quickly reach an atlas size of 100+MB. Also reduces bandwidth by a little bit, but not sure if font texture sampling is really a bottleneck for UI rendering. |
Mainly to test that font atlas upload and sampling works, especially when using single-channel format + swizzling on OpenGL and GLES3
2e45f10
to
978dda8
Compare
Slight differences on GLES, could be swiftshader?
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #115 +/- ##
==========================================
+ Coverage 78.18% 78.32% +0.14%
==========================================
Files 22 22
Lines 1022 1029 +7
==========================================
+ Hits 799 806 +7
Misses 223 223 ☔ View full report in Codecov by Sentry. |
Ha, few days ago I was actually thinking about doing the exact opposite for the Ui library... "if ImGui can get away with using a RGBA atlas for font glyphs, maybe the extra memory usage is not so bad in practice nowadays and I could just opt-in to use a RGBA format if people want to use emoji fonts?" The patch makes sense to me (and thanks for the test as well), but I have some questions:
|
ImGui has no support for color fonts -
That's a good question. Haven't found anything from a cursory glance. From what I understand
Yeah I didn't like that too much since it means needing a custom shader instead of using the built-in Flat. But it would be a somewhat sane alternative. Personally I'm OK with leaving out GLES2/WebGL from this optimization. 🤷
This briefly crossed my mind as well, it would definitely be useful to avoid running into texture size limits for the atlas. Our ImGui glyph atlas is already 8k by 4k, not hard to imagine going beyond 8k width if you include some exotic script support. |
I'm vaguely aware of a "relatively recent" ImGui feature that supports SVG fonts, by calling into lunasvg / plutosvg to turn those into raster: ocornut/imgui@2ad8c60 Never used it personally, don't know any details, I just know it exists. Maybe it's a completely different code path that isn't affected by this change, maybe it's even something that would need additional changes in the integration lib for proper support (tangentially, I have WIP What I want to say -- if SVG fonts work already with the integration lib in some way, I fear of breaking existing use cases if I merge this PR as-is. Then there would need to be some kind of an option where one can control the channel count during context creation, and it would possibly need to be opt-in instead of opt-out. If SVG fonts don't work, and would need extra changes to work, then merging the PR as-is would be fine I think.
Yeah, true. And
Quite a few times I ran into a problem where a generic asset loaded wrong because a monochrome PNG got optimized to single-channel, and the only portable solution was to manually expand or fiddle with plugin-specific config to get a RGBA again. So adding such an option as a builtin flag, to this shader and all others as well, makes complete sense. Or there's mosra/magnum#569 which could be finally kicked off by this (though such an implementation would make the eventual wgpu/vulkan backend harder).
In the |
Hum, I definitely misread the imgui code, good thing you poked a bit more at this 😅 The FAQ even explicitly mentions color fonts. Luckily,
That one is infamous. Up until recently we displayed red thumbnails for monochrome PNGs 😹
Haven't really looked into that, but from what I understand there's only one atlas. So you probably have to fix up glyph UVs manually after splitting the atlas? The texture ID is set on the atlas, so I suppose sneaking the z-slice in there won't work. |
cd92508
to
ead3e8a
Compare
I'll merge as soon as I get the time, thank you. My only remaining question is whether there are any consequences to font loading that would be worth putting into the docs? Such as making sure color fonts are loaded early enough for the texture format to be correct, etc. |
You have a great talent of finding bugs by asking seemingly innocent questions 😄 The official freetype atlas builder sets |
On OpenGL and GLES3 we can use a single-channel red texture together with 111r-swizzling, instead of wasting 3 bytes per pixel on RGB channels that get set to 1 anyway. Also adds a test for text rendering, mainly to test that the atlas uploading + sampling works for both configurations.
There's also a drive-by fix for an MSVC warning 🍒