Skip to content

Calling into worker via embind with PROXY_TO_PTHREAD=1 attempts to call GL functions on the main thread #23666

@sasmaster

Description

@sasmaster

Hi.
I am writing a rendering app. I need it to run in a secondary thread in order not to interfere with UI.
My linker config is as follow:

-sINITIAL_MEMORY=134217728 -sMAX_WEBGL_VERSION=2 -sWASM=1 -sFULL_ES3 -sASYNCIFY -sPROXY_TO_PTHREAD=1 -sOFFSCREEN_FRAMEBUFFER=1 -sOFFSCREENCANVAS_SUPPORT=1 -sNO_EXIT_RUNTIME=1 -lembind -sENVIRONMENT=web,worker -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=8 -lpthread -msimd128 -matomics -mbulk-memory
Inside my app I am creating webgl2 context with the following attributes:

attrs.explicitSwapControl =  EM_TRUE;
attrs.renderViaOffscreenBackBuffer = EM_FALSE;
attrs.enableExtensionsByDefault = EM_TRUE;
attrs.premultipliedAlpha = EM_TRUE;
attrs.preserveDrawingBuffer = EM_FALSE;
attrs.proxyContextToMainThread = EMSCRIPTEN_WEBGL_CONTEXT_PROXY_DISALLOW;

I am not sure about the second one but it is probably not related to my problem.
Now, I have a function called Init() and Run(). Init() creates webgl context and makes it current. Run() creates a rendering stuff and launches render loop with emscripten_set_main_loop_arg(&Render, this, 0, 1);

If Run() gets called within the app, like this:

  int main(int argc, char* argv[])
{
	if(!app.Init())
	{
		return EXIT_FAILURE;
	}
	app.Run();
	return EXIT_SUCCESS;
}

It all works, Stuff is rendering.
But,I want this function to be called via button press on the front end. For this I am using embind to expose the function to JS.
If I call Run() via JS it looks like the webgl context gets lost. Also in the callstack I can see that the code tries to execute the function on the main thread. And my context lives in the worker thread.

WasmApp.js:4923 Uncaught TypeError: Cannot read properties of undefined (reading 'bindFramebuffer')
    at _glBindFramebuffer (http://localhost:5500/WasmApp.js:4923:9)
    at imports.<computed> (http://localhost:5500/WasmApp.js:3042:20)
    at WasmApp.wasm._do_call (http://localhost:5500/WasmApp.wasm:wasm-function[1417]:0x6fd54)
    at WasmApp.wasm.maybe_call_on_current_thread (http://localhost:5500/WasmApp.wasm:wasm-function[1416]:0x6f037)
    at WasmApp.wasm.do_dispatch_to_thread (http://localhost:5500/WasmApp.wasm:wasm-function[1412]:0x6ebd2)
    at WasmApp.wasm.emscripten_async_run_in_main_thread (http://localhost:5500/WasmApp.wasm:wasm-function[1418]:0x71cae)
    at WasmApp.wasm.emscripten_async_run_in_main_runtime_thread_ (http://localhost:5500/WasmApp.wasm:wasm-function[1423]:0x725f7)
    at WasmApp.wasm.glBindFramebuffer (http://localhost:5500/WasmApp.wasm:wasm-function[1260]:0x6172f)
    at WasmApp.wasm.WebApp::Run() (http://localhost:5500/WasmApp.wasm:wasm-function[1238]:0x5f746)
    at WasmApp.wasm.emscripten::internal::MethodInvoker<emscripten::internal::rvp::default_tag, void (WebApp::*)(), void, 

From what I understood in the docs, embind should work fine with worker proxing function calls into the worker thread. But here it doesn't look like that. It seems like embind is attempting to execute the function on the main thread, which is not what I want.
Can someone explain what's going on here? And if embind is not supposed to work in this mode, what is the alternative for setting a communication between this wasm app and JS?
Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions