xterm.js icon indicating copy to clipboard operation
xterm.js copied to clipboard

WebGL rendering is broken on Safari Preview

Open prusnak opened this issue 3 years ago • 26 comments

Details

  • Browser and browser version: Safari 14.1
  • OS version: macOS 11.3 (Apple Silicon)
  • xterm.js version: 4.11.0 (gotty 1.3.0)

Steps to reproduce

  1. install xterm.js with webgl addon
  2. open the page in Safari
  3. observe missing letters, just background colors can be seen
  4. Chrome and Firefox work fine

prusnak avatar Jun 02 '21 08:06 prusnak

@prusnak Do you get any output at all? I think you should not - as far as I know Safari does not implement Webgl2 at all. Or did they change that recently?

jerch avatar Jun 02 '21 09:06 jerch

I did get the output - the background color of characters was rendered correctly. It's hard to see if the background is the same color everywhere, but if you use colorful output one can see that.

I run the following script:

for x in {0..8}; do
    for i in {30..37}; do
        for a in {40..47}; do
            echo -ne "\e[$x;$i;$a""m\\\e[$x;$i;$a""m\e[0;37;40m "
        done
        echo
    done
done

Chrome:

Screenshot 2021-06-02 at 11 53 50

Safari:

Screenshot 2021-06-02 at 11 53 56

prusnak avatar Jun 02 '21 09:06 prusnak

I think you may need to switch in webgl2 via an experimental feature in Safari. I'm not sure if that changes on M1.

Tyriar avatar Jun 02 '21 10:06 Tyriar

I think you may need to switch in webgl2 via an experimental feature in Safari. I'm not sure if that changes on M1.

Ah, it was actually the opposite :-)

I had WebGL 2.0 enabled in experimental settings and turning it off fixed the issue for me.

Feel free to close the issue if you want to.

prusnak avatar Jun 02 '21 10:06 prusnak

Ah ok, I guess that's why it's experimental then 😄. If it's off, loading the addon will throw and it will revert back to the DOM renderer.

Tyriar avatar Jun 02 '21 12:06 Tyriar

We're seeing this on ipad and the safari preview still

Tyriar avatar Aug 09 '21 15:08 Tyriar

@meganrogge and I looked into this just now, here's what we found:

  • The issue is just with rendering of text, not backgrounds (see the green above which is webgl powered)
  • The uploaded texture appears correct when getImageData is used and inspected on the browser side, but using the texture in the fragment shader doesn't seem to work
  • Using vec4(1.,0.,0.,1.) here shows red where the glyphs should show as expected: https://github.com/xtermjs/xterm.js/blob/522c8bf3afcc296f7586c21b097025fe3626dc32/addons/xterm-addon-webgl/src/GlyphRenderer.ts#L69
  • Also using vec4(v_texcoord,0.,1.) looks as expected (differing shades of red)
  • outColor = vec4(u_texture, vec2(v_texcoord.x, 1.-v_texcoord.y)) shows all black

Tyriar avatar Aug 09 '21 17:08 Tyriar

This is now happening for release versions of Safari.

Is there someway the WebGL renderer can be disabled for Safari until there's a fix?

only-cliches avatar Sep 22 '21 23:09 only-cliches

I’ve encountered this in iPadOS15. Once WebGL2.0 is disabled, it start to work again..

IMG_0578

shohey1226 avatar Sep 23 '21 04:09 shohey1226

for safari, we don't enable webgl https://github.com/microsoft/vscode/blob/aa93bc5e86dc929f07c5bfa51771c43664d15bdd/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts#L1589

meganrogge avatar Sep 27 '21 15:09 meganrogge

This seems to be a problem with the newly released Safari 15 on macOS Big Sur 11.6 as well...

LinusU avatar Oct 08 '21 12:10 LinusU

This is open for anyone to investigate why it's happening, the current recommendation is to disable the webgl extension on Safari.

Tyriar avatar Oct 08 '21 13:10 Tyriar

I guess this issue can be related to https://github.com/xtermjs/xterm.js/issues/3357 (it's also Safari, iOS, WebGL 2.0 is enabled by default).

bushev avatar Oct 12 '21 11:10 bushev

@bushev did you mean to paste in a different issue?

FWIW the PR linked above will now cause the webgl addon to throw when you try to activate it on Safari as a temporary workaround.

