Bug 229606 - Potential Memory Leak in Safari 15 (iOS)
Summary: Potential Memory Leak in Safari 15 (iOS)
Status: RESOLVED CONFIGURATION CHANGED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebGL (show other bugs)
Version: Safari Technology Preview
Hardware: iPhone / iPad Other
: P2 Critical
Assignee: Kimmo Kinnunen
URL:
Keywords: InRadar
Depends on:
Blocks: webglgpup
  Show dependency treegraph
 
Reported: 2021-08-27 03:50 PDT by Wayne Langman
Modified: 2022-06-23 14:11 PDT (History)
7 users (show)

See Also:


Attachments
Sample Code and Screenshots (238.52 KB, application/zip)
2021-08-27 03:50 PDT, Wayne Langman
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Wayne Langman 2021-08-27 03:50:56 PDT
Created attachment 436616 [details]
Sample Code and Screenshots

I've encountered an issue present in all versions of the iOS / Safari 15 betas seemingly related to gl.bindTexture().

I've included some sample code, a butchered version of a WebGLFundamentals.org example to save some time, which demonstrates the problem.

PSA: Flashing Images Warning! The demo switches between 2 textures rapidly (requestAnimationFrame) so if you're sensitive please keep this in mind.

In the first screenshot (safari_15_macos.png) you can see the expected results (stable memory ~114MB) on MacBook Pro (2016 model w/Radeon Pro 450 GPU) with:
MacOS 11.5.1
Safari Techology Preview 130
All 4 'GPU Process' options enabled
WebGL via Metal enabled

This is also consistent with previous versions of Safari and other browsers.

However, in the second screenshot (safari_15_ios.png), you can see the memory climb until the page either freezes or reloads, often to a blank page as the WebGL context has been lost.

This test was performed on an iPhone 7 Plus with iOS 15 Beta 7 and the default experimental settings enabled.

While this example might be somewhat contrived, there is no need to bind the texture every frame, there are many other practical examples where this is required. With this in mind, I believe this bug is a high priority, but feel free to update accordingly and/or correct any (incorrect) assumptions.

Also, please let me know if you require any additional information and if you'd like me to upload the traces (the two combined are ~250MB).
Comment 1 Kenneth Russell 2021-08-27 14:01:42 PDT
Could this be related to other earlier reported leaks where IOSurfaces were held on for too long? Bug 217581, Bug 218100 and Bug 217212 (which fixed the other two). I somewhat doubt it because this app's just dealing with several regular, non-IOSurface-backed textures.

There is a call to "webglUtils.resizeCanvasToDisplaySize(gl.canvas);" in the rendering loop; is this short-circuiting itself on this device or is it doing something?

Kimmo, would you be able to try reproducing this on-device? Everything looks fine on macOS 11.5.2 with Safari Technology Preview Release 130 (Safari 15.0, WebKit 16612.1.26.1.5). Chrome as well.

Aside: every time the Activity Monitor updates, the browser drops one or more animation frames.
Comment 2 Myles C. Maxfield 2021-08-27 16:52:26 PDT
On my phone running 19A340, the web process is stable at 84MB.
Comment 3 Myles C. Maxfield 2021-08-27 17:03:09 PDT
Wait a minute, if I remember correctly, GL isn't supposed to be using the GPU Process at all on iOS 15...
Comment 4 Kimmo Kinnunen 2021-08-30 06:32:52 PDT
Thanks for the report.
Yes, I can reproduce the issue with "GPU Process: WebGL" turned on. 
Note: in the shipping betas, this option is turned off by default.
Comment 5 Kimmo Kinnunen 2021-08-30 06:37:13 PDT
> I've encountered an issue present in all versions of the iOS / Safari 15 betas seemingly related to gl.bindTexture().

Wayne, if you have time and know this off-hand:
Is there a specific reason you think this is `bindTexture` related? E.g. were you able to turn off some of the code to stop the leak?
Comment 6 Wayne Langman 2021-08-31 04:26:33 PDT
Ah, thanks, this is good to know and puts less pressure on this issue (if this process indeed remains disabled by default). I lost track of what was actually enabled by default. Is there any way to reset the experimental settings to default on mobile or perhaps a resource somewhere that I can use to compare against mine?

When I initially put the sample together it appeared to only be occurring when I added ‘bindTexture’ to the render loop, which is why it was my first guess, but upon revisiting I believe this was in error. I can replicate this now simply by calling ‘drawArrays’ (only) in the render loop.

I’ve updated the summary to remove reference to ‘bindTexture’.
Comment 7 Kimmo Kinnunen 2021-08-31 04:55:28 PDT
Thanks for the clarification.

> I lost track of what was actually enabled by default. Is there any way to reset the experimental settings to default on mobile or perhaps a resource somewhere that I can use to compare against mine?

Unfortunately no. 
For the specific flags mentioned here, on most recent platforms and hardware:
GPU Process: Canvas Rendering On
GPU Process: Media On
GPU Process: Video Capture On
GPU Process: Audio Capture On
WebGL via Metal On
WebGL 2.0 On

Other similar off.
Comment 8 Radar WebKit Bug Importer 2021-09-03 03:51:17 PDT
<rdar://problem/82717132>
Comment 9 Brent Fulgham 2022-06-23 14:11:50 PDT
Adam and others confirmed this is resolved as of 4/28/2022.