sokol icon indicating copy to clipboard operation
sokol copied to clipboard

WebGL Offscreen rending is (potentially) broken in latest Chrome on Mac M1 and MacOS 14.5.

Open stomanovski opened this issue 1 year ago • 8 comments

Ok, this is one is bizarre. I am not sure if it is a real regression in latest Chrome or it is something specific to my machine.

Test case: https://floooh.github.io/sokol-html5/offscreen-sapp.html Donuts are supposed to be rotating but they are stuck at the first frame. Same with the shadows example which also relies on offscreen rendering: https://floooh.github.io/sokol-html5/shadows-sapp.html

Happens only in Google Chrome on my MacBook Air M1. My Chrome version: Version 127.0.6533.73 (Official Build) (arm64), MacOS: 14.5 (23F79). All other browsers on all other platforms work fine. It definitely worked before on the same machine.

I deleted all of the browser cache, restored browser settings to default, deleted the Chrome apk and re-dowloaded it, deleted everything in "~/Library/Preferences", "~/Library/Caches", "~/Library/Saved Application State" and "/Library/Google".

So there is a chance that this is platform specific regression in Chrome or it is some weird configuration issue specific for my machine. I just can't think of anything else that I can reset. Unfortunately I don't have another Arm Mac machine to test with (my Intel MacBook is fine).

Anyway, I will appreciate if anybody else can test on Mac Arm (preferably M1) with latest Chrome or just if somebody has an idea what might cause Chrome to behave this way.

stomanovski avatar Jul 26 '24 07:07 stomanovski

Also the WebGPU version works fine: https://floooh.github.io/sokol-webgpu/offscreen-sapp.html. So I updated the title

stomanovski avatar Jul 26 '24 09:07 stomanovski

Yeah I can confirm. Just updated to Chrome 127 on my M1 Mac and I see the same issues. The Windows version works fine.

I'll try to find out more. Thanks for the ping!

floooh avatar Jul 26 '24 14:07 floooh

I wrote a Chromium ticket here:

https://issues.chromium.org/issues/355605685

...and have been asking around in WebGPU and WebGL chats. I'll update here with any news.

floooh avatar Jul 26 '24 15:07 floooh

Woah, in Safari Tech Preview I get a WebGL context lost in that demo. Super weird (but AFAIK both Chrome and Safari now use the same WebGL implementation based on ANGLE).

floooh avatar Jul 26 '24 15:07 floooh

Firefox Nightly works fine.

floooh avatar Jul 26 '24 15:07 floooh

Reproduced this in Edge latest (127) as well. MacOS, ARM CPU (M3).

morew4rd avatar Jul 26 '24 16:07 morew4rd

I'll try to look into this tomorrow from my side... here's a demo that works:

https://webgl2fundamentals.org/webgl/webgl-render-to-texture.html

...and from looking at the source it doesn't seem to do anything fundamentally different than sokol-gfx (offscreen framebuffer setup is pretty much the same).

Even though it's clearly a regression in Chrome, maybe it helps debugging the issue when finding out what combination of WebGL calls causes the issue (and maybe even implement a workaround in sokol-gfx if needed).

floooh avatar Jul 26 '24 16:07 floooh

Thank you for responding so quickly and managing to test it on similar hardware! I was almost convinced that it is specific problem with my machine only :) I found something else that is related, although it might need separate ticket to track: All of the WebGPU examples are broken in Safari on this M1 machine (Version 17.5 (19618.2.12.11.6)) There is at least output in the console, seems like an assert: [sapp][panic][id:91][line:5760]

stomanovski avatar Jul 26 '24 18:07 stomanovski

I added more info to the chromium ticket. But basically this seems to be wasm specific issues. JS rendering is fine.

stomanovski avatar Jul 27 '24 00:07 stomanovski

hmm, i found working wasm example: https://bevyengine.org/examples/3d-rendering/3d-shapes/ So I am no longer sure that it is wasm v JS codepath problem in the browser

stomanovski avatar Jul 27 '24 01:07 stomanovski

@stomanovski I'm pretty sure Bevy does not do any offscreen rendering in that example.

janhohenheim avatar Jul 27 '24 02:07 janhohenheim

@stomanovski I'm pretty sure Bevy does not do any offscreen rendering in that example.

hmm, how do they draw the shadow then?

stomanovski avatar Jul 27 '24 03:07 stomanovski

Looking at the Bevy sample in Safari, it seems to do offscreen rendering, but there are a lot of WebGL calls, hard to make sense of it. I'll try to build a simple reproducer today both in WASM and in JS.

floooh avatar Jul 27 '24 11:07 floooh

hmm, how do they draw the shadow then?

Oh, you're right. I take it back.

janhohenheim avatar Jul 27 '24 12:07 janhohenheim

Simple WASM reproducer: https://floooh.github.io/sokol-repros/deploy/chrome127-offscreen.html

(in new repo: https://github.com/floooh/sokol-repros)

...now working on the same thing in Javascript.

floooh avatar Jul 27 '24 13:07 floooh

...and a simple Javascript reproducer:

https://floooh.github.io/sokol-repros/js/chrome127-offscreen-js.html

I'll try to tinker with this now a bit to figure out why this example works but mine doesn't.

floooh avatar Jul 27 '24 14:07 floooh

The bug is triggered by setting the GL_MAX_TEXTURE_LEVEL here:

https://github.com/floooh/sokol/blob/6f8121e6aa523b0c0a3e9d7212073bab9a885e15/sokol_gfx.h#L8301

However, we cannot simply remove this call, because it is required for rendering into textures with multiple miplevels (see: https://github.com/floooh/sokol/issues/923).

However, I can probably still try to create a workaround which calls glTexStorage2D() (this call is not available on macOS GL, but could be used in an Emscripten specific code path).

Will look into this later today, or latest tomorrow.

floooh avatar Jul 27 '24 14:07 floooh

I can confirm that disabling the setting of GL_MAX_TEXTURE_LEVEL fixes the issue. @floooh It is really impressive how quickly you found the root cause! And thank you for the workaround while waiting for a proper fix from the chromium guys!

stomanovski avatar Jul 27 '24 20:07 stomanovski

I can confirm that disabling the setting of GL_MAX_TEXTURE_LEVEL fixes the issue.

Note that this only works for render target textures with one mip level (which should be the common case for offscreen rendering though).

I will try today if calling glTexStorage to explicitly allocate storage also works, if it doesn't I will only set the MAX_TEXTURE_LEVEL for textures with more than a single mipmap, to at least have a workaround for the common offscreen rendering case.

floooh avatar Jul 28 '24 10:07 floooh

PR with workaround:

https://github.com/floooh/sokol/pull/1087

...unfortunately the diff looks messier than it actually is, so here's what it does:

  • on Emscripten only, call glTexStorage for textures without initial data
  • ...and only call the glTexImage functions when glTexStorage hadn't been called

Eventually I'd like to modernize the GL texture initialization to generally use glTexStorage and glTexSubImage, but this requires a fallback path for macOS since GL 4.1 doesn't have the glTexStorage calls yet.

I'll test the PR on Windows and Linux too and then merge it later today.

floooh avatar Jul 28 '24 11:07 floooh

The workaround has been merged, and I'll update my affected web pages now.

I will keep the issue open though until an upstream fix in Chrome lands.

floooh avatar Jul 28 '24 12:07 floooh

Chrome 128 is rolling out now and contains the fix. Closing this ticket.

floooh avatar Aug 22 '24 09:08 floooh