Tyriar avatar Oct 12 '21 12:10 Tyriar

Got it, the issue I've pasted just looks similar to this rendering issue, since some characters are missing in the console. But disabling od WebGL 2.0 doesn't help to solve #3357.

bushev avatar Oct 14 '21 19:10 bushev

The check in https://github.com/xtermjs/xterm.js/blob/master/src/common/Platform.ts#L21:

export const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);

doesn't seem to catch WKWebView, which is the browser engine powering Safari. Safari's user agent string (on an iPad) is:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15

Whereas WKWebView's user agent string (on an iPad) is:

Mozilla/5.0 (iPad; CPU OS 15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148

This is causing the demo on https://xtermjs.org to not show any content in WKWebView. I've reported this at https://github.com/xtermjs/xterm.js/issues/3575 but I'm also mentioning it here in case it's relevant.

litherum avatar Dec 14 '21 05:12 litherum

Rendering was finally fixed in iPadOS 15.4 Safari and both canvas and the WebGL add-on work without a single char disappearing.

After spending 6 months with the sluggish DOM renderer WebGL feels very fast. I did some performance testing and while it ran out of memory after adding the 8th parrot, until then I felt no performance hit. You can see for yourself in the clip I uploaded: seven dancing parrots and the invaders from space.

daonb avatar Mar 31 '22 12:03 daonb

... while it ran out of memory after adding the 8th parrot ...

@daonb Any pointers/traceback where things went overboard with 8th parrot?

jerch avatar Mar 31 '22 12:03 jerch

That's exciting if this will be fixed in the upcoming Safari!

Tyriar avatar Mar 31 '22 14:03 Tyriar

@daonb Any pointers/traceback where things went overboard with 8th parrot?

I suspect Safari ran out of canvas memory as it always does when I keep opening panes. All the parrots freeze and I there's no more canvas output. I added an onContextLoss handler with a console log but got nothing. I also tried without the WebGL addon and got the same frozen parrots so it can either be an out of memory issue or a sneaky Terminal7 bug

daonb avatar Mar 31 '22 14:03 daonb

I'm not sure I've seen the browser refusing to hand out GPU memory but that would be my guess as well.

Tyriar avatar Mar 31 '22 14:03 Tyriar

Are those panes full terminal instances (no clue how you do the multiplexing)? Because a single terminal instance can get quite demanding, depending on scrollback settings/buffer fillstate and/or incoming data pressure (without proper flow control). Then you might run into some sort of resource limits from the browser engine's JS context (could be any of RAM allocation, CPU perf, GPU limitations).

jerch avatar Mar 31 '22 14:03 jerch

@jerch pretty sure they're each individual instances

Tyriar avatar Mar 31 '22 14:03 Tyriar

Are those panes full terminal instances (no clue how you do the multiplexing)?

Yes they are - whenever the user splits a terminal he gets a new terminal and a new WebRTC data channel. I should probably run a more focused benchmark - in this one each parrot comes from curl parrot.live so it also loads the network. I'd love to hear any suggestions how to better test performance and the limitations.

daonb avatar Mar 31 '22 17:03 daonb

As stated in https://github.com/xtermjs/xterm.js/issues/3357#issuecomment-1084531272 this is fixed in the current safari version. I just want to confirm that it works fine for me in Safari Version 15.4 (17613.1.17.1.13) with WebGL 2.0 enabled.

r10r avatar May 13 '22 09:05 r10r

Also works for me on 15.4 after removing this:

https://github.com/xtermjs/xterm.js/blob/d29388394c60cef40dc0aa4aece9aad94ac46945/addons/xterm-addon-webgl/src/WebglAddon.ts#L28-L30

Let's keep the workaround there for a while until 15.4+ is more widely spread https://caniuse.com/usage-table

Tyriar avatar May 13 '22 12:05 Tyriar

Let's keep the workaround there for a while until 15.4+ is more widely spread https://caniuse.com/usage-table

Safari tells you which version it's running via navigator.appVersion (e.g. navigator.appVersion.match(/Version\/([0-9.]+).*Safari/)[1] => "15.6"). A much better workaround would be to only disable the WebGL addon on versions lower than 15.4.

aeriksson avatar Oct 21 '22 07:10 aeriksson