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

Emscripten: re-enable the -pthread compiler flag #9426

Merged
merged 4 commits into from
Jan 11, 2025

Conversation

oleg-derevenetz
Copy link
Collaborator

@oleg-derevenetz oleg-derevenetz commented Jan 8, 2025

emscripten-core/emscripten#23094 was merged recently, but there is no new release with these changes yet (and accordingly, there is no new docker image), so I decided to apply a temporary patch for now using our CI (it will be removed when the new Emscripten docker image will be released).

  • It works in general;

  • Background music playback is now resumed correctly (more or less, see below);

  • "Feeding" the player with musical chunks from MIDI/MP3/OGG decoders by SDL_mixer is still performed in the main thread, and not in the background threads, like it's done on other platforms, so the background music still chokes when the main thread is busy with something;

  • OGG backend periodically crashes like this:

    res0.c:821 Uncaught RuntimeError: divide by zero
      at fheroes2.wasm.res2_inverse (res0.c:821:51)
      at fheroes2.wasm.mapping0_inverse (mapping0.c:750:5)
      at fheroes2.wasm.vorbis_synthesis (synthesis.c:88:10)
      at fheroes2.wasm._fetch_and_process_packet (vorbisfile.c:706:15)
      at fheroes2.wasm.ov_read_filter (vorbisfile.c:1977:15)
      at fheroes2.wasm.ov_read (vorbisfile.c:2097:10)
      at fheroes2.wasm.OGG_GetSome (music_ogg.c:390:19)
      at fheroes2.wasm.music_pcm_getaudio (music.c:302:24)
      at fheroes2.wasm.OGG_GetAudio (music_ogg.c:442:12)
      at fheroes2.wasm.music_mixer (music.c:364:24)
    

    or like this:

    res0.c:840 Uncaught RuntimeError: memory access out of bounds
      at fheroes2.wasm.res2_inverse (res0.c:840:33)
      at fheroes2.wasm.mapping0_inverse (mapping0.c:750:5)
      at fheroes2.wasm.vorbis_synthesis (synthesis.c:88:10)
      at fheroes2.wasm._fetch_and_process_packet (vorbisfile.c:706:15)
      at fheroes2.wasm.ov_read_filter (vorbisfile.c:1977:15)
      at fheroes2.wasm.ov_read (vorbisfile.c:2097:10)
      at fheroes2.wasm.OGG_GetSome (music_ogg.c:390:19)
      at fheroes2.wasm.music_pcm_getaudio (music.c:302:24)
      at fheroes2.wasm.OGG_GetAudio (music_ogg.c:442:12)
      at fheroes2.wasm.music_mixer (music.c:364:24)
    
  • MP3 backend, however, seems to work correctly, except for spamming to the browser console by messages like this when the music is resumed from a previously remembered position (but resume mostly still works):

    fheroes2.js:2459 Note: Illegal Audio-MPEG-Header 0xf00ff082 at offset 182498.
    fheroes2.js:2459 Note: Trying to resync...
    fheroes2.js:2459 Note: Illegal Audio-MPEG-Header 0xf00ff082 at offset 181538.
    fheroes2.js:2459 Note: Skipped 490 bytes in input.
    fheroes2.js:2459 Note: Trying to resync...
    fheroes2.js:2459 
    fheroes2.js:2459 Warning: Big change from first (MPEG version, layer, rate). Frankenstein stream?
    fheroes2.js:2459 Note: Skipped 217 bytes in input.
    fheroes2.js:2459 Note: Illegal Audio-MPEG-Header 0xf00ff082 at offset 183458.
    fheroes2.js:2459 Note: Trying to resync...
    fheroes2.js:2459 Note: Illegal Audio-MPEG-Header 0xe0000010 at offset 184426.
    fheroes2.js:2459 Note: Skipped 490 bytes in input.
    fheroes2.js:2459 Note: Trying to resync...
    fheroes2.js:2459 Note: Illegal Audio-MPEG-Header 0x55555555 at offset 185161.
    fheroes2.js:2459 Note: Trying to resync...
    fheroes2.js:2459 Note: Skipped 213 bytes in input.
    fheroes2.js:2459 Note: Skipped 494 bytes in input.
    

    These messages are originated from the libmpg123 backend internals:

    Function Address
    put_char fheroes2.js:2459
    write fheroes2.js:2405
    write fheroes2.js:4441
    doWritev fheroes2.js:11089
    _fd_write fheroes2.js:11112
    imports. fheroes2.js:11238
    $__stdio_write __stdio_write.c:17
    $__vfprintf_internal vfprintf.c:748
    $vfiprintf vfprintf.c:769
    $fiprintf fprintf.c:21
    $INT123_read_frame parse.c:1323
    $get_next_frame libmpg123.c:695
    $mpg123_decode libmpg123.c:1052
    $mpg123_read libmpg123.c:944
    $MPG123_GetSome music_mpg123.c:383
    $music_pcm_getaudio music.c:302
    $MPG123_GetAudio music_mpg123.c:444
    $music_mixer music.c:364
    $mix_channels mixer.c:349
    $HandleAudioProcess SDL_emscriptenaudio.c:85
    $dynCall_vi fheroes2.wasm:0x21bcdd7
    ret. fheroes2.js:11270
    (anonymous) fheroes2.js:914
    dynCallLegacy fheroes2.js:11166
    dynCall fheroes2.js:11185
    SDL2.audio.scriptProcessorNode.onaudioprocess fheroes2.js:1238
  • MIDI playback seems to work flawlessly.

