xeokit / xeokit-sdk

Open source JavaScript SDK for viewing high-detail, full-precision 3D BIM and AEC models in the Web browser.
https://xeokit.io
Other
728 stars 287 forks source link

Performance regression on iPad Air with IOS 14.2 #482

Closed xeolabs closed 3 years ago

xeolabs commented 3 years ago

Seems IOS 14.2 breaks xeokit performance.

My guess is that there's a breakage in IOS 14.2 that prevents it from optimizing one of xeokit's shaders.

Debugging Plan

See which of these examples shows the performance regression:

  1. PerformanceModel geometry batching with edges
  2. PerformanceModel geometry batching without edges
  3. PerformanceModel geometry instancing with edges
  4. PerformanceModel geometry instancing without edges
  5. PerfromanceModel with Entity#offset disabled
tmarti commented 3 years ago

Any progress on this one?

Could be related to this? => https://bugs.webkit.org/show_bug.cgi?id=218949

xeolabs commented 3 years ago

No progress yet, but investigations are ongoing. It appears the issue, with regard to xeokit, is not specific to instancing.

I'm going to set up a github project with a test page that can be switched between experimental xeokit builds via a URL parameter, to try and isolate what is triggering the bug in iOS. For there, we can hack things out of xeokit, add a build to that project, then we can try iOS/Air with various engine builds.

tmarti commented 3 years ago

Ok! So ours seems a different problem seemingly not related to xeokit.

Tested with massive instancing example for three.js and same slowness in certain iOS devices, but fine on Android.

I set up a PoC of our xeokit viewer disabling usage of instancing yesterday (by "expanding" the instances in xkt-loader-plugin with some matrix magic) and will get feedback during this morning 🙂

Thanks for the input 😃

tmarti commented 3 years ago

Also, now that this issue has attention.

How do you guys to analyze GL shader performance with xeokit on the mobile?

Tried loads of tools in the past (Mac PC + connexted iOS device browser) with 0% luck.

xeolabs commented 3 years ago

@tmarti I've not used any mobile perf analysis tools myself - if you find any, would be curious what..

xeolabs commented 3 years ago

@tmarti I've starting making xeokit examples here, to isolate what's causing the issue. Each test has a different copy of xeokit, with a different bit of functionality disabled/removed.

An exhaustive divide-and-conquer process should uncover things.

https://xeokit.github.io/xeokit-perf-test/

Let us know if you get good perf on any of these on iPad/Air!

lasselaakkonen commented 3 years ago

This it should probably be renamed to something like "Performance issue on iOS devices" or since it seems be related to the CPU/GPU "Performance issue on iPad/iPhone A14 Bionic devices".

As we have discussed elsewhere, testing with these https://xeokit.github.io/xeokit-perf-test/ and the links from the original post, Xeokit renders below 1FPS with at least:

The issue seems to not have been reproduced on at least:

Safari vs Chrome vs Firefox does not seem to have affected the performance tests (.. or are all browsers on iOS actually forced to run the same engine underneath the hood or something?).

lasselaakkonen commented 3 years ago

Perhaps only an interesting coincidence, but running this https://dusanbosnjak.com/test/webGL/three-instanced-mesh/webgl_instanced_mesh_v4.html:

20 000 instances, dynamic=on

20 000 instances, dynamic=on, colors=on

Which matches the same "A14 Bionic performs badly and older/lower perf devices work fine"-pattern.

tmarti commented 3 years ago

Hello 🙂

See this thread https://bugs.webkit.org/show_bug.cgi?id=218949.

To me looks like Apple got a regression (maybe firmware, maybe drivers) on iOS 14, and the thread comes to confirm this has been confirmed to be mitigated at the WebKit side (the browser engine for iOS browsers and WebViews) 🎉

The enablement of ANGLE Metal backend on iPhone seems to fix the immediate performance issue here

To the reporters: we're collaborating as quickly as possible to shake out the bugs from ANGLE's Metal backend that Apple's made tremendous improvements to. That sounds like it will be the fastest resolution to this device-specific performance issue.

My impression is that enablement of ANGLE Metal Backend can be done very easily with native iOS applications using e.g. Swift or Objective-C, and this this reason some teams were able to release a patch for their native apps/games (by adjusting a setting on some *RenderingContext internal class (checked related commits in public WebKit repo)).

