godot
godot copied to clipboard
WebAssembly maximum memory 2GB causes Out of Memory error on iOS Safari 16.2
Godot version
4.0.dev (f382a2b)
System information
iOS 16.2 Safari, iPhone 13 Pro
Issue description
When exporting for Web and running on iOS 16.2 Safari, out of memory error occurs at WebAssembly.Memory initialization.
This error comes because maximum
argument is 2048MB which is quite bigger for iOS.
When I changed WASM_MEM_MAX
to 256MB for example at platform/web/detect.py: 197, the error disappeared.
env.Append(LINKFLAGS=["-s", "WASM_MEM_MAX=256MB"])
Steps to reproduce
- Build Godot Web export with option
module_raycast_enabled=no
to disable WebAssembly SIMD usage which seems to be not yet supported on iOS Safari 16.2. - Export minimal reproduction project to Web.
- Out of memory error log will be found on JavaScript console (reproduced).
- Change WASM_MEM_MAX to 256MB and rebuild Web export.
- Re-export minimal reproduction project.
- Rotating unlit white cube is correctly rendered (reproduced).
Minimal reproduction project
Even if doing these workaround, sometimes page crash occurs while loading indicator. Maybe related to #67949.
I'm getting the same error, posted a screen shot for reference. I think this is related to #67949 as well.
@TyounanMOTI I tried following your steps and I still could not get my project to run. I receive an error when running the test on ios, "Unhandled Promise Rejection: CompileError: WebAssembly.Module doesn't parse at byte 5: can't get Function local's type in group 1, in function at index 34516" Could you please upload your export template?
@stefano-elysium Here is the debug template for web built by myself. web_debug.zip
I receive an error when running the test on ios, "Unhandled Promise Rejection: CompileError: WebAssembly.Module doesn't parse at byte 5: can't get Function local's type in group 1, in function at index 34516"
That exception is caused by lack of WASM-SIMD implementation of iOS Safari 16.3 or earlier. Excluding module raycast while build by option module_raycast_enabled=no
as written in first comment will remove that error.
It seems that iOS Safari 16.4 adding WASM-SIMD support according to the release note. That may become a good news.
I will try recompiling with module_raycast_enabled=no, but just as a fyi I tested with the templates I have made for now and was unable to run on ios16.4 (although I couldn't figure out how to check if the browser updated too)
With module_raycast_enabled=no I managed to run it!
With module_raycast_enabled=no I managed to run it!
Is any method for use this solution without compiling engine?
Unfortunately, at least from my testing, the only realiable way to have web exports that run on most platforms is to use godot 3
@dyegoaurelio the issue is the same if you attempt to run godot 3 with multithreading on.
@dyegoaurelio the issue is the same if you attempt to run godot 3 with multithreading on.
The support for godot 3 web exports is better than godot 4 even with multithreading on (which is an optional feature)
For multithreading to work, the browser just needs to support Shared Array Buffer
Have you tried running a multithreaded godot 3 version on the iphone? I receive the same issue as with godot 4
@akien-mga Should we use module_raycast_enabled=no
for future official web builds? It's only used for CPU-based occlusion culling, which I gather isn't going to be used often in web projects (as most of them are 2D or simple 3D scenes, with relatively few triangles).
As a bonus, it'll make web export templates smaller as Embree could possibly be excluded at the same time. We just need to update the documentation accordingly to mention occlusion culling won't work in web exports.
Yeah we can probably disable the raycast module by default on Web, directly in detect.py
.
I hadn't really considered the memory footprint from including everything that can compile, so we might want to review other optional features to see if some would make sense to disable by default if we think that they're very unlikely to be used for Web projects. This would need to be documented of course as some users can be taken aback when a feature that works on PC seems broken/missing on Web.
In my testing WASM_MEM_MAX=256MB and module_raycast_enabled=no does allow Godot 4 games to start on iOS Safari. They seem to crash after a while though, but this could easily be a problem with Safari and not Godot. At least the games will start now :-)
@akien-mga I think github accidentally closed this issue, could you reopen it? This issue was originally about Godot starting with a too high web assembly memory requirement, which hasn't been fixed by the linked PR.
While disabling the ray cast module due to the lack of simd support in wasm is also necessary, it isn't a full solution to this problem.
On Godot 4.2 dev 6 still doesn't work. Did I still need to rebuild the engine with the "WASM_MEM_MAX=256MB" parameter?
I've tested on iPhone 11 Pro Max and iPhone 12 Pro.
https://github.com/godotengine/godot/assets/5132385/a9c141ef-c259-4541-9d85-35638bc35c5c
Edit: I've tried to change wasm maximum memory in index.js but without positive results. The game loaded and displayed the interface, then crashed.
That is as far as I have gotten as well. With 256MB it loads and looks fine for a few seconds, then it crashes.
That is as far as I have gotten as well. With 256MB it loads and looks fine for a few seconds, then it crashes.
Should probably open an issue upstream: https://bugs.webkit.org/
Did someone already reproduce the issue with the upstream Webkit? This is how to build it from source: https://trac.webkit.org/wiki/BuildingGtk#BuildingWebKitGTKfromgit
If it could be reproduced there, it would be easier to debug, both for us and for the WebKit developers.
Monkey testing stuff around I found a trick.
wasmMemory = new WebAssembly.Memory({
"initial": INITIAL_MEMORY / 65536,
//"maximum": 2147483648 / 65536,
"maximum": 268000000 / 65536,//Tei: It was 2048 MB, but iOS choke on it
"shared": true
});
I have not tested this in a large game, so maybe Godo choke on the smaller max memory. Also the value should be 256MB, it could be bigger than I tested it here.
Maybe this code could detect iOS, and use the smaller max memory there instead of everywhere.