Skip to content

Commit 58707d1

Browse files
authored
Wasmfs: Support SDL2_image (#19560)
To do that we need to implement emscripten_get_preloaded_image_data_from_FILE This is implemented in JS in the old FS, which then does FS.getStream() etc., which is more than we want to support in the WasmFS JS API. Instead, just implement that function in a simple way in wasm, which is much more straightforward anyhow. (That implementation is trivial aside from a new getPath() helper, but that helper is useful anyhow - I've been using that code to debug locally.) This also removes an SDL_Quit - removing that allows the test to actually show the image that was loaded (otherwise we quit before the render happens, which confused me as I was debugging).
1 parent f64d865 commit 58707d1

File tree

5 files changed

+71
-3
lines changed

5 files changed

+71
-3
lines changed

src/library_browser.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,7 @@ var LibraryBrowser = {
13001300
return 0;
13011301
},
13021302

1303+
#if !WASMFS // WasmFS implements this in wasm
13031304
emscripten_get_preloaded_image_data_from_FILE__deps: ['emscripten_get_preloaded_image_data', 'fileno'],
13041305
emscripten_get_preloaded_image_data_from_FILE__proxy: 'sync',
13051306
emscripten_get_preloaded_image_data_from_FILE: function(file, w, h) {
@@ -1311,6 +1312,7 @@ var LibraryBrowser = {
13111312

13121313
return 0;
13131314
}
1315+
#endif
13141316
};
13151317

13161318
autoAddDeps(LibraryBrowser, '$Browser');

system/lib/wasmfs/emscripten.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2023 The Emscripten Authors. All rights reserved.
2+
// Emscripten is available under two separate licenses, the MIT license and the
3+
// University of Illinois/NCSA Open Source License. Both these licenses can be
4+
// found in the LICENSE file.
5+
6+
//
7+
// This file contains implementations of emscripten APIs that are compatible
8+
// with WasmFS. These replace APIs in src/library*js, and basically do things
9+
// in a simpler manner for the situation where the FS is in wasm and not JS
10+
// (in particular, these implemenations avoid calling from JS to wasm, and
11+
// dependency issues that arise from that).
12+
//
13+
14+
#include <emscripten.h>
15+
#include <stdio.h>
16+
17+
#include <string>
18+
19+
#include "file.h"
20+
#include "file_table.h"
21+
#include "wasmfs.h"
22+
23+
namespace wasmfs {
24+
25+
// Given an fd, returns the string path that the fd refers to.
26+
// TODO: full error handling
27+
// TODO: maybe make this a public API, as it is useful for debugging
28+
std::string getPath(int fd) {
29+
auto fileTable = wasmfs::wasmFS.getFileTable().locked();
30+
31+
auto openFile = fileTable.getEntry(fd);
32+
if (!openFile) {
33+
return "!";
34+
}
35+
36+
auto curr = openFile->locked().getFile();
37+
std::string result = "";
38+
while (curr != wasmfs::wasmFS.getRootDirectory()) {
39+
auto parent = curr->locked().getParent();
40+
// Check if the parent exists. The parent may not exist if curr was
41+
// unlinked.
42+
if (!parent) {
43+
return "?/" + result;
44+
}
45+
46+
auto parentDir = parent->dynCast<wasmfs::Directory>();
47+
auto name = parentDir->locked().getName(curr);
48+
result = '/' + name + result;
49+
curr = parentDir;
50+
}
51+
return result;
52+
}
53+
54+
} // namespace wasmfs
55+
56+
extern "C"
57+
char *emscripten_get_preloaded_image_data_from_FILE(FILE *file,
58+
int *w,
59+
int *h) {
60+
auto fd = fileno(file);
61+
if (fd < 0) {
62+
return 0;
63+
}
64+
65+
auto path = wasmfs::getPath(fd);
66+
return emscripten_get_preloaded_image_data(path.c_str(), w, h);
67+
}

test/browser/test_sdl2_image.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,5 @@ int main() {
7474

7575
printf("you should see an image.\n");
7676

77-
SDL_Quit();
78-
7977
return result;
8078
}
81-

test/test_browser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2945,6 +2945,7 @@ def test_sdl2_image_jpeg(self):
29452945
'-sUSE_SDL=2', '-sUSE_SDL_IMAGE=2', '--use-preload-plugins'
29462946
])
29472947

2948+
@also_with_wasmfs
29482949
@requires_graphics_hardware
29492950
def test_sdl2_image_formats(self):
29502951
shutil.copyfile(test_file('screenshot.png'), 'screenshot.png')

tools/system_libs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,6 +1857,7 @@ def get_files(self):
18571857
filenames=['file.cpp',
18581858
'file_table.cpp',
18591859
'js_api.cpp',
1860+
'emscripten.cpp',
18601861
'paths.cpp',
18611862
'special_files.cpp',
18621863
'support.cpp',

0 commit comments

Comments
 (0)