Bug 234303 - Varying rAF during WebGL video upload on iPod touch 7, iOS 15.2
Summary: Varying rAF during WebGL video upload on iPod touch 7, iOS 15.2
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebGL (show other bugs)
Version: WebKit Local Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-12-14 10:42 PST by Kimmo Kinnunen
Modified: 2022-01-06 07:36 PST (History)
6 users (show)

See Also:


Attachments
screen recording (18.12 MB, video/quicktime)
2021-12-14 10:44 PST, Kimmo Kinnunen
no flags Details
iPhone 12 Pro Screen Recording (26.25 MB, video/quicktime)
2021-12-15 04:26 PST, Simon Taylor
no flags Details
Screenshot of Timeline Recording in web inspector (195.34 KB, image/png)
2021-12-15 04:56 PST, Simon Taylor
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kimmo Kinnunen 2021-12-14 10:42:36 PST
From Simon Taylor:
> No noticeable improvement in iOS 15.2 on the iPod touch 7 that I generally use for testing.
> There's also some weirdness I have noticed where the page doesn't always call rAF at 60FPS, even though frame timings remain ~5ms and Timelines in web inspector suggest there are sufficient resources - just looks like the callback rate is being throttled.
> This may not be new in 15.2 (I've seen weirdly throttled simple WebGL content in earlier iOS 15 releases too) but this seems readily reproducible here - navigating to one of the demo pages by tapping the links from this bug report seems to load it in some sort of throttled mode, which survives refresh / back-forward / etc. Killing Safari and re-opening and we're back up to 60FPS. It's almost like each navigation ends up with a different rAF callback rate. I'll attach a screen recording.
> Is this just the new normal with GPU process and Metal backend or is there any point hoping for improvements? iOS 15 has definitely made life much harder for those of us trying to ship smooth interactive WebGL experiences for mobile.
Comment 1 Kimmo Kinnunen 2021-12-14 10:44:11 PST
Created attachment 447142 [details]
screen recording
Comment 2 Simon Taylor 2021-12-15 03:30:55 PST
Thanks for splitting off this one Kimmo (sorry for not doing so originally).

This also reproduces pretty readily on an iPhone 12 Pro with iOS 15.2 (I annoyingly forget to try before doing the update to see if it was in 15.1.1 too). Not just older hardware or iPod-specific.

It haven't been able to reproduce on iPhone 12 mini, iOS 14.8.1.

There might be other relevant bugs around mistaken rAF throttling - I've got a vague memory of some chatter around tabs not being correctly flagged as "foreground" in some cases and getting some of the background tab throttling behaviours applied.

I'll do a quick test case without the video (just gl.clear() with a color cycle) and see if that is still affected.
Comment 3 Simon Taylor 2021-12-15 04:02:05 PST
Here's the quick color cycle test:
https://tango-bravo.net/webkit-bug-234303/clear_color_cycle.html

And the RGBA video upload again:
https://tango-bravo.net/WebGLVideoPerformance/texImage2d_video_rgba.html

Will follow up with whether I can reproduce when the links are in the bugzilla page - what's weird is both of these pages run at 60FPS when going back and forth from my local test server's index page...
Comment 4 Simon Taylor 2021-12-15 04:26:25 PST
Created attachment 447221 [details]
iPhone 12 Pro Screen Recording

Screen recording from an iPhone 12 Pro.

It looks like it only reproduces with the video link, but also only when not using the local dev server.

It appears consistently the second time when visiting the link that's hosted on the web. I suspect the dev server prevents caching, and the web one doesn't - perhaps in this case webkit tries to re-awaken a saved state of the overall page that causes some change in behaviour?
Comment 5 Simon Taylor 2021-12-15 04:56:46 PST
Created attachment 447223 [details]
Screenshot of Timeline Recording in web inspector

One final observation - when pausing the video, we jump back up to 60 FPS.

So one more random theory - perhaps it's not throttled, but it's not correctly hooked back up to a v-sync timer for rAF in those cases. As a fallback, it just schedules the next rAF for 16.66ms later. That looks legit from the timeline recording in Web Inspector...
Comment 6 Simon Taylor 2021-12-15 05:08:48 PST
I did also try moving the rAF call up to the top of the draw function, but it still leaves the 16.66ms gap after the end of that function.
https://tango-bravo.net/WebGLVideoPerformance/texImage2d_video_rgba_early_raf.html

From WebInspector it appears the frame time alternates based on whether there's a new video frame or not, so it does look like that fix for part of the regression of #231031 is working correctly - thanks for that!
Comment 7 Kimmo Kinnunen 2021-12-15 06:17:58 PST
Reproduced on iPad Pro 2015

To reproduce bug:
- restart Safari
- navigate to the bugzilla page bug 231031
- open the link (for rgba test case)

-> observe consistent sub-60fps reports on most loads

To reproduce working scenario
- copy the rgba test case to clipboard
- restart Safari
- paste the link directly to safari

-> observe consistent 60fps reports

So the buggy behaviour needs some other page to be loaded before. It is unclear which page features trigger the problem.

The buggy vs non-buggy cases have similar looking CPU traces.
Comment 8 Simon Taylor 2021-12-15 09:38:44 PST
Another way to trigger this is just to navigate away from the page (just enter a new URL), and then hit back.

Here's another simpler reproducer - it's a simple gl.clear() in the draw call, but then with a busy loop that waits until (performance.now() > frameStart + 8):

https://tango-bravo.net/webkit-bug-234303/clear_color_cycle_busyloop.html

I'd thought it might be related to caching options, but here's one with "Cache control: no-store" that still reproduces readily:

https://tango-bravo.net/webkit-bug-234303/clear_color_cycle_busyloop_nocache.html

I'm pretty confident in my diagnosis that the buggy behaviour involves waiting 16.66ms after one rAF callback completes before triggering the following one, rather than basing timing on screen refresh.

Does feel something to do with bringing a recent closed tab back to life that skips setting up the CADisplayLink properly.
Comment 9 Simon Taylor 2021-12-16 03:58:02 PST
Here's an even simpler reproducer which doesn't actually do anything other than busy-loop for 8ms in its rAF callback:
https://tango-bravo.net/webkit-bug-234303/raf_busyloop.html

Could it perhaps have something to do with content process isolation, when switching back to an existing content process from another domain? (I don't even know if WebKit does that but know it's a thing in Chrome)

This appears to be the behaviour, 100% reproducible from a clean start (Safari killed, no tabs open, even cleared all data and rebooted first but this isn't necessary):

1) Visit this bugzilla page
2) Click any of the links to any of the demos on this page
3) Note rAF loop runs at 60 FPS
4) Back to this page
5) Click any other link to the same domain (doesn't need to be the same page)
6) Note rAF now runs at <60 FPS. <60FPS persists through refresh, background / foreground app switch, history navigation.
7) Kill Safari (still with tab open) and re-open. Back to 60 FPS.

Copying/pasting the URL from a <60FPS tab into a new one also gets 60FPS, so seems something to do with the Tab & Domain combo that is affected.
Comment 10 Simon Fraser (smfr) 2021-12-16 10:32:24 PST
Seems like we need a new bug filed which is not related to WebGL.
Comment 11 Radar WebKit Bug Importer 2021-12-21 10:43:33 PST
<rdar://problem/86775843>
Comment 12 Simon Taylor 2022-01-06 07:36:37 PST
(In reply to Simon Fraser (smfr) from comment #10)
> Seems like we need a new bug filed which is not related to WebGL.

I've added Bug 234923 now the wider scope of the issue is clear. Feel free to close this one as a dupe of that.