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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
diff --git a/src/video/emscripten/SDL_emscriptenframebuffer.c b/src/video/emscripten/SDL_emscriptenframebuffer.c
index d4e9cb8..d7f41ef 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 e730725..976716a 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';
}