But in the WebGL case.... as we don't have control on some internal Apple class from the browser, it takes the WebKit Team to do it for us, so we need to wait.

The guess is that we need to stay tuned to that bugzilla thread and wait for next release news on a next iOS version 👀

tmarti commented 3 years ago

Just in case you're curious about the related changesets in WebKit, those are...

... which are not obvious to indentify from the bugzilla tracker in previous message in this thread 😉

lasselaakkonen commented 3 years ago

I commented this in the Webkit bug tracker https://bugs.webkit.org/show_bug.cgi?id=218949:

Assuming that the issue is on all devices with A14 Bionic chips.

  1. Since Kimmo was able to reproduce the issue on 2020-11-16 in https://threejs.org/examples/webgl_interactive_cubes.html using an iPhone 12 and now the issue can not be reproduced on that page with a iPad Air 4th gen 2020, it would mean that issue would have been fixed in Three.js?

  2. Since for example all of these work at FPS 60 on an iPad Air 4th gen 2020, Three.js has fixed / worked around the issue somehow?

So if those assumptions are correct, facts are correct and Three.js has had the same issue as Xeokit. Then, since Three.js has made changes in the library in the past 5 months, which have fixed the issue, then Xeokit could in theory do the same changes as well?

tmarti commented 3 years ago

Hello @lasselaakkonen,

Your question is a bit trappy 😉

since Three.js has made changes in the library in the past 5 months, which have fixed the issue, then Xeokit could in theory do the same changes as well?

In theory yes the same could be done with xeokit, but as that seems a regression on some Apple code, I'm afraid the side effects (like this reduced FPS on xeokit) are highly webgl-usage dependant: three.js might have solved for its usage patterns as you mention, but I've seen other engines based on recent versions of three.js (extended use of shaders, some more dynamic geometry loading/unloading) that suffers from same frame rate drop, but in that case only for very concrete models 🙂

So again, think it's a bit webgl-usage dependant, but cannot 100% tell w/out looking at the involved changes in WebKit (yes, all browsers and WebViews in AppStore seem forced to be based in WebKit browser engine to be approved for passing Apple validation) in iOS 14 (it could be also a regression in some parts with private code, we cannot tell w/out official notice from Apple).

Humble opinion, but @xeolabs tried many things to workaround this, and the fact that WebKit is about to release a patch mitigating the problem kind of publicly admits the problem is general and not "concrete application specific".

Hope that makes sense for you 🙂

But hey, I don't talk in the name of anyone, just some reflections after also stumbling upon this problem and finding zero Apple official responses 🤗

xeolabs commented 3 years ago

I'll need to dig through the THREE commits to see what their work around is there.

BTW a WebGL dev on twitter mentioned that they switched their private WebGL renderer from glDrawElements to glDrawArrays, which helped (https://twitter.com/caiiiycuk/status/1382369727952093184).

This change is also possible in xeokit, but would increase the XKT file size and viewer memory footprint, since glDrawArrays does not use a indices array, and does therefore does not reuse positions (all primitives need to have their own set of positions, normals etc).

I'm going to deploy a quick and dirty experimental build of xeokit that uses glDrawArrays.

If that works OK on IOS, then I'll see if we can do a production release using glDrawArrays, though possibly as an optional workaround mode (since glDrawElements is preferable for lower memory footprint). Or maybe glDrawArrays is not a big deal, and OK to use all the time, we'll see.

xeolabs commented 3 years ago

Anybody got feedback after the latest IOS updates?

lasselaakkonen commented 3 years ago

It seems as though iOS 15 might fix the issue.

On an iPad Air 4th gen 2020, it seems that this https://xeolabs.github.io/xeokit-disable-offsets-spike/examples/animation_offsets_disabled.html and our app (which uses some not-latest-version of xeokit):

Similarly this https://github.com/xeokit/xeokit-sdk/issues/482#issuecomment-782833340 is also now smooth on iOS 15.0 beta 2. Since I don't have iOS 14 anymore on the device, I can't verify that it is still actually slow on that.

xeolabs commented 3 years ago

Closing - confirmed that this is issue was caused by Apple WebGL driver bugs, and has been fixed in iOS 15.