Skip to content
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

SDL2 application will break when using pthreads #6009

Open
aliasdevelopment opened this issue Dec 31, 2017 · 17 comments
Open

SDL2 application will break when using pthreads #6009

aliasdevelopment opened this issue Dec 31, 2017 · 17 comments

Comments

@aliasdevelopment
Copy link

I have made a SDL2 application using the linker flag "-s USE_SDL=2" which works as expected.
I have made a ASIO application using https://github.com/emscripten-ports/asio which works as expected.
I have made a ASIO/pthread application with works as expected using the linker flags "-s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=4 -s PROXY_TO_PTHREAD=1"

But I can not merge these applications together. It seems as if USE_SDL and USE_PTHREADS/PROXY_TO_PTHREAD works against each other. I known that many older tutorials states that multithreading is not possible, but also knows that a lot of activities has been done to change this.

I get the following error when combining SDL and pthreads:
pthread-main.js onmessage() captured an uncaught exception: ReferenceError: screen is not defined

I can understand that I would make sense that the resources for rendering would only be available for the main thread, but pthread is missing some features/resources for SDL to possible.

Is it by design that USE_SDL and USE_PTHREADS/PROXY_TO_PTHREAD work against each other?
Would it be possible to use SDL from the main thread and still use pthreads for additional work?

@jakogut
Copy link
Contributor

jakogut commented Feb 27, 2019

I'm encountering this same issue. USE_SDL and USE_PTHREAD/PROXY_TO_PTHREAD seem to be incompatible.

@jakogut
Copy link
Contributor

jakogut commented Feb 27, 2019

Digging into the issue further, the stack trace shows:

ReferenceError: screen is not defined
    at Array.ASM_CONSTS (http://localhost:6931/test.js:1501:32)
    at _emscripten_asm_const_i (http://localhost:6931/test.js:1526:26)
    at _Emscripten_VideoInit (wasm-function[17363]:43)
    at _SDL_VideoInit (wasm-function[17486]:635)
    at _SDL_InitSubSystem (wasm-function[17481]:203)
    at _SDL_Init (wasm-function[17612]:3)
    at _main (wasm-function[310]:133)
    at Module._main (http://localhost:6931/test.js:11418:75)
    at ___call_main (http://localhost:6931/test.js:1877:24)
    at ___emscripten_thread_main (wasm-function[18150]:23)
onmessage @ test.worker.js:181

Looking at the Emscripten port of SDL2, video/emscripten/SDL_emscriptenvideo.c:145:

mode.w = EM_ASM_INT_V({
    return screen.width;
}); 

mode.h = EM_ASM_INT_V({
    return screen.height;
}); 

So it seems that the Emscripten_VideoInit function tries to get the screen dimensions from the JS object screen, but the object isn't being proxied to the new thread main is running in.

@jakogut
Copy link
Contributor

jakogut commented Feb 27, 2019

I've resolved the issues with proxying EM_ASM calls in the sdl2 port (my fixes are available at https://github.com/jakogut/SDL2/tree/sdl2-proxy-pthread-fixes), now I'm getting:

TypeError: Cannot read property 'getContext' of undefined
    at Object.createContext (http://localhost:6931/test.js:6608:19)
    at _eglCreateContext (http://localhost:6931/test.js:6793:24)
    at _SDL_EGL_CreateContext (wasm-function[17463]:337)
    at _Emscripten_GLES_CreateContext (wasm-function[17453]:12)
    at _SDL_GL_CreateContext (wasm-function[17025]:143)
    at _GLES2_CreateRenderer (wasm-function[17017]:489)
    at _SDL_CreateRenderer (wasm-function[17662]:303)
    at _main (wasm-function[388]:376)
    at Module._main (http://localhost:6931/test.js:12316:33)
    at ___call_main (http://localhost:6931/test.js:2000:24)

Doing a little digging around seems to indicate that the EGL code at src/library_egl.js is unable to access the canvas object, probably because those calls need proxied as well. @kripken, can you shed any light on this issue?

@kripken
Copy link
Member

kripken commented Feb 27, 2019

This may be stuff that has not been proxied yet, yes - @juj can confirm.

@stale
Copy link

stale bot commented Feb 27, 2020

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.

@stale stale bot added the wontfix label Feb 27, 2020
@kripken
Copy link
Member

kripken commented Feb 27, 2020

Looks like the PR for this is #9336 - would be good to get that landed. @jakogut - is there something blocking it?

@stale stale bot removed the wontfix label Feb 27, 2020
@jakogut
Copy link
Contributor

jakogut commented Mar 10, 2020

@kripken No blockers, just have to address the feedback given. I can look at doing that later this week.

@Hossein-Noroozpour
Copy link

Hi, is there any update for this issue?

@janpaul123
Copy link

For those coming across this, it looks like emscripten-ports/SDL2#127 is still open.

@SoapyMan
Copy link

SoapyMan commented Apr 10, 2021

So question is... when? 😅

@zengming00
Copy link

I ran into the same problem when I added network support to a working SDL2 project
#10665
#13755

@puzzlepaint
Copy link

I ran into this issue as well and would add +1 for merging emscripten-ports/SDL2#127 which seems to fix it.

@flyingllama87
Copy link

+1 running into this issue.

@HarrievG
Copy link

HarrievG commented Nov 30, 2021

+1 ,
But , retrieving the size from screen can be replaced with just Module['canvas'].width/height
-edit-
There are way more problems in emscripten land to be fixed than this one.

Besides the screensize, mouse locking crashes, and all of the EGL calls proxy to main, which makes using EGL on a thread not really feasible. (Fixable by removing every async property from EGL.js lib)
Besides the EGL issues, openAL is totally unusable since that proxies everything. Proxy can be removed from some calls, but not all as is with the egl case.

Long story short, emscripten is not ready for production level threading work that needs to be performance critical.
Without significantly editing the js libraries,the best bet is to only use calls in thread things that are not in the emscripten libraries.
Or, to use asyncify smartly and make it work on an single thread.

@connorjclark
Copy link
Contributor

connorjclark commented Apr 12, 2022

There is a fix available for using PROXY_TO_PTHREAD with SDL, if you are willing to use a fork and hack a bit. @Daft-Freak did this amazing work. here's how to use it today, in case this is a blocker for you:

  1. open your emscripten installation tools/ports/sdl2.py
  2. set TAG to a93fc312a87cc2a94ce19bedec8ba846a6ee50e4
  3. set HASH to cc47eca26d647d4aee2d4fb2e8565a3bad490dcf3a364cca139e8cda275c0a2d0d60aa198164b3f2d03111df06c836d22158c5764b204d8fab2af98292e40de7
  4. change L23 to use https://github.com/Daft-Freak/SDL/archive/
  5. add SDL_list.c to L31
  6. delete your cached libsdl library, and run embuilder build sdl2
  7. in cache/ports/sdl2/SDL-a93fc312a87cc2a94ce19bedec8ba846a6ee50e4/src/audio/emscripten/SDL_emscriptenaudio.c change L259 to use MAIN_THREAD_EM_ASM_INT

After that, you should be able to run SDL compiled with PROXY_TO_PTHREAD and OFFSCREENCANVAS_SUPPORT.

Although, I have noticed some issues re: audio locking the main thread if you have MAIN_THREAD_* proxy calls.

@magne4000
Copy link

magne4000 commented Jun 20, 2023

Is this still an issue since libsdl-org/SDL#5365 has been merged?

@connorjclark
Copy link
Contributor

Fixing your link: libsdl-org/SDL#5365

I believe libsdl-org/SDL#6142 is what may have resolved this, which I think incorporated the changes I suggested to the author in my previous comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.