xterm.js
xterm.js copied to clipboard
WebGL rendering is broken on Safari Preview
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
- install xterm.js with webgl addon
- open the page in Safari
- observe missing letters, just background colors can be seen
- Chrome and Firefox work fine
@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?
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:
Safari:
I think you may need to switch in webgl2 via an experimental feature in Safari. I'm not sure if that changes on M1.
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.
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.
We're seeing this on ipad and the safari preview still
@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
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?
I’ve encountered this in iPadOS15. Once WebGL2.0 is disabled, it start to work again..
for safari, we don't enable webgl https://github.com/microsoft/vscode/blob/aa93bc5e86dc929f07c5bfa51771c43664d15bdd/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts#L1589
This seems to be a problem with the newly released Safari 15 on macOS Big Sur 11.6 as well...
This is open for anyone to investigate why it's happening, the current recommendation is to disable the webgl extension on Safari.
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 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.
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.
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.
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.
... while it ran out of memory after adding the 8th parrot ...
@daonb Any pointers/traceback where things went overboard with 8th parrot?
That's exciting if this will be fixed in the upcoming Safari!
@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
I'm not sure I've seen the browser refusing to hand out GPU memory but that would be my guess as well.
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 pretty sure they're each individual instances
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.
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.
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
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.