emscripten: Don't set OpenGL swap intervals until first PumpEvents.
Build (All) / Create test plan (push) Waiting to run
Build (All) / level1 (push) Blocked by required conditions
Build (All) / level2 (push) Blocked by required conditions

Any requested swap interval will be saved and set on the first PumpEvents.
Once PumpEvents has been called at least once, swap intervals are set
immediately.

This assumes that events won't be pumped until after an Emscripten main loop
has been defined, and so prevents a warning on the javascript console:

"emscripten_set_main_loop_timing: Cannot set timing mode for main loop since
a main loop does not exist! Call emscripten_set_main_loop first to set one
up."

Fixes #9969.
This commit is contained in:
Ryan C. Gordon
2025-01-11 15:14:36 -05:00
parent d42b4ed961
commit 3ad9c38a46
3 changed files with 34 additions and 5 deletions
@@ -47,10 +47,14 @@ bool Emscripten_GLES_SetSwapInterval(SDL_VideoDevice *_this, int interval)
{
if (interval < 0) {
return SDL_SetError("Late swap tearing currently unsupported");
} else if (interval == 0) {
emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, 0);
} else {
emscripten_set_main_loop_timing(EM_TIMING_RAF, interval);
}
if (Emscripten_ShouldSetSwapInterval(interval)) {
if (interval == 0) {
emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, 0);
} else {
emscripten_set_main_loop_timing(EM_TIMING_RAF, interval);
}
}
return true;
+24 -1
View File
@@ -48,6 +48,10 @@ static SDL_FullscreenResult Emscripten_SetWindowFullscreen(SDL_VideoDevice *_thi
static void Emscripten_PumpEvents(SDL_VideoDevice *_this);
static void Emscripten_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
static bool pumpevents_has_run = false;
static int pending_swap_interval = -1;
// Emscripten driver bootstrap functions
static void Emscripten_DeleteDevice(SDL_VideoDevice *device)
@@ -228,6 +232,8 @@ static void Emscripten_VideoQuit(SDL_VideoDevice *_this)
{
Emscripten_QuitMouse();
Emscripten_UnlistenSystemTheme();
pumpevents_has_run = false;
pending_swap_interval = -1;
}
static bool Emscripten_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
@@ -245,9 +251,26 @@ static bool Emscripten_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoD
return true;
}
bool Emscripten_ShouldSetSwapInterval(int interval)
{
if (!pumpevents_has_run) {
pending_swap_interval = interval;
return false;
}
return true;
}
static void Emscripten_PumpEvents(SDL_VideoDevice *_this)
{
// do nothing.
if (!pumpevents_has_run) {
// we assume you've set a mainloop by the time you've called pumpevents, so we delay initial SetInterval changes until then.
// otherwise you'll get a warning on the javascript console.
pumpevents_has_run = true;
if (pending_swap_interval >= 0) {
Emscripten_GLES_SetSwapInterval(_this, pending_swap_interval);
pending_swap_interval = -1;
}
}
}
static bool Emscripten_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props)
@@ -47,4 +47,6 @@ struct SDL_WindowData
bool has_pointer_lock;
};
bool Emscripten_ShouldSetSwapInterval(int interval);
#endif // SDL_emscriptenvideo_h_