| Summary: | Safari Tab freezes when creating too many webgl render calls without flushing | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Sebastian Dunkel <sebastian.dunkel> |
| Component: | WebGL | Assignee: | Nobody <webkit-unassigned> |
| Status: | NEW --- | ||
| Severity: | Normal | CC: | dino, kbr, kkinnunen, kpiddington, webkit-bug-importer |
| Priority: | P2 | Keywords: | InRadar |
| Version: | Safari 15 | ||
| Hardware: | iPhone / iPad | ||
| OS: | iOS 15 | ||
|
Description
Sebastian Dunkel
2022-04-29 05:19:16 PDT
I suspect this has already been addressed in top-of-tree WebKit with many other fixes that have been integrated. Submitter, does this happen on macOS with M1 hardware? That would make it easier to diagnose and confirm whether it's been fixed with Safari Technology Preview. On an M1 MacBook Pro (16-inch, 2021) with Safari 15.4 (17613.1.17.1.13) I can reach 33.500.000 draw calls in the test app and then the tab crashes and reloads. I can't reproduce the freezing behaviour on the Mac though, so I can't say for sure whether it is exactly the same problem. Turning off "WebGL via Metal" or flushing the GL context prevents the crashes on the Mac as well. The console shows similar error messages: // IOReturn IOGPUDevice::new_resource(IOGPUNewResourceArgs *, struct IOGPUNewResourceReturnData *, IOByteCount, uint32_t *): PID 62576 likely leaking IOGPUResource (count=135000) // virtual bool IOGPUResource::map(uint64_t): failed to create mapping. resType=0x0 // IOReturn IOGPUDevice::new_resource(IOGPUNewResourceArgs *, struct IOGPUNewResourceReturnData *, IOByteCount, uint32_t *): failed to create mapping. // static IOReturn IOGPUDeviceUserClient::s_new_resource(IOGPUDeviceUserClient *, void *, IOExternalMethodArguments *) failed to create resource Same behaviour with Safari Tech Preview (15.4, WebKit 17614.1.7.7) Looking at the code, it seems that we only flush when we exceed a resident resource count. Either this isn't being calculated right, or we need more flush conditions.
bool CommandBuffer::needsFlushForDrawCallLimits() const
{
return mWorkingResourceSize > kMaximumResidentMemorySizeInBytes;
}
We might need to tweak this to a maximum number of drawArrays calls too. 10k, maybe?
That seems reasonable though I would: 1) Count all draw calls, not just drawArrays calls. 2) Make the limit higher so long as that mitigates this reported problem - like 100K draw calls. 3) Write a WebGL conformance test that tries to expose the freezing. Please note that similar bugs were found in the past: https://github.com/KhronosGroup/WebGL/blob/main/sdk/tests/conformance/rendering/many-draw-calls.html and a reasonable place for any new test case could be: https://github.com/KhronosGroup/WebGL/tree/main/sdk/tests/conformance2/rendering |