From d00f373336a0a31296ec126a21280007df9bdae7 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sat, 26 Feb 2022 12:24:32 +0000 Subject: [PATCH] emscripten: Return an error for webgl context limitations --- src/video/emscripten/SDL_emscriptenopengles.c | 30 ++++++++++++++++++- src/video/emscripten/SDL_emscriptenvideo.h | 2 ++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/video/emscripten/SDL_emscriptenopengles.c b/src/video/emscripten/SDL_emscriptenopengles.c index a601064ca56d45..dbf9b276bf044f 100644 --- a/src/video/emscripten/SDL_emscriptenopengles.c +++ b/src/video/emscripten/SDL_emscriptenopengles.c @@ -94,6 +94,12 @@ Emscripten_GLES_CreateContext(_THIS, SDL_Window * window) attribs.majorVersion = 2; /* WebGL 2.0 ~= GLES 3.0 */ window_data = (SDL_WindowData *) window->driverdata; + + if (window_data->gl_context) { + SDL_SetError("Cannot create multiple webgl contexts per window"); + return NULL; + } + context = emscripten_webgl_create_context(window_data->canvas_id, &attribs); if (context < 0) { @@ -106,6 +112,7 @@ Emscripten_GLES_CreateContext(_THIS, SDL_Window * window) return NULL; } + window_data->gl_context = (SDL_GLContext)context; return (SDL_GLContext)context; } @@ -113,6 +120,18 @@ Emscripten_GLES_CreateContext(_THIS, SDL_Window * window) void Emscripten_GLES_DeleteContext(_THIS, SDL_GLContext context) { + SDL_Window *window; + + /* remove the context from its window */ + for (window = _this->windows; window != NULL; window = window->next) { + SDL_WindowData *window_data; + window_data = (SDL_WindowData *) window->driverdata; + + if (window_data->gl_context == context) { + window_data->gl_context = NULL; + } + } + emscripten_webgl_destroy_context((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context); } @@ -129,7 +148,16 @@ Emscripten_GLES_SwapWindow(_THIS, SDL_Window * window) int Emscripten_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { - /* ignores window, as it isn't possible to reuse contexts across canvases */ + /* it isn't possible to reuse contexts across canvases */ + if (window && context) { + SDL_WindowData *window_data; + window_data = (SDL_WindowData *) window->driverdata; + + if (context != window_data->gl_context) { + return SDL_SetError("Cannot make context current to another window"); + } + } + if (emscripten_webgl_make_context_current((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context) != EMSCRIPTEN_RESULT_SUCCESS) { return SDL_SetError("Unable to make context current"); } diff --git a/src/video/emscripten/SDL_emscriptenvideo.h b/src/video/emscripten/SDL_emscriptenvideo.h index 20481235e5b566..4cd0a5ce59e244 100644 --- a/src/video/emscripten/SDL_emscriptenvideo.h +++ b/src/video/emscripten/SDL_emscriptenvideo.h @@ -33,6 +33,8 @@ typedef struct SDL_WindowData SDL_Window *window; SDL_Surface *surface; + SDL_GLContext gl_context; + char *canvas_id; float pixel_ratio;