nanovg sample running in emscripten/WebGL

1,129 views
Skip to first unread message

Floh

unread,
Aug 29, 2014, 5:17:01 PM8/29/14
to emscripte...@googlegroups.com
I spent a couple hours to integrate nanovg (https://github.com/memononen/nanovg) into the oryol engine, and it runs pretty well through emscripten (number of GL calls is pretty high):


nanovg (almost) didn't require any changes, one fix I did was to remove the fairly excessive calls to glGetError since this killed performance in Chrome, and non-power-of-2 textures didn't render because the GL_TEXTURE_WRAP_S/T modes need to be set to GL_CLAMP_TO_EDGE.

Another thing I had to fix in the demo scene was resource loading (fonts and images), nanovg either can load directly from file via fopen/fread/fclose, but also can create from file-data in memory. I used the create-from-memory functions and asynchronous resource loading to create fonts and images deferred, and skipped parts of the demo scene rendering if a required resource isn't available yet.

I think a really useful optimization for nanovg would be to try reducing the number of GL calls.

Cheers :)
-Floh.

Alon Zakai

unread,
Aug 29, 2014, 9:22:47 PM8/29/14
to emscripte...@googlegroups.com
Nice, that runs really well!

I wonder if someone wrapped NanoVG with the WebIDL binder or embind, so it could be used from normal JS, if normal web devs would find that useful. It provides a similar API to 2D canvas, but GL-based so it could be much faster. Basically it could let them write GL-accelerated UIs in a pretty simple way?

- Alon



--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Anthony Liot

unread,
Aug 30, 2014, 5:37:24 AM8/30/14
to emscripte...@googlegroups.com
Hi Floh,

It's working really nice, but not on iOS8.

I add the console résult on iOS8, may be can help.

Anyway, good work !!!

Tony

=> App::StartMainLoop()
App::onFrame(): Switching to app state 'EnqueuePreload'
App::onFrame(): Switching to app state 'Preloading'
App::onFrame(): Switching to app state 'Init'
oryol assert: cond='EMSCRIPTEN_RESULT_SUCCESS == res'
msg='none'
file='/Users/floh/projects/oryol/code/Modules/Render/emsc/emscDisplayMgr.cc'
line='52'
func='void Oryol::Render::emscDisplayMgr::SetupDisplay(const Oryol::Render::RenderSetup &)'
trap!



Floh

unread,
Aug 30, 2014, 5:38:48 AM8/30/14
to emscripte...@googlegroups.com
I haven't played around much yet with calling into emscripten code from JS, but the nanovg API is very simple and pure C, so it should be possible:

- the context is actually an pointer, but never used as a pointer, only as an opaque handle
- images and fonts have normal int's as id
- the image and font creation functions could be a bit tricky, they either take a filename, or a memory pointer/size pair

Vanilla nanovg at first had shockingly bad perf on Chrome, but that turned out to be the many glGetError calls, also the test scene currently has 538 draw calls and 6182 GL calls, which seems a bit heavy, hopefully this can be reduced with a bit of optimization work, I'll write a few nanovg tickets today and step a bit through the code to understand it better.

Cheers,
-Floh
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.

Floh

unread,
Aug 30, 2014, 5:41:27 AM8/30/14
to emscripte...@googlegroups.com
Oh, I haven't tested yet on iOS8, this looks like the display setup fails very ealry, it's requesting a 24 bit RGB color and 24/8 depth/stencil render target, may be the iOS8 Safari WebGL implementation doesn't like that.

Thanks!
-Floh.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.

Floh

unread,
Aug 30, 2014, 6:11:37 PM8/30/14
to emscripte...@googlegroups.com
I managed to reduce the calls into WebGL in the nanovg test scene from 6.2k down to 2.6k by merging the 13 glUniform calls into one (this happens only in the GLES2 and GL2 render path, the others use uniform buffer objects). I have updated the web demo and will prepare an upstream pull request for nanovg.

There are also blocks of adjacent draw calls which could probably be merged. I'll probably look into this next.

BTW, the Firefox canvas inspector comes in very handy for looking at the GL call sequence, much less hassle to setup/start then other GL tracing tools :)

Cheers,
-Floh.
Reply all
Reply to author
Forward
0 new messages