# Using SDL\_GL\_SwapWindow() with Emscripten

**URL:** <https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390>\
**Category:** SDL Development\
**Created:** [June 24, 2023, 10:00pm UTC](https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390 "2023-06-24T22:00:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![rtrussell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/rtrussell/32/4768_2.png) [@rtrussell](https://discourse.libsdl.org/u/rtrussell)\
**Post date:** [June 24, 2023, 10:00pm UTC](https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390/1 "2023-06-24T22:00:52Z")

</div>

When compiled with Emscripten I’m getting rendering anomalies (periodic black frames, resulting in ‘flashing’). This happens _only_ on **Safari** , and _only_ when using **`SDL_GL_SwapWindow()`**. Everything is fine with other browsers (those based on the Chrome engine, and Firefox) **or** when using `SDL_RenderPresent()` rather than `SDL_GL_SwapWindow()`.

I’m yielding back to the browser immediately after calling `SDL_GL_SwapWindow()` or `SDL_RenderPresent()` so that the drawn frame can be displayed, which I believe is the correct way to do it. It means I am relying on `SDL_GL_SwapWindow()` not returning until the internal frame buffer has been updated; I’m not sure that is guaranteed, but I don’t know how else to do it.

Under the hood, are there differences between `SDL_RenderPresent()` and `SDL_GL_SwapWindow()` which might be important when using Emscripten?

---

<div class="post-metadata">

**Author:** ![eri0o](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/eri0o/32/4277_2.png) [@eri0o](https://discourse.libsdl.org/u/eri0o)\
**Post date:** [June 25, 2023, 12:24am UTC](https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390/2 "2023-06-25T00:24:35Z")

</div>

So SDL\_GL\_SwapWindow will eventually call eglSwapBuffers in Emscripten and also work as a point to give control to the browser in case you are using asincify.

> <https://github.com/emscripten-core/emscripten/blob/c25d2663c797904c740ef9c203b1dd4165a16771/src/library_egl.js#L638>

I think eglSwapBuffers doesn’t do anything unless the call is coming from a worker. I think the browser should naturally do the swap and that call is not needed. You mention it only happens in Safari when using it, so if you just remove it does it work alright in Safari and all other browsers?

I am not familiar with the SDL renderer so I don’t know what the other call does.

---

<div class="post-metadata">

**Author:** ![rtrussell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/rtrussell/32/4768_2.png) [@rtrussell](https://discourse.libsdl.org/u/rtrussell)\
**Post date:** [June 25, 2023, 9:41am UTC](https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390/3 "2023-06-25T09:41:49Z")

</div>

> [@eri0o](#):
>
> as a point to give control to the browser in case you are using asincify.

I’m not using **asyncify** , I’m explicitly returning control to the browser by exiting the mainloop after I’ve drawn my scene.

> You mention it only happens in Safari when using it, so if you just remove it does it work alright in Safari and all other browsers?

I’d not tried that, but have now done so and it makes no difference at all (which is consistent with your belief that it does nothing in WebGL). So it’s not so much the call to `SDL_GL_SwapWindow()` which triggers the issue, but that I am drawing my scene using shaders (the heavy-lifting is done in `glDrawArrays()`) and **not** calling `SDL_RenderPresent()`.

An additional piece of information is that this unwanted ‘flashing’ bevahior appeared in a fairly recent Emscripten update, earlier versions work OK and later versions exhibit the effect. I’ve bisected it to see exactly what the precise change was, but the Emscripten people cannot see how that change (which was related to timers) could have any effect at all on rendering, but it clearly does.

---

<div class="post-metadata">

**Author:** ![eri0o](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/eri0o/32/4277_2.png) [@eri0o](https://discourse.libsdl.org/u/eri0o)\
**Post date:** [June 25, 2023, 11:09am UTC](https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390/4 "2023-06-25T11:09:10Z")

</div>

Hey, what GL are you using? Like, are you using WebGL or some layer of emulation (say OpenGL ES2 or some other)? Asking just because these emulations are some JS hacks in case there some timer in one of them - there probably isn’t, but I don’t know, haven’t looked into them looking for it.

---

<div class="post-metadata">

**Author:** ![rtrussell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/rtrussell/32/4768_2.png) [@rtrussell](https://discourse.libsdl.org/u/rtrussell)\
**Post date:** [June 25, 2023, 12:56pm UTC](https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390/5 "2023-06-25T12:56:35Z")

</div>

> [@eri0o](#):
>
> what GL are you using? Like, are you using WebGL

WebGL, yes. The key call is [`glDrawArrays()`](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawArrays) which draws my scene using custom shaders.

Having discovered that `SDL_GL_SwapWindow()` seemingly does nothing and can be omitted, I tried replacing it with a `glFlush()` or `glFinish()` but it makes no difference either.

---

<div class="post-metadata">

**Author:** ![eri0o](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/eri0o/32/4277_2.png) [@eri0o](https://discourse.libsdl.org/u/eri0o)\
**Post date:** [June 25, 2023, 1:31pm UTC](https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390/6 "2023-06-25T13:31:25Z")

</div>

Found a mention here in their webgl saying that swap behavior is implicit

> <https://github.com/emscripten-core/emscripten/blob/c25d2663c797904c740ef9c203b1dd4165a16771/src/library_webgl.js#L737>

Yes I know it’s in a different line, but if you look you can see that Emscripten webgl isn’t REALLY WebGL as it tries to harmonize different implementations and versions…

Unfortunately now that I see this and reread your comment on timers, I ask if this is pthreads related and what kind of drawings are performed in the worker.

My experience with pthreads is that it’s not dependable yet, if you go in Unity Technologies GitHub organization you can see they have locked themselves in an older version of Emscripten - I think juj freelance for them too.

Anyway, if it’s flashing black/correct there has to be a point where it’s yielded to the browser but the canvas buffered has been cleared and other where the drawing has happened. If you only yield in one place in your code, then there has to be a way that state changes.

Other approach though is to open an issue in WebKit and mention that it has a different behavior between Chrome and Safari in macOS and then open a feedback on Apple development. When something has a different behavior they usually monitor a bit closely although they are silent about it - you will see many status changes in the issue, but no one will answer.

---

<div class="post-metadata">

**Author:** ![rtrussell](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/rtrussell/32/4768_2.png) [@rtrussell](https://discourse.libsdl.org/u/rtrussell)\
**Post date:** [June 25, 2023, 5:00pm UTC](https://discourse.libsdl.org/t/using-sdl-gl-swapwindow-with-emscripten/44390/7 "2023-06-25T17:00:24Z")

</div>

> [@eri0o](#):
>
> Anyway, if it’s flashing black/correct there has to be a point where it’s yielded to the browser but the canvas buffered has been cleared and other where the drawing has happened. If you only yield in one place in your code, then there has to be a way that state changes.

I’ve double-checked everything and I can’t see any way that it can yield back to the browser with the canvas not correctly drawn. In any case if it **did** ever do that it would surely fail on other browsers too, not just Safari.

What is interesting is that `SDL_RenderPresent()` doesn’t fail in the same way. Does it use shaders in the Emscripten build? If so it must be using code similar to mine so I wonder what the difference is.
