memononen / nanovg

Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.
zlib License
5.06k stars 767 forks source link

Significant Font Texture Creation Overhead upon Transform #596

Open KTRosenberg opened 3 years ago

KTRosenberg commented 3 years ago

Hello, and thanks for this library! I’ve been trying to adapt it mostly for font rendering and manipulation, using the metal port.

I’m hoping you could suggest a fix for a pretty big performance issue I’m facing though: Every time I change nvg state such as the transform or font sizes, it seems that nvg will regenerate all of the font textures via fontstash, due to the checks in functions like the one in nvgText that flushes font textures. I am trying to zoom in/out, translate, and rotate select pieces of the ui based on continuous touch controls. What happens is that nvg ends up generating large textures per-frame, which causes a massive performance slow-down.

My current workaround is to implement a view matrix command directly to circumvent the immediate-mode transforms. The tradeoff is that I need to make the font resolution very high at start, ehich I imagine might come with its own tradeoffs.

I’d prefer to implement a change in nvg or fontstash more cleanly that doesn’t generate these alternative fonts per-frame...every single time the state changes.

Do you know how this could be done? Firstly, it looks like you only support 4 fonts at once, which is a bit low. Couldn’t we make it so mostnpossible font scales are generated at-once at program starr and just interpolate between them, lod-style? I spent a couple hours poring over the library code, but wasn’t sure how to do this since it looks like the textures are just rewritten over and over if anything changes in the dirty rect at all.

I’d also like sdf support, though I’m not sure how that would be integrated with your current system. This looks like a great opengl example: https://github.com/nyyManni/msdfgl MetalByExample has one old sdf example, but the reason I prefer nanovg is its typesetting/alignment API.

I hope we can work-out a cleaner, more scalable solution to this. Thanks for your time. (Also, thanks for libtess2!)