-
Notifications
You must be signed in to change notification settings - Fork 949
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
WebGL and wasm multithreading with web workers #2652
Comments
@expenses Do you think the Canvas.transferControlToOffscreen() workflow with a web-worker would be a small first step in that direction? I've recently added OffscreenCanvas support for the WebGL backend, but I didn't yet try if it works also out of the box from a web worker or if there are further adaptions required. It's not real multi-threading, but it can free up the main thread and avoid blocking one or the other. |
@haraldreingruber-dedalus interesting! I absolutely have not looked into this, no. I'm hoping that WebGPU will be stable before looking into this becomes a good idea 😉 But busy at the moment to do that now unfortunately |
It's multi-processes rather than multi-threads alas. trunk has a nice example of using web-workers with wasm. It seems to work pretty well from my experience - I've had no problems using webworkers to do a lot of I/O and preprocessing and just pop the small amount of data required for rendering the graphics over to the main process. A bit fiddly to set up but once set up I've had no additional issues with it over the months. I'm no game dev but you can see it in action at http://dotsama.world |
This is now solved and wgpu types are !Send !Sync on wasm. |
That prevents causing the bug, but doesn't resolve the need/desire to support multi-threading in WASM... Should that be set up as a separate issue? |
It's currently not possible. There's no way to send webgpu objects (or webgl objects) across threads. |
So this is something that seems pretty difficult to implement and the best bet is almost definitely to just wait until WebGPU becomes more widely available (I'm using WebXR which doesn't work with WebGPU yet).
In a couple of places we lie about wasm not having threads:
wgpu/wgpu-hal/src/gles/device.rs
Lines 1146 to 1150 in 9be974a
This is not true, as wasm has thread support via web workers, see https://web.dev/webassembly-threads/ https://rustwasm.github.io/docs/wasm-bindgen/examples/raytrace.html https://github.com/wngr/wasm-futures-executor etc.
There are a couple of limitations that make trying to use wgpu in a multthreaded way with the WebGL backend very difficult at the moment:
You can't access a lot of global properties in web workers. See https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope. This means that you can't run your main function in a web worker.
Any
wasm_bindgen
javascript values that are passed across the thread boundary such as theWebGl2RenderingContext
becomeundefined
.I did look into creating a more threadsafe device api that involved pushing tasks to a device in the main thread: https://gist.github.com/expenses/64a467b5f09462ad2441b9ceefe55b6f but I was not able to make this work fully.
It's possible that there are good ways around these issues and that it would end up being worthwhile. The idea of having a separate thread for WebGL rendering has been around for a while:
https://research.mozilla.org/2014/07/22/webgl-in-web-workers-today-and-faster-than-expected/
The text was updated successfully, but these errors were encountered: