godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine

Home Page:https://godotengine.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HTML5 export for Godot 4.x takes 1-2 minutes to load on macOS

Luzzotica opened this issue · comments


Bugsquad note: This issue has been confirmed several times already. No need to confirm it further.
Bugsquad note2: Also, please avoid asking when this will be fixed. The issue is confirmed to be with the version of ANGLE used by Chromium, so we are all waiting for Google to ship the fix.


Godot version

4.0.beta10

System information

MacOS Monterey 12.2.1

Issue description

Godot games block the main thread (And potentially crashes it) on MacOS.

Untested for Windows or Linux.

This happens from both a generic build and when you run the project in a browser from the engine.

Steps to reproduce

Create a new project for Godot Beta 10.

Add a UI Button to the screen.

Have it print things out, whatever you wish.

Add an HTML5 export, install the HTML5 export library if necessary.

Click the run on HTML5 button on the top right.

Proceed to wait for 1-2 minutes before the game will fully load.

Minimal reproduction project

TestGodot4Web.zip

Duplicate of #41118 and/or #68647 (same cause – large size causes slow initialization times).

@Calinou I feel like this isn't the same as those. I don't believe it's a size issue.

Running locally on MacOS on both Brave and Chrome: Took about ~2 minutes and 30 seconds for the game to load. Both Brave and Chrome wanted to kill the tab. It had locked up the entire browser for (Couldn't go to any other tab).

Running this on Windows, and the game loads in ~10 seconds.

If this is a size issue, then MacOS Chrome and Brave are just INSANELY slow to load things. Which doesn't seem right.
Also, since I'm running it locally, I assume the web assembly can load faster... This might be untrue, but I doubt that it is.

In that case, it might be shader loading and/or conversion (correct me if I'm wrong, but MacOS converts stuff to ANGLE behind the scenes, doesn't it?)

In that case, it might be shader loading and/or conversion (correct me if I'm wrong, but MacOS converts stuff to ANGLE behind the scenes, doesn't it?)

I also think may be a shader compilation issue. Chrome definitely uses ANGLE, but I am not sure about Brave. macOS doesn't use ANGLE when running on desktop though.

While attempting to fix the gl_compatibility renderer on macOS I experimented with using ANGLE, but found that the shader compilation times ended up increasing by over 100X. In #70065 I was able to speed up shader compilation times and get gl_compatibility working on macOS without ANGLE. However, since chrome uses ANGLE, my guess is we are hitting those pathological shader compilation issues anyway. I am not sure what exactly in the shader is causing the issue (it may even be a bug in ANGLE).

Related #65696

The issue of Chrome crashing on MacOS 13 does indeed exist, and Firefox takes over 2 minutes to load.

I'm completely new to C++ dev, but I would like to help with this issue.
What can I do to help?

Can confirm, 4.0 RC2 is still taking minutes to load on Brave on MacOS.. Causes my entire browser to lock down completely.

The issue still persists in rc4, rc5, rc6. In Forward+, Mobile, and Compability mode. Chrome hangs, Firefox takes a while but loads, and Safari has a infinitely loading spinner and reports the following in the console:

[Error] Unhandled Promise Rejection: CompileError: WebAssembly.Module doesn't parse at byte 1155: can't get 1th argument Type
	promiseEmptyOnRejected
	promiseReactionJob
> Selected Element
< <html lang="en">…</html>
[Error] still waiting on run dependencies:
	onPrintError (tmp_js_export.js:14008)
	(anonymous function) (tmp_js_export.js:737)
[Error] dependency: wasm-instantiate
	onPrintError (tmp_js_export.js:14008)
	(anonymous function) (tmp_js_export.js:739)
[Error] (end of list)
	onPrintError (tmp_js_export.js:14008)
	(anonymous function) (tmp_js_export.js:742)

In the latest version of Godot Engine 4 (RC 6), the game still completely freeze internet browsers (tested on Chrome and Firefox and MacOS 13.2.1). Will a stable version of Godot really be released today with such a bug?

Just to confirm - this issue does occur on Godot 4.0 stable, viewing the web export in Chrome 110 on macOS 13.2 on a MacBook Pro 2023 M2. A project containing only a very simple 2D pixel art scene takes 70s to load initially. Is it possible to find a workaround until this is fixed, e.g. strip shaders from the web export?

Is it possible to find a workaround until this is fixed, e.g. strip shaders from the web export?

No, other than staying on Godot 3.x.

(PS: Modern OpenGL/WebGL rendering always uses shaders, no matter how much your custom build is stripped. This is also the case in Godot 3.x.)

I extracted the shaders from godot 4.0 from the sample linked above and filed a bug. Only 19 shaders are compiled at startup but for some reason (didn't look into why) several shaders, 5 shaders take ~15 seconds each for a total of 1 minute at 15 seconds (on an M1 mac)

https://bugs.chromium.org/p/angleproject/issues/detail?id=8068

If you're curious I wrote this code

// extract-shader.js
(function() {
  const programs = [];

  function dumpPrograms(label) {
    if (programs.length) {
      if (label) {
        console.log('//', label);
      }
      console.log(JSON.stringify(programs));
      programs.length = 0;
    }
  }

  globalThis.dumpPrograms = dumpPrograms;

  for (const RenderingContext of [WebGL2RenderingContext, WebGLRenderingContext]) {
    RenderingContext.prototype.linkProgram = function(origFn) {
      return function(prg) {
        console.log('// link', programs.length);
        const shaders = this.getAttachedShaders(prg);
        programs.push(shaders.map(sh => {
          return {
            type: this.getShaderParameter(sh, this.SHADER_TYPE),
            src: this.getShaderSource(sh),
          };
        }));
        origFn.call(this, prg);
      };
    }(RenderingContext.prototype.linkProgram);

    for (const name of ['clear', 'drawArray', 'drawElements', 'drawArraysInstanced', 'drawElementsInstanced']) {
      RenderingContext.prototype[name] = function(origFn) {
        return function(...args) {
          dumpPrograms();
          origFn.call(this, ...args);
        };
      }(RenderingContext.prototype[name]);
    }
  }
})();

And then I added <script src="extract-shaders.js'></script> to the top of the html file and I added importScripts('extrac-shaders.js') to the worker (as I wasn't sure which one uses WebGL, the main thread, the worker, or both). I also added a call to dumpShaders in the onmessage code in the worker and in the onPrint function in the main thread JavaScript since the sample above does so little that I wasn't sure WebGL is actually being called.

In any case, you can use code like this to extract shaders and then code like the one in the chromium bug report to make a minimal repo.

So looking into this more, it appears to be an issue with ANGLE running on top of the MacOS OpenGL drivers. Chrome is working to switch over to ANGLE running on top of Metal. You can test that path with

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --use-cmd-decoder=passthrough --use-angle=metal --user-data-dir=<some-random-folder>

In which case the shaders compile faster. Hopefully that will ship soon.

You can verify which backend ANGLE is running on by going to about:gpu

ANGLE running on OpenGL:

GL_RENDERER: ANGLE (Apple, Apple M1 Max, OpenGL 4.1 Metal - 83)

ANGLE running on Metal:

GL_RENDERER: ANGLE (Apple, ANGLE Metal Renderer: Apple M1 Max, Version 13.2.1 (Build 22D68))

Yes, it's confusing that both strings say 'metal' 😅

This is fantastic @greggman -- can confirm the project now loads in seconds instead of minutes.

ANGLE (Apple, ANGLE Metal Renderer: Apple M2 Pro, Version 13.2 (Build 22D49))

So we just gotta wait for chrome/safari/brave to migrate to the new Metal Renderer?
Because there's no way I'm gonna get my players to run their browser with that special command haha!

So we just gotta wait for chrome/safari/brave to migrate to the new Metal Renderer?

correct...

Or you can try to adjust the shaders so they don't provoke the issue in the Apple OpenGL drivers, or pray Apple updates their OpenGL drivers.

If you want to update the shaders in the short term, lowering MAX_LIGHTS lowers the compile time. The issue is probably the way Apple's OpenGL driver handles UBOs. Their might be other work arounds, I'm not sure.

Is it possible to fallback to the way Godot 3.x handled web exports while we wait for browsers to migrate to Metal?

If you want to update the shaders in the short term, lowering MAX_LIGHTS lowers the compile time. The issue is probably the way Apple's OpenGL driver handles UBOs. Their might be other work arounds, I'm not sure.

Which value did you test for MAX_LIGHTS, and how much did it speed loading? Looks like it's hardcoded in these 2 places (if you're referring to 2D rendering):

uint32_t max_lights_per_render = 256;

DEFAULT_MAX_LIGHTS_PER_RENDER = 256,

Is there a way we could expose a project setting, then add a web override to decrease it by default in HTML5 exports? This could cause 2D lights to visually break after exporting to HTML5 (depending on the number of lights present in the scene), but it's better than having very long load times.

Is it possible to fallback to the way Godot 3.x handled web exports while we wait for browsers to migrate to Metal?

No, as 3.x featured entirely different and incompatible rendering backends (most notably a GLES2 backend, which is much simpler and more limited).

Given this isn't the only shortcoming of the HTML5 export in 4.x, it may be worth looking into creating a 4to3 project converter. This way, you can downgrade a Godot 4 project to Godot 3 until the HTML5 export matures (and then use 3to4 to convert it back once that happens). This could take a long time to be fixed upstream after all.

commented

Probably a worse case of this #56670 (3.x 3D web)

Hi I just wanted to share my frustration with the bug reported on #72584. In 3.x exporting to Web was a safe way to ensure your game was playable on many platforms.

Web exports for a very minimal 2D game are unable to be played in chrome on a MAC, however interestingly enough Safari seems to work. It's very unfortunate because web exports being cross platform was a huge selling point for me.

I look forward to progress on this.

@Xwaffle1 Please don't bump issues without contributing significant new information. Use the 👍 reaction button on the first post instead.

(Remember that commenting creates a notification for everyone watching the repository. If you want to subscribe to an issue without commenting, click the Subscribe button in the sidebar.)

There's also the workaround described here which you can try by modifying some values in the engine source code, then compiling a custom HTML5 export template: #70691 (comment)
Testing this workaround and making sure it works will help this issue be resolved faster.

commented

This looks fixed on the latest macOS Ventura (13.3.1) using Safari (16.4). I'm running this on a 2021 M1 Macbook Pro. I tested a variety of scenes both with Godot 4.0.2 and Godot 3.5.2 with the WebGL2 export. Safari uses Metal and not ANGLE for WebGL2 and perhaps that's why the behaviour is different.

The only error I get in the console is
[Error] USER WARNING: Project setting: rendering/limits/global_shader_variables/buffer_size exceeds maximum uniform buffer size of: 16384
which is mitigated by changing the project setting to the recommended value.

Firefox still hangs for a bit before loading the scene. Running a CPU Profile reveals that most of the work is stalling on some sort of shader introspection from a GL library. Which means that Firefox is running on a GL layer.

SCR-20230421-ucoh

The recommended Chrome workaround (#70691 (comment)) works for me.

In general there is quite a bit of variability, but given the majority of people are probably using Chrome this is still dependent on them switching to the Metal backend.

With 4.1 in RC state, is this receiving any love? Safari seems to do the right thing so one can always point at that, but this may still catch people out by surprise.

Won't get any focus until after 4.1 is released, only high impact bugs and crashes get much focus at that stage, unless this is a trivial fix and someone finds it pretty much immediately

I guess I meant if this was somehow lost in the changelog that I missed but yeah, thanks for the update anyway :)

If the issue is open it hasn't been fixed :) no PR has been linked to this so no fix seems to be in progress right now, keep looking here for updates like that

If the issue is open it hasn't been fixed :) no PR has been linked to this so no fix seems to be in progress right now, keep looking here for updates like that

I guess the confusion comes from the fact that issues such as this leave a strong indication that it would be worked on for 4.1. While that is now clearly not the case, perhaps a better indication of a timeline for investigation/fix could be added to the documentation, just so people embarking on potential new projects can plan accordingly?

How does an issue on a separate repository indicate anything about the priorities in this one? This issue is clearly marked "4.x", and no PR has been opened for this so no solution is clear.

perhaps a better indication of a timeline for investigation/fix could be added to the documentation

We don't track these things in the documentation, that's what the issues here are for

If the issue is open it hasn't been fixed :) no PR has been linked to this so no fix seems to be in progress right now, keep looking here for updates like that

I guess the confusion comes from the fact that issues such as this leave a strong indication that it would be worked on for 4.1. While that is now clearly not the case, perhaps a better indication of a timeline for investigation/fix could be added to the documentation, just so people embarking on potential new projects can plan accordingly?

It might be helpful for you to circle back on previous comments in this thread. The issue here is with Chrome's implementation of ANGLE on MacOS. We are waiting for them to resolve the issue upstream. The Godot Project has no influence over Google's release cycles, nor do we have special insight into them. So we unfortunately can't give you a timeline when Google will be shipping a fix, nor can we speed up the timeline.

I would suggest for someone affected by this issue to make a clear MRP (both a ready-to-test demo available online, and the source with instructions on how to export using Godot) and report the bug upstream to Chromium: https://bugs.chromium.org/p/chromium/issues/list

It would be important to include information from that comment: #70691 (comment)
i.e. that --use-angle=metal solves the issue, but is sadly not the default behavior as of current Chrome releases on macOS.

They hopefully track this internally, but some user reports confirming that the current status quo is not satisfactory can help them prioritize. I see some existing upstream issues about slow WebGL performance on Chrome macOS, but not specific to Godot, so it could be good to add one.

Another option is the more "end user bug report" pipeline with https://support.google.com/chrome/answer/95315?hl=en&co=GENIE.Platform%3DDesktop - a bunch of users each reporting that a readily accessible online project runs terribly on Chrome while it runs well on Safari and Firefox will likely help prioritize further.

How does an issue on a separate repository indicate anything about the priorities in this one? This issue is clearly marked "4.x", and no PR has been opened for this so no solution is clear.

Apologies for the confusion, that was more on the path of arriving here from discussions on various platforms; it was all about setting the right expectations, since posts on Twitter and the documentation itself leave the impression that this is either a temporary issue or something being worked on.

If that is not the case and it's all dependent on Google fixing Chrome and Mozilla fixing Firefox, then that's all fine and good to know, but it needs to me made clear so we go and fill the right bugs and follow-ups for those platforms as necessary (as well pointed out below by @akien-mga). For example, the documentation currently mentions "Safari has several issues with WebGL 2.0 support that other browsers don't have, so we recommend using a Chromium-based browser or Firefox if possible", which is exactly opposite at the moment, with Safari being the only functional browser in macOS. Perhaps a note there that Safari works and Chrome/Firefox need upstream fixes would help point people in the right direction?

Thank you and sorry again for any confusion.

If that is not the case and it's all dependent on Google fixing Chrome and Mozilla fixing Firefox

It isn't though, because web builds made with Godot 3.5.2 don't have this problem. Maybe at some point changes to Firefox and Chrome will make the issue go away, but I rather doubt developers working on those projects consider addressing Godot regressions to be their job.

@soundgnome Try GLES3 on Godot 3, you should have the same issue. It's a WebGL 2 support issue in Chromium, which relies on deprecated OpenGL drivers for ANGLE instead of the modern Metal backend that Apple developed and contributed to Google for ANGLE.

I would suggest for someone affected by this issue to make a clear MRP (both a ready-to-test demo available online, and the source with instructions on how to export using Godot) and report the bug upstream to Chromium: https://bugs.chromium.org/p/chromium/issues/list

Thank you for the suggestion, there appear to be actually two issues there that reference this problem:

  1. One opened by @greggman from the above comments in March -- https://bugs.chromium.org/p/angleproject/issues/detail?id=8068
  2. An older one referencing issues with Godot and WASM specifically (but having to do with WebGL); rather than creating a new issue, I've added a test project and steps for reproducing to that second issue -- https://bugs.chromium.org/p/chromium/issues/detail?id=1324296

Hopefully, this will attract the attention of the right people who can either fix the problem or work on switching to the Metal renderer.

I stirred up a wasps nest – sorry! But at least we have pointers to go poke Google in the right places so thank you! :)

EDIT: Nice of them to comment on the issue just a few hours ago confirming the intention of shipping the Metal backend very soon! 🎉

I don't understand why this issue is being deferred to the Google and the browser vendors. Obviously this is a breaking change on the Godot project. If web exports work in 3.5.2 this is a breaking change. The Godot project scrapped the stable WebGL1.0 export pipeline in favor of broken WebGL2.0. Its fairly well known that WebGL2.0 is not yet stable or widely adopted with browser vendors.

Ideally I would assume here that Godot would offer a stable WebGL1.0 exporter from the 3.5.2 line and then introduce a new unstable WebGL2.0 exporter. Is it possible to restore the WebGL1.0 pipeline? I'm assuming this not trivial because during the 3 -> 4 major version change some architectural changes.

I don't understand why this issue is being deferred to the Google and the browser vendors.

WebGL 2.0 works nicely on a lot of platforms already, and it has been doing so for years. The other platforms are the ones that need to be fixed 🙂

Ideally I would assume here that Godot would offer a stable WebGL1.0 exporter from the 3.5.2 line and then introduce a new unstable WebGL2.0 exporter. Is it possible to restore the WebGL1.0 pipeline?

This would mean recreating a GLES2 renderer from scratch and maintaining it separately from the existing GLES3 and Vulkan renderers (no code can be reused across GLES2 and modern renderers). We don't have enough rendering contributors to be able to maintain that – the existing 3 rendering methods are already proving challenging to maintain.

If you absolutely need WebGL 1.0, Godot 3.x will remain supported for a while.

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --use-cmd-decoder=passthrough --use-angle=metal --user-data-dir=<some-random-folder>

every <some-random-folder> I've tried hasn't worked. Does somebody have a more specific example?

image
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --use-cmd-decoder=passthrough --use-angle=metal --user-data-dir=<some-random-folder>

every <some-random-folder> I've tried hasn't worked. Does somebody have a more specific example?

image

That's a permissions issue in your Mac configuration. This works fine at least in my computer.

Respectfully, this isn't simply an issue of the game taking a while to load — running a Godot 4 web game causes my entire browser to become unresponsive until I manage to kill the tab, which is hard to do when it causes simple tasks like changing tabs, opening right click menus or closing tabs to take 8-12 seconds.

If solving the issue is reliant on fixes over which you have no control, might it be possible to warn OSX Chrome users before starting the loading process?

If solving the issue is reliant on fixes over which you have no control, might it be possible to warn OSX Chrome users before starting the loading process?

Given Chrome user agents are now frozen, there's no longer a way to warn users of a specific browser version without also impacting users with a newer browser version that has the bug fixed. This means that the warning would be displayed for every Chrome user on macOS, even if it's not relevant for them in the future. (We could make the warning only display once using localStorage, but it can still be an annoyance for those in private browsing mode.)

In short: you can detect that someone is using Chrome and macOS, but you can't distinguish between the current version (say, 114) and a future version with the bug resolved (say, 120).

For what it's worth, you can use javascript to identify whether the browser is running Angle on OPEN GL

const gl = document.createElement("canvas").getContext("webgl");
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);

// => 'ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)'

It's not a great solution, but you could potentially prevent your application from loading if it detects an incompatibility. I haven't tested this in practice.

For what it's worth, you can use javascript to identify whether the browser is running Angle on OPEN GL

Unfortunately, it's not enough to test for ANGLE, but for the specific case of using the Metal renderer -- a @greggman notes above:

ANGLE running on OpenGL:
GL_RENDERER: ANGLE (Apple, Apple M1 Max, OpenGL 4.1 Metal - 83)
ANGLE running on Metal:
GL_RENDERER: ANGLE (Apple, ANGLE Metal Renderer: Apple M1 Max, Version 13.2.1 (Build 22D68))
Yes, it's confusing that both strings say 'metal' 😅

But this might be useful to look for "ANGLE Metal Renderer" specifically, and perhaps show an alert or some red warning text? It's not about incompatibility, but slowness in loading (i.e. 1-2 minutes even, depending on shaders used), which causes the browser to "lock".

So, for mac users, we can open Godot web games by opening Chrome with this command:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --use-cmd-decoder=passthrough --use-angle=metal

Note that you must make sure Chrome is completely 100% quit before running it this way or you can pass in another profile

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --use-cmd-decoder=passthrough --use-angle=metal --user-data-dir=<some-random-folder>

Source

So, for mac users, we can open Godot web games by opening Chrome with this command:
(...)

Yes, this was taken from a comment higher up here. However, in the meantime it has become less relevant, since developers on macOS can easily test using Safari -- which works fine and comes included with the OS.

The problem remains for end-users, who are not going to switch browsers or run arcane Terminal invocations in order to test a game or demo on e.g. itch.io, and that can only be solved by Chrome itself...

commented

However, in the meantime it has become less relevant, since developers on macOS can easily test using Safari -- which works fine and comes included with the OS.

@mgc8 It seems like there's still a high degree of relevance to opening an alternative Chrome profile since opening in Safari suffers from the issue described here (which in turn links to this comment from higher up in this thread).

I'm not able to test the build of my simple game in normal Chrome or Safari; Chrome with the --use-profile=metal flag is the only way that I've been able to play an HTML5 export (alt: waiting several minutes for the FF build to load).

@mgc8 It seems like there's still a high degree of relevance to opening an alternative Chrome profile since opening in Safari suffers from the issue described here (which in turn links to this comment from higher up in this thread).

The comment and bug referenced there are very old and pertain to macOS 13.2, while the current version is 13.4. Latest Safari (16.5) has no issues whatsoever playing the "MinimalProject.zip" included in report #74512:
Screenshot 2023-07-30 at 02 12 28

I'm not able to test the build of my simple game in normal Chrome or Safari; Chrome with the --use-profile=metal flag is the only way that I've been able to play an HTML5 export (alt: waiting several minutes for the FF build to load).

I can run my own projects as well as official demos without issues or delays in the current version of Safari. Do you have a build/demo of your game that fails we could test with?

As a side-note, new versions of Firefox (at least since around 112+) have also improved considerably in playing Godot games, the delay on load is only about 30 seconds now (with additional few seconds every time new shaders need to be compiled). The only big problem remains with Chrome, which indeed locks up and takes many minutes in the default (non-Metal) pathway.

As a side-note, new versions of Firefox (at least since around 112+) have also improved considerably

In my case:

  • macOS: 13.1 (22C65) Intel Core i5
  • Firefox: 115.0.3 (64-bit)

This project with just a few images takes 1:20 minutes to load

In Safari (16.2 (18614.3.7.1.5)), the same project above doesn't show any signal to load. I waited 2:00 minutes.

In iPad Chrome or Safari Godot4 web exported projects also don't load. I assume it is the same for iPhone

A bigger project like this (with shaders):

In the above Firefox took ... don't know, I waited 3:00 minutes still loading

