WebAssembly 和 OpenGL - 单一上下文,多个输出(到 canvas)

WebAssembly & OpenGL - Single context, many output (to canvas)

(OpenGL/Emscripten 新手)

对于我正在构建的股票交易客户端应用程序,需要 40 多个打开的图表。其中大约 50% 处于某种 'Free draw' 状态,这意味着它们显示烛台以及其他 lines/arrows/images 等

在过去几个月尝试了很多选择之后,归根结底就是这样。

我 bootstrap 一个 WebAssembly 应用程序实例,并在其上调用函数让 C++ 使用 OpenGL 创建图表,映射到 WebGL(2)。一切正常。

我选择 (WebAssembly + OpenGL) -> Emscripten 的原因是因为有很多数字运算,而 c++ 也适合这项工作:)

问题是 WebGL 在 Chrome(59) 中的上下文限制约为 10。所以拥有 40-100 个 WebGL 上下文(图表)不是一个聪明的主意,而且我的直觉告诉我,拥有这么多几乎总是输出为静态图像的上下文是对 OpenGL 资源的浪费,除非你滚动图表等

有没有人有将单个 OpenGL 上下文渲染到随机 canvas 元素(或任何其他元素,并不重要)的良好经验?

我的想法如下:

  1. 在另一个线程中使用离屏 canvas 启动 c++ OpenGL, https://github.com/OleksandrChekhovskyi/emscripten-offscreen-canvas-test/blob/master/main.c#L35
  2. Javascript 告诉 c++ 渲染图形
  3. share/render OpenGL 后台缓冲区与 JS 通过共享 Uint8Array...SharedArrayBuffers 在 JS 工作线程和主(渲染)线程中被 C++ 填充 reads/transpiles 以将图像写入 canvas/html元素.

我似乎没有其他方法可以不创建许多 OpenGL 上下文。

问题是: 这样做性能如何,基本上将 OpenGL 缓冲区复制到 Javascript 等等?它偏离轨道很远吗?

谢谢

p.s。底部图表(带有红色波浪线)现在由 WebAssembly 和 OpenGL(GLFW 等)呈现

------ 更新 -----

选项 2:始终呈现相同的 Canvas,并使用 JS 将 canvas 的上下文复制到另一个 canvas(但如果上下文更新,它可能会被删除.. )

所以,在构建更多之后,我找到了一个快速的解决方案。

我只使用 1 个上下文 (GLFW) 并通过 JS 触发 C++ 函数来呈现图表,一旦完成,C++ 信号返回 JS 使用 EM_ASM_ 和相应的图表 ID 来呈现结果(图像)到达目的地 canvas 宽度:

chart.el.getContext('2d').drawImage(Module.canvas, 0, 0, width, height, 0, 0, width, height);

我测试了它,它工作得非常快,从 canvas 复制图像总是不到 1 毫秒。即使在 2K+ 图像的 4K 屏幕上。

而当Chrome完全支持离屏canvas时,我可以在web worker中加载WebAssembly渲染部分,完全绕过主线程,也许切换canvas上下文即时渲染到目的地 canvas。让它更快。但还不可能(再过几个月 :))

因此,除非浏览器支持 100 多个 webGL 上下文,否则我猜这将是不久的将来最快的解决方案。