Overall, I regard the Emscripten build as still quite unstable. It is playable, but it's very rough for now.

Also please note that Emscripten uses the SharedArrayBuffer to implement the cross-thread communication and synchronization. SharedArrayBuffer needs the specific cross origin policy headers to be set by the HTTP server, namely Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp. These headers, in turn, will be accepted by a browser only if at least one of the following is true:

  • Website is opened using HTTPS with the proper certificate;
  • Website URL's host part is localhost (in this case, HTTPS is not required).

@oleg-derevenetz oleg-derevenetz added improvement New feature, request or improvement Wasm WebAssembly version of the engine labels Jan 8, 2025
@oleg-derevenetz oleg-derevenetz added this to the 1.1.6 milestone Jan 8, 2025
@ihhub
Copy link
Owner

ihhub commented Jan 9, 2025

Hi @oleg-derevenetz , since this version has so many issues with audio, should we disable opera music and only allow MIDI for now? After all, a web version of the engine is not what we will prioritise.

@oleg-derevenetz
Copy link
Collaborator Author

oleg-derevenetz commented Jan 9, 2025

Hi @ihhub

since this version has so many issues with audio, should we disable opera music and only allow MIDI for now? After all, a web version of the engine is not what we will prioritise.

Well, we have to think a bit here. Perhaps we just shouldn't allow pthreads in the emscripten build yet. I thought it would help against music choking, but it doesn't - probably the web workers (which emulate threads in wasm) do not have access to the browser music engine, so SDL cannot use them to decode the music in background, or something like this... Anyway, enabling -pthread doesn't help here. OGG crashes are observed by me only with -pthread (but maybe I just haven't tested enough, and crashes will be observed even without it). mpg123 junk is observed only when resuming a track from the previously remembered position, which just doesn't work without threads anyway.

@oleg-derevenetz
Copy link
Collaborator Author

oleg-derevenetz commented Jan 9, 2025

Hi @ihhub after some thought and tests, I suggest to enable the -pthread flag, but disable the OGG support in the sdl2_mixer. According to my tests, the vorbis library occasionally crashes like shown above even without threads. On the other hand, MP3 backend works in general (even the track resume works), despite the littering of the browser console. In the worst case scenario, nothing worse will happen than starting the track from the beginning instead of resuming. After all, WASM is still nothing more than an experimental technology.

Please note that I added a paragraph in the PR description regarding the cross origin policy settings required to get the multithread version to work in a web browser.

@oleg-derevenetz oleg-derevenetz marked this pull request as ready for review January 9, 2025 10:23
@oleg-derevenetz oleg-derevenetz requested a review from ihhub January 9, 2025 10:23
Copy link
Owner

@ihhub ihhub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @oleg-derevenetz , I left few questions here. Could you please check them?

src/dist/Makefile.emscripten Outdated Show resolved Hide resolved
src/dist/Makefile.emscripten Show resolved Hide resolved
src/dist/Makefile.emscripten Show resolved Hide resolved
@ihhub ihhub merged commit baebb96 into ihhub:master Jan 11, 2025
21 checks passed
@ihhub
Copy link
Owner

ihhub commented Jan 11, 2025

@oleg-derevenetz , many thanks for these updates!

@oleg-derevenetz oleg-derevenetz deleted the ems-pthread branch January 11, 2025 06:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement New feature, request or improvement Wasm WebAssembly version of the engine
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants