Skip to content

Commit cacd5a9

Browse files
authored
Workerized emscripten retroarch (WIP) (#17484)
* workerized RA * Workerized (non-async) web player, using OPFS This patch eliminates the need for asyncify and uses modern filesystem APIs instead of the deprecated, unmaintained BrowserFS. This is a WIP patch because it won't fully work until these two Emscripten PRs land and are released: emscripten-core/emscripten#23518 emscripten-core/emscripten#23021 The former fixes an offscreen canvas context recreation bug, and the latter adds an equivalent to BrowserFS's XHR filesystem (but without the hazardous running-XHR-on-the-main-thread problem). The biggest issue is that local storage of users who were using the old version of the webplayer will be gone when they switch to the new webplayer. I don't have a good story for converting the old BrowserFS IDBFS contents into the new OPFS filesystem (the move is worth doing because OPFS supports seeking and reading only bits of a file, and because BrowserFS is dead). I've kept around the old libretro webplayer under pkg/emscripten/libretro-classic, and with these make flags you can build a non-workerized RA that uses asyncify to sleep as before: make -f Makefile.emscripten libretro=$CORE HAVE_WORKER=0 HAVE_WASMFS=0 PTHREAD=0 HAVE_AL=1 I also moved the default directory for core content on emscripten to not be a subdirectory of the local filesystem mount, because it's confusing to have a subdirectory that's lazily fetched and not mirrored to the local storage. I think it won't impact existing users of the classic web player because they already have a retroarch.cfg in place. * Get fetchfs working without manifest support * makefile fixes
1 parent 4b5f782 commit cacd5a9

File tree

17 files changed

+1199
-180
lines changed

17 files changed

+1199
-180
lines changed

Makefile.common

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1526,7 +1526,10 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
15261526
endif
15271527

15281528
ifeq ($(HAVE_EMSCRIPTEN), 1)
1529-
OBJ += gfx/drivers_context/emscriptenegl_ctx.o
1529+
ifeq ($(HAVE_EGL), 1)
1530+
OBJ += gfx/drivers_context/emscriptenegl_ctx.o
1531+
endif
1532+
OBJ += gfx/drivers_context/emscriptenwebgl_ctx.o
15301533
endif
15311534

15321535
ifeq ($(HAVE_MALI_FBDEV), 1)

Makefile.emscripten

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ HAVE_SCREENSHOTS = 1
2424
HAVE_REWIND = 1
2525
HAVE_AUDIOMIXER = 1
2626
HAVE_CC_RESAMPLER = 1
27-
HAVE_EGL = 1
27+
HAVE_EGL ?= 0
28+
HAVE_OPENGLES = 1
2829
HAVE_RJPEG = 0
2930
HAVE_RPNG = 1
3031
HAVE_EMSCRIPTEN = 1
@@ -48,6 +49,8 @@ HAVE_7ZIP = 1
4849
HAVE_BSV_MOVIE = 1
4950
HAVE_AL = 1
5051
HAVE_CHD ?= 0
52+
HAVE_WASMFS ?= 1
53+
HAVE_WORKER ?= 1
5154

5255
# WARNING -- READ BEFORE ENABLING
5356
# The rwebaudio driver is known to have several audio bugs, such as
@@ -68,7 +71,7 @@ HAVE_OPENGLES3 ?= 0
6871

6972
ASYNC ?= 0
7073
LTO ?= 0
71-
PTHREAD ?= 0
74+
PTHREAD ?= 4
7275

7376
STACK_SIZE ?= 4194304
7477
INITIAL_HEAP ?= 134217728
@@ -92,11 +95,52 @@ _cmd_toggle_menu,_cmd_reload_config,_cmd_toggle_grab_mouse,_cmd_toggle_game_focu
9295
_cmd_set_volume,_cmd_set_shader,_cmd_cheat_set_code,_cmd_cheat_get_code,_cmd_cheat_toggle_index,_cmd_cheat_get_code_state,_cmd_cheat_realloc,\
9396
_cmd_cheat_get_size,_cmd_cheat_apply_cheats
9497

98+
EXPORTS := callMain,FS,PATH,ERRNO_CODES,stringToNewUTF8,UTF8ToString
99+
95100
LIBS := -s USE_ZLIB=1
101+
102+
ifeq ($(HAVE_WASMFS), 1)
103+
LIBS += -s WASMFS -s FORCE_FILESYSTEM=1 -lfetchfs.js -lopfs.js
104+
EXPORTS := $(EXPORTS),FETCHFS,OPFS
105+
endif
106+
107+
ifeq ($(HAVE_WORKER), 1)
108+
LIBS += -s PROXY_TO_PTHREAD -s USE_ES6_IMPORT_META=0 -sENVIRONMENT=worker,web
109+
else
110+
ifeq ($(HAVE_AL), 1)
111+
override ASYNC = 1
112+
endif
113+
endif
114+
115+
ifeq ($(HAVE_OPENGLES), 1)
116+
ifeq ($(HAVE_OPENGLES3), 1)
117+
LDFLAGS += -s FULL_ES3=1 -s MIN_WEBGL_VERSION=2 -s MAX_WEBGL_VERSION=2
118+
else
119+
LDFLAGS += -s FULL_ES2=1
120+
endif
121+
endif
122+
123+
ifeq ($(GL_DEBUG), 1)
124+
LDFLAGS += -s GL_ASSERTIONS=1 -s GL_DEBUG=1
125+
endif
126+
127+
ifeq ($(FS_DEBUG), 1)
128+
LDFLAGS += -s FS_DEBUG=1
129+
endif
130+
131+
ifeq ($(HAVE_SDL2), 1)
132+
LIBS += -s USE_SDL=2
133+
DEFINES += -DHAVE_SDL2
134+
endif
135+
136+
96137
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s STACK_SIZE=$(STACK_SIZE) -s INITIAL_MEMORY=$(INITIAL_HEAP) \
97-
-s EXPORTED_RUNTIME_METHODS=callMain,FS,PATH,ERRNO_CODES,stringToNewUTF8,UTF8ToString \
138+
-s EXPORTED_RUNTIME_METHODS=$(EXPORTS) \
98139
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="$(EXPORTED_FUNCTIONS)" \
99140
-s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORT_NAME="libretro_$(subst -,_,$(LIBRETRO))" \
141+
-s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=0 \
142+
-s OFFSCREENCANVAS_SUPPORT \
143+
-s OFFSCREEN_FRAMEBUFFER \
100144
--extern-pre-js emscripten/pre.js \
101145
--js-library emscripten/library_rwebcam.js \
102146
--js-library emscripten/library_platform_emscripten.js
@@ -105,48 +149,29 @@ ifeq ($(HAVE_RWEBAUDIO), 1)
105149
LDFLAGS += --js-library emscripten/library_rwebaudio.js
106150
DEFINES += -DHAVE_RWEBAUDIO
107151
endif
152+
108153
ifeq ($(HAVE_AL), 1)
109154
LDFLAGS += -lopenal
110155
DEFINES += -DHAVE_AL
111-
override ASYNC = 1
112156
endif
113157

114158
ifneq ($(PTHREAD), 0)
115-
LDFLAGS += -s MAXIMUM_MEMORY=1073741824 -pthread -s PTHREAD_POOL_SIZE=$(PTHREAD)
116-
CFLAGS += -pthread
159+
LDFLAGS += -s WASM_MEM_MAX=1073741824 -pthread -s PTHREAD_POOL_SIZE=$(PTHREAD)
160+
CFLAGS += -pthread -s SHARED_MEMORY
117161
HAVE_THREADS=1
118162
else
119163
HAVE_THREADS=0
120164
endif
121165

166+
122167
ifeq ($(ASYNC), 1)
168+
DEFINES += -DEMSCRIPTEN_ASYNCIFY
123169
LDFLAGS += -s ASYNCIFY=$(ASYNC) -s ASYNCIFY_STACK_SIZE=8192
124170
ifeq ($(DEBUG), 1)
125171
LDFLAGS += -s ASYNCIFY_DEBUG=1 # -s ASYNCIFY_ADVISE
126172
endif
127173
endif
128174

129-
ifeq ($(HAVE_OPENGLES), 1)
130-
ifeq ($(HAVE_OPENGLES3), 1)
131-
LDFLAGS += -s FULL_ES3=1 -s MIN_WEBGL_VERSION=2 -s MAX_WEBGL_VERSION=2
132-
else
133-
LDFLAGS += -s FULL_ES2=1
134-
endif
135-
endif
136-
137-
ifeq ($(GL_DEBUG), 1)
138-
LDFLAGS += -s GL_ASSERTIONS=1 -s GL_DEBUG=1
139-
endif
140-
141-
ifeq ($(FS_DEBUG), 1)
142-
LDFLAGS += -s FS_DEBUG=1
143-
endif
144-
145-
ifeq ($(HAVE_SDL2), 1)
146-
LIBS += -s USE_SDL=2
147-
DEFINES += -DHAVE_SDL2
148-
endif
149-
150175
include Makefile.common
151176

152177
CFLAGS += $(DEF_FLAGS) -Ideps -Ideps/stb
@@ -183,8 +208,10 @@ RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
183208

184209
all: $(TARGET)
185210

186-
$(TARGET): $(RARCH_OBJ) $(libretro)
187-
@$(if $(libretro), mv -f $(libretro) $(libretro_new),)
211+
$(libretro_new) : $(libretro)
212+
mv -f $(libretro) $(libretro_new)
213+
214+
$(TARGET): $(RARCH_OBJ) $(libretro_new)
188215
@$(if $(Q), $(shell echo echo "LD $@ \<obj\> $(libretro_new) $(LIBS) $(LDFLAGS)"),)
189216
$(Q)$(LD) -o $@ $(RARCH_OBJ) $(libretro_new) $(LIBS) $(LDFLAGS)
190217

frontend/drivers/platform_emscripten.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ static void frontend_emscripten_get_env(int *argc, char *argv[],
235235
"config", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG]));
236236
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_MENU_CONTENT], user_path,
237237
"content", sizeof(g_defaults.dirs[DEFAULT_DIR_MENU_CONTENT]));
238-
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], user_path,
239-
"content/downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]));
238+
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], base_path,
239+
"downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]));
240240
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_PLAYLIST], user_path,
241241
"playlists", sizeof(g_defaults.dirs[DEFAULT_DIR_PLAYLIST]));
242242
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG],
@@ -308,7 +308,10 @@ int main(int argc, char *argv[])
308308
specialHTMLTargets["!canvas"] = Module.canvas;
309309
});
310310

311+
emscripten_set_canvas_element_size("!canvas", 800, 600);
312+
emscripten_set_element_css_size("!canvas", 800.0, 600.0);
311313
emscripten_set_main_loop(emscripten_mainloop, 0, 0);
314+
emscripten_set_main_loop_timing(EM_TIMING_RAF, 1);
312315
rarch_main(argc, argv, NULL);
313316

314317
return 0;

gfx/drivers_context/emscriptenegl_ctx.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,9 @@ static void gfx_ctx_emscripten_destroy(void *data)
124124

125125
if (!emscripten)
126126
return;
127-
128127
#ifdef HAVE_EGL
129128
egl_destroy(&emscripten->egl);
130129
#endif
131-
132130
free(data);
133131
}
134132

@@ -191,7 +189,6 @@ static void *gfx_ctx_emscripten_init(void *video_driver)
191189
#endif
192190

193191
return emscripten;
194-
195192
error:
196193
gfx_ctx_emscripten_destroy(video_driver);
197194
return NULL;

0 commit comments

Comments
 (0)