mapbox-maps-ios
mapbox-maps-ios copied to clipboard
App hangs when Zooms in and Zooms out, when we have around 1000 style layers.
Environment
- Xcode version: 13.1
- iOS version: 16.2
- Devices affected: iPad
- Maps SDK Version: 10.11
Note: App hangs when we Zoom in and Zoom out (at 0:24 Second). When we checked the analytics report, we found the following Crash logs.
https://drive.google.com/file/d/1QAtC7b9-oLlY0B_khSWvqBFhl0R2WgoE/view?usp=sharing
Stack traces of CRASH:
Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: FRONTBOARD 2343432205
<RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-update watchdog transgression: application<bundle identifier>:2451 exhausted real (wall clock) time allowance of 10.00 seconds
ProcessVisibility: Foreground
ProcessState: Running
WatchdogEvent: scene-update
WatchdogVisibility: Background
WatchdogCPUStatistics: (
"Elapsed total CPU time (seconds): 7.940 (user 7.940, system 0.000), 9% CPU",
"Elapsed application CPU time (seconds): 0.122, 0% CPU"
) reportType:CrashLog maxTerminationResistance:Interactive>
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x20160aaa8 mach_msg2_trap + 8
1 libsystem_kernel.dylib 0x20161cfc4 mach_msg2_internal + 80
2 IOKit 0x1cc4ea23c io_connect_method + 520
3 IOKit 0x1cc4e95e0 IOConnectCallMethod + 236
4 IOGPU 0x22c09712c IOGPUResourceCreate + 236
5 IOGPU 0x22c094ebc -[IOGPUMetalResource initWithDevice:options:args:argsSize:] + 396
6 IOGPU 0x22c094c7c -[IOGPUMetalBuffer initWithPrimaryBuffer:heapIndex:bufferIndex:bufferOffset:length:args:argsSize:] + 260
7 AGXMetalA12 0x249ee83a4 0x249edc000 + 50084
8 AGXMetalA12 0x249ee8118 0x249edc000 + 49432
9 AGXMetalA12 0x249f40f7c 0x249edc000 + 413564
10 MapboxCoreMaps 0x1071dcf50 mbgl::metal::StreamBufferResource::update(mbgl::metal::UploadPass&, id<MTLBuffer>, void const*, unsigned long) + 368
11 MapboxCoreMaps 0x1071e3f4c mbgl::metal::UploadPass::createVertexBufferResource(void const*, unsigned long, mbgl::gfx::BufferUsageType) + 156
12 MapboxCoreMaps 0x1073601ec mbgl::SymbolBucket::upload(mbgl::gfx::UploadPass&) + 1424
13 MapboxCoreMaps 0x10761d0d0 mbgl::GeometryTileRenderData::upload(mbgl::gfx::UploadPass&) + 88
14 MapboxCoreMaps 0x1074341e8 mbgl::TileSourceRenderItem::upload(mbgl::gfx::UploadPass&, mbgl::RenderStaticData&) const + 428
15 MapboxCoreMaps 0x1074178f0 mbgl::Renderer::Impl::render(mbgl::RenderTree const&) + 3152
16 MapboxCoreMaps 0x1074125a8 mbgl::Renderer::render(std::__1::shared_ptr<mbgl::UpdateParameters> const&) + 596
17 MapboxCoreMaps 0x10719fef0 mapbox::maps::MapImpl::Impl::render() + 400
18 MapboxCoreMaps 0x10719b598 -[MBMMetalViewDelegate drawInMTKView:] + 544
19 MetalKit 0x22684463c -[MTKView draw] + 160
20 MapboxMaps 0x107e1cf88 MapView.updateFromDisplayLink(displayLink:) + 684
21 MapboxMaps 0x107e25988 partial apply for closure #1 in MapView.didMoveToWindow() + 68
22 MapboxMaps 0x107dcbf1c @objc ForwardingDisplayLinkTarget.update(with:) + 68
23 QuartzCore 0x1c5c13fa4 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 820
24 QuartzCore 0x1c5c259f8 display_timer_callback(__CFMachPort*, void*, long, void*) + 372
25 CoreFoundation 0x1c45c3804 __CFMachPortPerform + 176
26 CoreFoundation 0x1c45e0ce0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 60
27 CoreFoundation 0x1c45e28e8 __CFRunLoopDoSource1 + 520
28 CoreFoundation 0x1c45c4120 __CFRunLoopRun + 2264
29 CoreFoundation 0x1c45c8ec0 CFRunLoopRunSpecific + 612
30 GraphicsServices 0x1fdd73368 GSEventRunModal + 164
31 UIKitCore 0x1c6abe86c -[UIApplication _run] + 888
32 UIKitCore 0x1c6abe4d0 UIApplicationMain + 340
33 SwiftUI 0x1c80d7368 0x1c7f09000 + 1893224
34 SwiftUI 0x1c803839c 0x1c7f09000 + 1242012
35 SwiftUI 0x1c8021750 0x1c7f09000 + 1148752
Hi @JacobVnu, thank you for the report!
We don't have hard limits to number of layers, yet having 1000 layers sounds too much for any case.
Can you provide little more context on your specific use-case? Style reference or minimal reproducible example would be very helpful.
Hi @persidskiy, thanks for the reply. I have attached the video along with the issue description, here am attaching the screenshot of how the layers (Markers) looks like.

@JacobVnu Do I understand correctly, that you generate one layer per annotation?
If that's the case, you can significantly improve performance by setting multiple data points to a single layer using GeoJSON, or using PointAnnotation API. You can find several examples in Examples application:
@JacobVnu did @persidskiy's suggestion help?
This same application hang is happening for us. However, our data consists of a Geometry.lineString so the suggestions to cluster or use point annotations does not apply.
Our standard dataset consists of ~500 lineStrings, each with a source and layer object. The application hangs consistently when zooming in and out. Breaking the process shows a very similar call stack to what is listed above.
This seems like a legit bug in the SDK. We can mitigate the crash by reducing the number of objects rendered, but that is sub-optimal. We have cases where we would like to display substantially more rendered lines on a more powerful device and this has acceptable performance ... until the app hangs.
The occurrence rate of this hang appears to be directly proportional to the number of objects rendered. At 200 lineStrings, the hang doesn't occur while at 1000 it happens extremely often.
I would love to work with your team to discuss optimizations that we could make in the client application as well as help to provide crash dumps or whatever else is needed to diagnose the issue.