As a side-note, new versions of Firefox (at least since around 112+) have also improved considerably
In my case:

  • macOS: 13.1 (22C65) Intel Core i5
  • Firefox: 115.0.3 (64-bit)

Ouch, looks like you last updated that machine over six months ago! Current macOS Ventura version is 13.5 and Safari 16.5.

This project with just a few images takes 1:20 minutes to load

It takes about 45 seconds for me -- but yes, Firefox is still slow and needs more fixes to be properly functional in this context. However, it used to completely lock the tab and/or error out, so the fact that it at least loads and works now is good progress.

In Safari (16.2 (18614.3.7.1.5)), the same project above doesn't show any signal to load. I waited 2:00 minutes.

This is a known problem on itch.io specifically, because they insist on using the wrong headers for Safari, as reported here (assuming you've already enabled the SharedArrayBuffers support):
https://itch.io/t/2025776/experimental-sharedarraybuffer-support#post-7852760

Screenshot 2023-07-31 at 01 00 47

... but in your case that is a moot point, as you need to use a recent version of Safari anyway (the bugs discussed here were fixed in 16.4 which was released back in March):
https://bugs.webkit.org/show_bug.cgi?id=247860

You don't need to upload your games to itch.io in order to test functionality, you can do that locally much faster by running a simple HTTP server in the Web build directory (the one containing your "index.js" file) like the following in a server.py, then using Safari to go to http://localhost:8000:

#!/usr/bin/env python3
from http import server # Python 3

class MyHTTPRequestHandler(server.SimpleHTTPRequestHandler):
        def end_headers(self):
                self.send_my_headers()
                server.SimpleHTTPRequestHandler.end_headers(self)

        def send_my_headers(self):
                self.send_header("Access-Control-Allow-Origin", "*")
                self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
                self.send_header("Cross-Origin-Opener-Policy", "same-origin")

if __name__ == '__main__':
        server.test(HandlerClass=MyHTTPRequestHandler)

In iPad Chrome or Safari Godot4 web exported projects also don't load. I assume it is the same for iPhone

That is another kettle of fish altogether, i{pad}OS is not macOS and i{pad}OS Safari is not the same as the desktop version; plus there is no difference with Chrome in i{pad}OS, it's just Safari but with a different UI. There currently is at least one known bug that prevents Godot 4 working properly with it -- the "Out Of Memory" one referenced in #70621 -- but the workaround presented in that issue can be used to make it functional: manually setting the memory size to 256MiB instead of the default 2048MiB. The secondary WebAssembly SIMD issue mentioned there was solved since 16.2 as well. You can use the same kind of script as above to test with that too, but there is an added complication that it needs SSL as well if not connecting to localhost (a relatively simple change).

A bigger project like this (with shaders):

That's a fun game, by the way, refreshing take on the Arkanoid genre! It loaded in Firefox for me after about 2:12 minutes, with another delay caused by screen transitions (probably due to new shaders being loaded there each time). It plays well, but crashes after the tutorial with a console error (same in Chrome on Windows).

Here it is running perfectly in Safari though, with no crashes even (using the above localhost solution):
Screenshot 2023-07-31 at 01 27 46

... and it also worked great on an iPad, by the way, using the memory workaround described above!

So, at this point in time at least, for macOS users and especially developers, Safari is the best bet for running Godot 4 games. itch.io needs to fix their headers, and Chrome needs to fix their default render pathways, for sure, but those are not really things Godot can influence much...

You don't need to upload your games to itch.io in order to test functionality, you can do that locally much faster by running a simple HTTP server in the Web build directory (the one containing your "index.js" file) like the following in a server.py, then using Safari to go to http://localhost:8000/:

Note that we have a similar script in the Godot repository already: https://github.com/godotengine/godot/blob/master/platform/web/serve.py

itch.io needs to fix their headers

Would godotengine/godot-proposals#6616 be usable on itch.io as a workaround?

itch.io needs to fix their headers

Would godotengine/godot-proposals#6616 be usable on itch.io as a workaround?

It should, and from testing it does appear to set the right headers, but for some reason when loaded through itch.io the app still doesn't "see" them. Could be due to being inside an iFrame, or a conflict between the headers set by itch.io and the ones set in JavaScript?

As a side-note, while experimenting with this I noticed that if you right-click and open just the iFrame for the game in a separate tab/window, the headers are set fine (with "require-corp") and it works nicely in Safari -- case in point, the game posted a bit earlier:
https://html.itch.zone/html/8415314/coco_and_frogy_web_v1.0.15/index.html

It should, and from testing it does appear to set the right headers, but for some reason when loaded through itch.io the app still doesn't "see" them. Could be due to being inside an iFrame, or a conflict between the headers set by itch.io and the ones set in JavaScript?

After some thorough testing, I think I tracked down the issues with itch.io (there were two):

  1. coi-serviceworker.js itself has a bug that reverses the 'credentialless' and 'request-corp' options, thus (sigh) only affecting Safari, since Chrome and Firefox work with either one; reported here

  2. itch.io complicates the header situation due to the way the "game" pages are configured:

  • If the "experimental SharedArrayBuffer" option is not selected, the main page will have no headers, while the iframe can set them fine (such as with our service-worker script), but the browser will not activate the "crossOriginIsolated" status because the parent container needs to have it as well. If the main page had been loaded on the same domain as the iframe, this would not have been an issue, since the service-worker would have taken that over as well (tested locally) and overridden the headers. But on itch.io they are on different hostnames, thus an iframe service-worker can't touch the parent.
  • If the experimental option is selected, then the main page will have headers, but hardcoded to 'credentialless'; meanwhile, the iframe can override its own headers with the service-worker and send the correct ones for each browser (i.e. 'credentiallless' for Chrome and 'request-corp' for Safari). This will work fine in Chrome or Firefox, but Safari doesn't see the parent page as being properly isolated due to the 'credentialless' there, which our service-worker again cannot override; thus it breaks.

So, for now, the "open iframe in its own tab/window" option remains as a workaround, while itch.io could improve the situation by adding a bit of browser-detection code to switch between 'credentialless' and 'request-corp' as needed, though I'm not sure if they have any inclination to do that.

Thanks @mgc8, all this is great support for all the suffering mac Godot users like me

I'm not sure why it disappeared, but I can confirm that the Chrome flags suggestion posted earlier works great in Chrome 116.0.5845.179/macOS/M1, and is an easier temporary workaround rather than the Terminal version of the same (at least until the Chrome devs make Metal the default):
Screenshot 2023-09-09 at 21 50 47

commented

So, for now, the "open iframe in its own tab/window" option remains as a workaround

On itchio, you should assume that at some point your game will be required to be loaded in an iframe that has been generated by itch.io. A solution that involves breaking out the frame is not a long term fix because we have system in place to automatically inject site locking to prevent shady third-party platforms from embedding our games to steal bandwidth.

while itch.io could improve the situation by adding a bit of browser-detection code to switch between 'credentialless' and 'request-corp' as needed

Unfortunately require-corp has a bunch of side effects with regards to any external references on the page, and may impact how the site operates, so the solution isn't simply change the value of the header. This is why we opted for credentialless since it's mostly transparent solution, but the browser compatibility is not ideal.

I think our long term fix (assuming safari never supports the header) will probably involve launching the game in a separate page containing only an iframe and different headers specific to safari, instead of trying to execute the game on the full project page.

Edit: Was double checking the code and it looks like this was already implemented for the Game Embed tool located in the uploader's dashboard. If they generate an embed URL from there, it will provide a link to the game that will use require-corp instead of credentialless. Example game URL: https://itch.io/embed-upload/8831158?color=1e0e11 (note url may not work in the future if this particular developer removes their game)

Edit2: I deployed a fix that will cause Safari to always load games in a new window using the embed URL I described above that uses the require-corp header value. Should resolve any issues for Safari users, at the expense of slightly different user experience.

On Newgrounds, SharedArrayBuffer support works in Safari as well as the other major browsers (tested with the same build of the same project, etc.). I'm not sure which method they've used, however, or if it would translate easily to itch, if it would be useful to look into, or who over there to ask about it if it would be useful.

Edit: I should note my test wasn't with a Godot game, but a plain jane Emscripten build of a C program—the underlying issue appears to be the same.

Edit2: I deployed a fix that will cause Safari to always load games in a new window using the embed URL I described above that uses the require-corp header value. Should resolve any issues for Safari users, at the expense of slightly different user experience.

Hi @leafo, thank you for dropping by! This looks like a good, pragmatic solution given the current state of browsers, with every major one seemingly having a different, incompatible issue related to this. I can confirm that the "new window" works nicely for itch.io games in Safari, so at least that's solved now for end-users. Hopefully the browser developers will also move on with updates/fixes to make the whole process less frustrating for both site owners and game devs (three months later, Chrome still hasn't switched to Metal as default back-end on macOS)...

The "new window" solution works great on desktop! On mobile, it gives me a 404 error in the new tab (tried iOS and iPadOS, both Safari and Chrome, but did not try Android).

As of right now me using IOS doesn't seem to load my game that used Godot4, so even with the Embed game link it doesn't work.
Not sure if there will be a fix anytime soon but at least it works on pc for now.

Hi there @leafo , thank you so much for the fix and for creating the website indie devs know and love!

In recent exports, the new window in safari appears to give 404. This seems to indicate that the generation of the embed link is not working correctly. Is there anything users can do to specify the embed link, or otherwise make the new window use the correct embed link? This is on a laptop M1 Mac.

commented

@revanj

In recent exports, the new window in safari appears to give 404. This seems to indicate that the generation of the embed link is not working correctly. Is there anything users can do to specify the embed link, or otherwise make the new window use the correct embed link? This is on a laptop M1 Mac.

Is your safari configured to block cookies in any way? A cookie is combined with the generated link to verify access to the popup

commented

@revanj

In recent exports, the new window in safari appears to give 404. This seems to indicate that the generation of the embed link is not working correctly. Is there anything users can do to specify the embed link, or otherwise make the new window use the correct embed link? This is on a laptop M1 Mac.

Is your safari configured to block cookies in any way? A cookie is combined with the generated link to verify access to the popup

My safari is fresh out of the box and shows the same issue.

Screenshot 2023-11-28 at 22 21 01

It seems to be way better when exporting using the single-threaded export template. #85939

Maybe on Chrome, but now it takes forever on Firefox/macOS.

As an update, it does appear that Chrome is now using the Metal renderer by default now. I am using Chome 123.0.6312.59 and I have verified that the Angle Metal renderer is being used. I have not changed any flags or set a custom profile.

Also the "image rendering issue" renders without issue.
https://arturitoproductions.itch.io/testingimageissue (password: godot)

I also use Brave but it still not updated to use the Angle Metal Renderer. I suspect its only a matter of time for the other browsers to follow suit.

As an update, it does appear that Chrome is now using the Metal renderer by default now. I am using Chome 123.0.6312.59 and I have verified that the Angle Metal renderer is being used. I have not changed any flags or set a custom profile.

Also the "image rendering issue" renders without issue. https://arturitoproductions.itch.io/testingimageissue (password: godot)

I also use Brave but it still not updated to use the Angle Metal Renderer. I suspect its only a matter of time for the other browsers to follow suit.

Thank you very much for updating us! I suspect firefox and brave should update soon to match, but I worry that safari is still a long ways off. At any rate, having everything work well on the others puts us in a much better position.

commented

Also the "image rendering issue" renders without issue. https://arturitoproductions.itch.io/testingimageissue (password: godot)

That demo locks up my Chrome, but no longer locks up my computer.

It will sit there like this for a long time:
Screenshot 2024-03-27 at 10 03 43

Screenshot 2024-03-27 at 10 05 04 Screenshot 2024-03-27 at 10 06 10

Interesting that this appears to be a CPU bound issue, why is that?

@tavurth The screenshot you posted indicates you need to relaunch Chrome for chrome version you've listed to take effect. I might try relaunching chrome and trying again. The other difference is that I am using an ARM (M1) machine, but I can't see why that would matter.

Once you've restarted Chrome, can you open the console and run the following commands and share the output:

const gl = document.createElement("canvas").getContext("webgl");
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);

FWIW, on my machine, I see:

ANGLE (Apple, ANGLE Metal Renderer: Apple M1 Pro, Unspecified Version)

That's interesting. Can I ask what chrome version?

Looks like its M* related though - I have what chrome says is latest as of today: 123.0.6312.87 on an intel macbook pro and a M3 macbook pro and I get:

Intel: ANGLE (ATI Technologies Inc., AMD Radeon Pro 5300M OpenGL Engine, OpenGL 4.1)

M3: ANGLE (Apple, ANGLE Metal Renderer: Apple M3 Max, Unspecified Version)

commented

On my M1 laptop the build with a few number labels from here https://arturitoproductions.itch.io/testingimageissue opens quickly on Chrome, but slowly on Firefox. And on Safari it's popping up a new itch.io window, which gives a 404 error :)

Firefox has likely not adopted the Angle Metal renderer as their default yet.

It may be the same with the latest version of non-ARM Chrome installs. If the x86 (intel based) installs of chrome are not yet defaulted to Angle Metal renderer, then we'll have to wait a bit longer for Godot 4 web exports to work as expected for all mac users. As of today, it should be working for M1, M2, M3 mac users with the latest version of chrome

I believe the Safari 404 issue is unrelated (there's some discussion above about a missing required header on itch.io)

commented

The screenshot you posted indicates you need to relaunch Chrome for chrome version you've listed to take effect

Yep, was just keeping the version the same as you listed in your original post. Now it's:

Screenshot 2024-03-27 at 23 02 58

And the result of the GPU probe:

'ANGLE (Intel Inc., Intel(R) Iris(TM) Plus Graphics 655, OpenGL 4.1)'

It appears the new chrome default has only been applied to ARM based macs. intel based macs may have to wait a bit longer. Still, it's promising that these changes are slowly trickling out