From 4dca8f7fb4c63d1b42c31c7dd821197832714c3f Mon Sep 17 00:00:00 2001
From: Reinhold Gschweicher <[EMAIL REDACTED]>
Date: Thu, 24 Feb 2022 21:09:03 +0100
Subject: [PATCH] SDL2 thread proxying fixes
This PR uses new APIs added in [emscripten-core/emscripten#9336](https://github.com/emscripten-core/emscripten/pull/9336)
to improve compatibility with USE_PTHREADS=1.
Original PR: https://github.com/emscripten-ports/SDL2/pull/127
By: @jakogut
Reviewed by: Daft-Freak
---
.../emscripten/SDL_emscriptenframebuffer.c | 37 +++++++++----
src/video/emscripten/SDL_emscriptenmouse.c | 54 +++++++++++++------
2 files changed, 65 insertions(+), 26 deletions(-)
diff --git a/src/video/emscripten/SDL_emscriptenframebuffer.c b/src/video/emscripten/SDL_emscriptenframebuffer.c
index d4e9cb8e8d7..d7f41ef9297 100644
--- a/src/video/emscripten/SDL_emscriptenframebuffer.c
+++ b/src/video/emscripten/SDL_emscriptenframebuffer.c
@@ -26,6 +26,8 @@
#include "SDL_emscriptenframebuffer.h"
#include "SDL_hints.h"
+#include <emscripten/threading.h>
+
int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
{
@@ -57,18 +59,8 @@ int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * form
return 0;
}
-int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
+static void Emscripten_UpdateWindowFramebufferWorker(SDL_Surface *surface)
{
- SDL_Surface *surface;
-
- SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
- surface = data->surface;
- if (!surface) {
- return SDL_SetError("Couldn't find framebuffer surface for window");
- }
-
- /* Send the data to the display */
-
EM_ASM_INT({
var w = $0;
var h = $1;
@@ -156,6 +148,29 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
SDL2.ctx.putImageData(SDL2.image, 0, 0);
return 0;
}, surface->w, surface->h, surface->pixels);
+}
+
+int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
+{
+ SDL_Surface *surface;
+
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ surface = data->surface;
+ if (!surface) {
+ return SDL_SetError("Couldn't find framebuffer surface for window");
+ }
+
+ /* Send the data to the display */
+
+ if (emscripten_is_main_runtime_thread()) {
+ Emscripten_UpdateWindowFramebufferWorker(surface);
+ } else {
+ emscripten_sync_run_in_main_runtime_thread(
+ EM_FUNC_SIG_VI,
+ Emscripten_UpdateWindowFramebufferWorker,
+ (uint32_t)surface
+ );
+ }
if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) {
/* give back control to browser for screen refresh */
diff --git a/src/video/emscripten/SDL_emscriptenmouse.c b/src/video/emscripten/SDL_emscriptenmouse.c
index e7307259091..976716afdb1 100644
--- a/src/video/emscripten/SDL_emscriptenmouse.c
+++ b/src/video/emscripten/SDL_emscriptenmouse.c
@@ -24,6 +24,7 @@
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
+#include <emscripten/threading.h>
#include "SDL_emscriptenmouse.h"
#include "SDL_emscriptenvideo.h"
@@ -62,19 +63,9 @@ Emscripten_CreateDefaultCursor()
return Emscripten_CreateCursorFromString("default", SDL_FALSE);
}
-static SDL_Cursor*
-Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
+static const char *Emscripten_GetCursorUrl(int w, int h, int hot_x, int hot_y, int pixels)
{
- const char *cursor_url = NULL;
- SDL_Surface *conv_surf;
-
- conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0);
-
- if (!conv_surf) {
- return NULL;
- }
-
- cursor_url = (const char *)EM_ASM_INT({
+ return (const char *)EM_ASM_INT({
var w = $0;
var h = $1;
var hot_x = $2;
@@ -122,7 +113,40 @@ Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
stringToUTF8(url, urlBuf, url.length + 1);
return urlBuf;
- }, surface->w, surface->h, hot_x, hot_y, conv_surf->pixels);
+ }, w, h, hot_x, hot_y, pixels);
+}
+
+static SDL_Cursor*
+Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
+{
+ const char *cursor_url = NULL;
+ SDL_Surface *conv_surf;
+
+ conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0);
+
+ if (!conv_surf) {
+ return NULL;
+ }
+
+ if (emscripten_is_main_runtime_thread()) {
+ cursor_url = Emscripten_GetCursorUrl(
+ surface->w,
+ surface->h,
+ hot_x,
+ hot_y,
+ conv_surf->pixels
+ );
+ } else {
+ cursor_url = emscripten_sync_run_in_main_runtime_thread(
+ EM_FUNC_SIG_IIIIIII,
+ Emscripten_GetCursorUrl,
+ surface->w,
+ surface->h,
+ hot_x,
+ hot_y,
+ conv_surf->pixels
+ );
+ }
SDL_FreeSurface(conv_surf);
@@ -206,7 +230,7 @@ Emscripten_ShowCursor(SDL_Cursor* cursor)
curdata = (Emscripten_CursorData *) cursor->driverdata;
if(curdata->system_cursor) {
- EM_ASM_INT({
+ MAIN_THREAD_EM_ASM_INT({
if (Module['canvas']) {
Module['canvas'].style['cursor'] = UTF8ToString($0);
}
@@ -215,7 +239,7 @@ Emscripten_ShowCursor(SDL_Cursor* cursor)
}
}
else {
- EM_ASM(
+ MAIN_THREAD_EM_ASM_INT(
if (Module['canvas']) {
Module['canvas'].style['cursor'] = 'none';
}