EGL calls are always proxied to main thread which breaks OFFSCREENCANVAS_SUPPORT with PROXY_TO_PTHREAD
When I use PROXY_TO_PTHREAD and OFFSCREENCANVAS_SUPPORT to run a SDL app, the canvas is transferred to the worker and then all operations on the canvas are done by that worker.
GL calls work, however, EGL calls are proxied to the main thread, which can no longer access the canvas and we see this error:
InvalidStateError: Failed to execute 'getContext' on 'HTMLCanvasElement': Cannot get context from a canvas that has transferred its control to offscreen.
I was able to get my app to work by simply removing lines containing if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread for all functions that start with _egl in the generated file, but I'm not sure this is a general solution, hence no PR.
Technically a duplicate of https://github.com/emscripten-core/emscripten/issues/8852 but it was marked as stale.
Since this issue will most likely share the same fate, here's my patch script:
sed -i '/^function _egl/ {
N
s/\(.*\)\n.*if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread.*/\1/
}' generated_js_file.js
I am running into a similar issue as i am exploring some EGL rendering.
First I am currently running with PROXY_TO_PTHREAD so all my logic is running on pthreads. All EGL and GL calls as i understand should be proxied to main thread. I am getting the context created fine via EGL class libegl.js but then i immediately crashing because GLctx is undefined in _emscripten_glGetString (not proxied to the main thread):
TypeError: Cannot read properties of undefined (reading 'getParameter')
at _emscripten_glGetString
I think libglemu.js could be missing proxying all these calls to the main thread where GLctx is defined.
Secondly, I attempted OFFSCREENCANVAS_SUPPORT but as @zb3 has pointed out the canvas is transferred to offscreen via transferControlToOffscreen at startup but then all the EGL calls are proxied back to the main thread and you then get InvalidStateError: Failed to execute 'getContext' on 'HTMLCanvasElement': Cannot get context from a canvas that has transferred its control to offscreen.
If i remove all the ENVIRONMENT_IS_PTHREAD in libegl.js when using OFFSCREENCANVAS_SUPPORT then things work smoothly.
So i think there could be a few things that could be going wrong and need fixed.
@juj @sbc100 @kripken. Any update on some of these issues that went stale and this PR that seemed reasonable but fell through https://github.com/emscripten-core/emscripten/pull/8901. One suggestion was why can't it check that canvas.controlTransferredOffscreen isn't true/set before proxying the function to the main thread? not sure if that is still the preferred approach and how that will work with __proxy: 'sync'
One suggestion was
why can't it check that canvas.controlTransferredOffscreen isn't true/set before proxying the function to the main thread?not sure if that is still the preferred approach and how that will work with__proxy: 'sync'
The Offscreen Framebuffer mechanism implements a proxying scheme like this. It is called "sync_on_current_webgl_context_thread", implementation is in src/lib/libhtml5_webgl.js.
It would be possible to implement a similar model for EGL, to proxy to the thread that holds the active EGL context.
Though that is serious development work, and I don't think there is anyone looking after developing/improving EGL support, beyond basic maintenance at this point.
Back when I held a day job at developing Emscripten, I did attempt to rewrite EGL in a manner that would resolve this issue. The PR is at https://github.com/emscripten-core/emscripten/pull/5580.
Though I was not able to complete the work, and moved on afterwards, so had to close it as unfinished.
If someone would like to have a stab at improving EGL support for multithreading, then possibly reviving the above PR could be the way to go.
That would help avoid needing to proxy EGL at all, I think.
If someone would like to have a stab at improving EGL support for multithreading, then possibly reviving the above PR could be the way to go.
Not sure i agree with the only way forward is significant work, which likely requires some with some deeper knowledge.
For now seems a very straight forward fix to do what was proposed in #5580,(plus a few other methods that need same treatment). That will at least get the combination of PROXY_TO_PTHREAD and OFFSCREENCANVAS_SUPPORT working. Otherwise the library is just stuck with an unsupported combination with the barrier being a full overhaul.
I get the ideal state of not needing to proxy at all, but a quick patch seems reasonable, especially if the ideal is going to be serious development work.