-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove supportsWebGL2EntryPoints #9919
Remove supportsWebGL2EntryPoints #9919
Conversation
375f5f1
to
3194635
Compare
7c5c477
to
a6a0686
Compare
Argh, now I realize can't quite leverage the full potential until we have a setting to opt out from WebGL1 support altogether. I was hesitating to add a Until that happens, this PR can make a partial step towards that though. |
Chrome 69 for desktop has a 0.4% market share. No idea what the Chrome 57 market share is, but I imagine it's at least 10% of that. I think it would be crazy to try and support such old versions of Chrome, especially at the detriment of other users. Not to mention the maintenance burden. So I'm definitely in support of PRs like this 👍. |
a6a0686
to
ebcf568
Compare
@kripken: how do you feel about the |
For another example, e1cab71 |
Posted PR #9937 to illustrate the idea. Some people want to target ancient browsers, others want to rely on the newest and greatest. This would allow catering to everyone. Also later under the hood we could adjust limits automatically, e.g. when targeting Wasm, that would imply Edge >= 16, Firefox >= 52, Chrome >= 57, Safari >= 11 and IE not supported. |
I think I like this idea. Presumably we could use the default setting of each of these to document an absolute lower bound on each, and move that forward over time as we completely remove support for certain older browsers. The main downside is that it adds N more settings to our already numbers configuration matrix. Is there some way we could matrix dimensionality somehow while still being intuitive, or is one setting per browser the only logical way to express this? i.e. would a single ES version, or year not be granular enough? |
The reason why I like this browser version specific check is that that matches most often with what people are thinking about. That is, users report bugs that "did not work on IE11/Chrome 76/Safari 11.0.1", and devs make decisions "we don't support IE" etc. Also I recommend this kind of check is kept light and more or less orthogonal. For example, I don't recommend we start building up complex features <-> browsers mappings and validations, so e.g. adding all kinds of I intend these checks are more like an easier way to remove cruft in JS libraries, for example I'd like a way to express when I'd be able to remove Also note that I don't think these Also I think these fields should obsolete |
ebcf568
to
f371b63
Compare
I think adding fine-grained options like this is ok, but I think we should also keep |
src/settings.js
Outdated
// contain polyfills and backwards compatibility for Chrome >= 58 and newer. Set this to a small value to target old browsers, and to a high value to reduce code size | ||
// by dropping polyfill support for older browsers. Default to 0 to mean "all Chrome versions" (although in practice a large number of features require a specific much | ||
// newer Chrome version, e.g. Wasm or WebGL 2) | ||
var OLDEST_SUPPORTED_CHROME_VERSION = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about MIN_CHROME_VERSION
?
More importantly, I think this should have a reasonable default, which is to not support super-old browsers. Like how LEGACY_VM_SUPPORT
is optional, and not the default. We shouldn't by default suffer too much for ancient browsers.
However, as this is the actual version, that implies we'd need to update it from time to time. Maybe that's not so bad. Anyhow, as a starting version, it might be 58 as that is a useful value here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think perhaps leave tuning the initial defaults for later once all of them have landed, and when LEGACY_VM_SUPPORT
can migrate to preconfiguring OLDEST_SUPPORTED_X_VERSION
values?
MIN_CHROME_VERSION
sounds ok too, I'll rename to that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be more disruptive to change MIN_CHROME_VERSION
from 0 to 58 (or such) later, because it kind of changes the actual use and meaning of the flag - from "optionally change this to not support old browsers" to "optionally change this to yes support old browsers".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer if the default option were to only support "current" Chrome versions - that is, the last ~3-6 months of Chrome releases (relative to the release date of a version of Emscripten). Realistically, how sure are we even that the rest of Emscripten works on browsers that old? - given, I assume, most developers are not actively testing that far back. And there are very few users on old Chrome versions (<1%).
Maybe this is not in line with the philosophy of the project. I have run across quite a bit of code in Emscripten to handle old browsers, which I would like to remove if it were possible.
Anyway, if you don't want to add that, then defaulting to 58 (now) would be an OK option to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realistically, how sure are we even that the rest of Emscripten works on browsers that old?
I target Samsung Galaxy S2 and Samsung Galaxy Nexus with Chrome 33, iPhone 4S with Safari 8.0, and Raspberry Pi Zero underclocked to 200MHz as the lowest end devices, mostly because they are extremely good performance profiling targets for tiny 2D "Candy Crush" games (and run at 30-60fps). Emulations are needed for performance.now()
, requestAnimationFrame()
, fonts, landscape/portrait rotation and especially audio, but things work well on those even.
Most of these tiny playable games are on the order of NES/C64 level of graphical complexity, and if you wanted to run an ad as a playable using asm.js/wasm with Emscripten, you'd really like it to tax only a few % of your browser's gigahertz scale CPU capacity, so it is an useful exercise to look at scaling to ancient browsers.
The only hard limit I have seen so far is on Android 4.3 and older with built-in browser AppleWebKit/534.30 and older, for some reason that completely misparses and misexecutes asm.js code which I was never able to figure out. There are also unfortunate issues with new Chrome and Firefox versions, where sometimes the old built-in browser that ships with a device works better than newest Chrome or Firefox, understandably due to expired lack of testing.
tests/test_other.py
Outdated
@@ -9509,6 +9509,7 @@ def test_minimal_runtime_code_size(self): | |||
'-s', 'GL_SUPPORT_EXPLICIT_SWAP_CONTROL=0', | |||
'-s', 'GL_POOL_TEMP_BUFFERS=0', | |||
'-s', 'FAST_UNROLLED_MEMCPY_AND_MEMSET=0', | |||
'-s', 'OLDEST_SUPPORTED_CHROME_VERSION=58', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we switch to 58 as suggested earlier as the default value, this line can be removed.
@@ -9531,7 +9532,7 @@ def test_minimal_runtime_code_size(self): | |||
(opts, hello_world_sources, {'a.html': 968, 'a.js': 604, 'a.wasm': 86}), | |||
(asmjs + opts, hello_webgl_sources, {'a.html': 881, 'a.js': 4918, 'a.asm.js': 11139, 'a.mem': 321}), | |||
(opts, hello_webgl_sources, {'a.html': 857, 'a.js': 4874, 'a.wasm': 8841}), | |||
(opts, hello_webgl2_sources, {'a.html': 857, 'a.js': 5507, 'a.wasm': 8841}) # Compare how WebGL2 sizes stack up with WebGL 1 | |||
(opts, hello_webgl2_sources, {'a.html': 857, 'a.js': 5362, 'a.wasm': 8841}) # Compare how WebGL2 sizes stack up with WebGL 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wow, that was a big cost for backwards compatibility...
I think this change OK to land, but I do think we risk making testing harder. Since the stated purpose is to be able to strip the JS code using the equivalent of Perhaps if we come up with simple testing strategy that we can follow. Perhaps something like: for each location where we modify generated JS code based on a specific browser version we need a test for that part of the code in both configurations. ? |
src/library_webgl.js
Outdated
@@ -526,6 +526,18 @@ var LibraryGL = { | |||
webGLContextAttributes['preserveDrawingBuffer'] = true; | |||
#endif | |||
|
|||
#if USE_WEBGL2 && OLDEST_SUPPORTED_CHROME_VERSION <= 57 | |||
// BUG: Workaround Chrome WebGL 2 issue: the first shipped versions of WebGL 2 in Chrome did not actually implement the new WebGL 2 functions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this comment is old, but can we elaborate in the comment? I'm pretty sure (cab6be0) this was about the srcOffset+length versions of various entry points which were added to WebGL 2 (possible added to the spec after Chrome shipped, I don't remember). And were there really no versions of Firefox that shipped WebGL 2 without these entry points?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Firefox did ship with the new entry points from the first version of WebGL 2 forward. It was only Chrome that missed the new entry points.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this comment is old, but can we elaborate in the comment?
check.
src/settings.js
Outdated
// contain polyfills and backwards compatibility for Chrome >= 58 and newer. Set this to a small value to target old browsers, and to a high value to reduce code size | ||
// by dropping polyfill support for older browsers. Default to 0 to mean "all Chrome versions" (although in practice a large number of features require a specific much | ||
// newer Chrome version, e.g. Wasm or WebGL 2) | ||
var OLDEST_SUPPORTED_CHROME_VERSION = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer if the default option were to only support "current" Chrome versions - that is, the last ~3-6 months of Chrome releases (relative to the release date of a version of Emscripten). Realistically, how sure are we even that the rest of Emscripten works on browsers that old? - given, I assume, most developers are not actively testing that far back. And there are very few users on old Chrome versions (<1%).
Maybe this is not in line with the philosophy of the project. I have run across quite a bit of code in Emscripten to handle old browsers, which I would like to remove if it were possible.
Anyway, if you don't want to add that, then defaulting to 58 (now) would be an OK option to me.
That link is for desktop only - is there public data on mobile? (modifying the graph there doesn't seem to support that) I worry about older Android versions with non-updating Chrome, stuff like that. But I agree in general - supporting 99% of Chrome users by default seems fine, and to get really old legacy versions, a flag would be needed. That's basically what |
I don't have any stats offhand. Unfortunately for some reason that site doesn't track browser versions on mobile. Old Android devices that stop getting Android updates do continue getting Chrome updates for quite a long time as long as they're using the Play Store. Last I heard Chrome still supports back to Android 4.4 (2013), though it could have advanced slightly since then. |
My understanding matches Kai's, and I agree we should set sensible defaults here and not try to support older browser with a tiny userbase (not by default anyway). Hopefully we can use real usage number to drive this. |
Let's try to get Chrome telemetry (UMA) data about this. I don't know how to query UMA to get the data we need, so one of us will have to try to figure it out. |
For my use case dropping older browsers would be great. I'm using pthreads, which depends on SharedArrayBuffer + Atomics, so I can't support older browsers anyway. |
f371b63
to
b6c44ae
Compare
I really dislike the whole That is why I think we should just remove LEGACY_VM_SUPPORT altogether. It does not serve the user, because I don't think there really exists a binary "I want to support old things" or "I don't want to support old things" choice by the developer, but they need to define what "old" means for them, and then they need to cross-reference and research whether their understanding of "old" matches LEGACY_VM_SUPPORT's understanding of old. That is why I think these browser version specific checks are more exact and accurate, and people can then in straightforward fashion add cmdline flags that match what they are thinking. "I don't support IE -> -s MIN_IE_VERSION=-1". But @sbc100 does raise a good point:
Writing code for #if MIN_IE_VERSION <= 8
{{{ makeSetValue('width', '0', 'rect.right - rect.left', 'double') }}};
{{{ makeSetValue('height', '0', 'rect.bottom - rect.top', 'double') }}};
#else
{{{ makeSetValue('width', '0', 'rect.width', 'double') }}};
{{{ makeSetValue('height', '0', 'rect.height', 'double') }}};
#endif is very easy to do and very easy to maintain, but writing tests for both parts is very hard and time consuming to do and maintain, and adds to the test suite run time. That is why I recommend to avoid these kinds of combinatorial testing, and instead focus on just testing the defaults. If someone finds a bug in a specific combination of the old paths, then we can add testing reactively. |
Ok so we will continue to do most of our testing with only default MIN_VERSIONs and occasionally add specific tests as need for older combinations. That sounds feasible for us, but a little sad for our users who will be running code that the CI never runs. But to be fair we don't run out tests against older browsers either so... We might want to warn people when stray from the tested path: "You chose a non-default, and possibly less-tested browser version combo", if not at compile time at least in the documentation? |
@juj I'm confused about your strong objection to cc @Brion for thoughts on |
Ah, yeah, that sounds good to me. |
ed2b023
to
3682d49
Compare
Rebased this on top of incoming, good for re-review. |
src/library_webgl.js
Outdated
// If not chrome, fall through to return undefined. (undefined <= integer will yield false) | ||
} | ||
if (getChromeVersion() <= 57) { | ||
WebGL2RenderingContext = undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- How does hiding this prototype definition actually cause Emscripten to disable WebGL 2? (Maybe a comment to explain why it works)
- That said, I would prefer if we didn't modify the page global state. Is there a way we can disable Emscripten's use of WebGL 2 without doing that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good points both. Updated to avoid modifying global page state.
…urden on code size. Reduces -15.9% of code size (997 bytes) in https://github.com/juj/webgl_render_test for WebGL 2. Introduce new setting -s OLDEST_SUPPORTED_CHROME_VERSION=x to enable customizing which Chrome versions to target.
…o MIN_CHROME_VERSION
1de4c28
to
5b7bc11
Compare
5b7bc11
to
1a7ba44
Compare
* Remove support for WebGL 2 in Chrome 57 due to its high maintenance burden on code size. Reduces -15.9% of code size (997 bytes) in https://github.com/juj/webgl_render_test for WebGL 2. Introduce new setting -s OLDEST_SUPPORTED_CHROME_VERSION=x to enable customizing which Chrome versions to target. * Update other.test_minimal_runtime_code_size * Fix chrome version test, and rename OLDEST_SUPPORTED_CHROME_VERSION to MIN_CHROME_VERSION * Update comment on old Chrome 57 not supporting WebGL 2 GC free entry points * Remove duplicate MIN_CHROME_VERSION
Just two cents - Safari 14 (which is still the latest stable release) has an "Experimental WebGL 2.0" option which triggers the same scenario as removed It's a pity that there is no more place to put a workaround for this broken Safari... (hopefully this bug will be fixed in closest Safari updates).
|
@gkv311 That issue should be fixed on Safari Tech Preview, I remember having a video call with their engineers about this issue some months ago. So when their Experimental WebGL 2 reaches stable release, they should be working properly on this front. |
This test is designed to verify the minimum code size so I can't see why we would want to enable support for an older browser here (potentially triggering the inclusion of polyfills). This was added #9919 but its not clear to me why.
Remove support for WebGL 2 in Chrome 57 due to its high maintenance burden on code size. Reduces -15.9% of code size (997 bytes) in https://github.com/juj/webgl_render_test for WebGL 2. Introduce new setting -s OLDEST_SUPPORTED_CHROME_VERSION=x to enable customizing which Chrome versions to target.