(New to OpenGL / Emscripten)
For a stock trading client application I'm building there is the need of 40+ open charts. About 50% of them being in some sort of 'Free draw' state, meaning they show candlesticks plus other lines/arrows/images etc.
After trying a lot of options the last few months, here is what it comes down to.
I bootstrap a single WebAssembly app instance, and call functions on it to let C++ create charts with OpenGL, that maps to WebGL(2). It all works fine.
The reason I go for (WebAssembly + OpenGL) -> Emscripten, is because there is a lot of number crunching, and c++ suits that job fine as well :)
Problem is WebGL has a context limit of about 10 in Chrome(59). So having 40-100 WebGL context (Charts) is not a smart idea, also my guts tell me its a waste of OpenGL resources to have so many context that are almost always output as static images, unless you scroll the chart etc.
Does anyone have good experience with rendering a single OpenGL context to a random canvas element (or any other element, doesn't really matter)?
My thought are as follow:
I can't seem of any other way to not create many OpenGL contexts.
Question is: How performant will it be to do it like this, and basically copy over the OpenGL buffer to Javascript etc? It it far off track?
Thanks
p.s. bottom graphs (with red wave line) are now rendered by WebAssembly and OpenGL (GLFW etc)
------ UPDATE -----
Option 2: Always render to same Canvas, and use JS to copy context of canvas to another canvas (but it will probably be erased if the context updates..)
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.
WebAssembly is designed to be a complement to JavaScript, not a replacement. That means that it is not meant to be used independently, but rather to be used in conjunction with JavaScript. For example, you can compile WASM code to run alongside JS code.
By itself, WebAssembly cannot currently directly access the DOM; it can only call JavaScript, passing in integer and floating point primitive data types. Thus, to access any Web API, WebAssembly needs to call out to JavaScript, which then makes the Web API call.
WebAssembly is a low-level assembly language that can run in any major browser. It's designed to be fast, much faster than JavaScript, in order to handle the modern use cases of the web that require higher performance.
So, after building some more I found a fast solution.
Im using just 1 context (GLFW) and trigger a C++ function through JS to render the chart, once done c++ signals back to JS using EM_ASM_ with the corresponding Chart ID to render the result (image) to its destination canvas width:
chart.el.getContext('2d').drawImage(Module.canvas, 0, 0, width, height, 0, 0, width, height);
I tested it and it works really fast, copying over the image from the canvas is always less than 1ms. Even on a 4K screen with 2K+ images.
And when Chrome fully supports off-screen canvas, I can load the WebAssembly rendering part in a web worker and bypass the main thread in total, and maybe switch canvas contexts on the fly to render to the destination canvas instantly. making it even faster. But its not possible yet (few more months :))
So unless Browsers will support 100+ webGL contexts, this will be the fastest solution in the nearby future I guess.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With