-
Notifications
You must be signed in to change notification settings - Fork 1.3k
GPU/CPU usage problem - updateFromDisplayLink deadlock #15342
Description
Hello Mapbox community and team!
I'll be providing sample code of a ViewController with a MapView that when zoomed in to the lowest tiles and back up again somehow initiates a very odd behaviour starting with the Mapbox-iOS-SDK 5.1.0. Lower versions will not result in this error, higher versions such as 5.2.0 still do.
After zooming in and back out the gpu and cpu are constantly at roughly 60% usage and will never cease to go below this even though the I'm not interacting with the device in any way.
Due to the update being called over over, all MapAnnotations are constantly updated as well, which makes it impossible to use drag and drop as they flicker between the new and old position, which in comparison is only a minor inconvenience.
This error does not appear on an empty MapView. It only appears after adding a source and layer that I'd normally use to show icons on the map. I'll follow up this thread once I figure out what exactly is causing this issue. Do note however, that the very same code runs into no issues with any SDK version below 5.1.0 Hopefully someone can figure out what changed. As always, I'm happy to help try out whatever I can to help nail down the reason for error.
Steps to reproduce
- Present the controller provided or any other with a MapView that includes a symbol style/layer
- Zoom all the way in, Zoom all the way out
- Go over to the performance logging and watch the never ending CPU/GPU usage
Expected behavior
MapView will stop rendering things once no more updates are made, such as movement.
Actual behavior
MapView is called/calls updateFromDisplayLink over and over.
Configuration
Mapbox SDK versions:
5.1.0+ and up
iOS/macOS versions:
Tested only on 12.3 and up, sorry i didn't have older versions available.
Device/simulator models:
iPhone 5S simulated with 12.3.1
Xcode version:
Version 10.2.1 (10E1001)
Here the inverted call stack:
Result in SDK versions 5.1.0 and up:
Result in SDK versions 5.0.0 and lower:
The ViewController which lets this error be reproduced every single time once zoomed in all the way and back out:
import Mapbox
class TestMapController: UIViewController, MGLMapViewDelegate {
var mapView: MGLMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView = MGLMapView(frame: view.bounds, styleURL: MGLStyle.lightStyleURL)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.tintColor = .darkGray
mapView.delegate = self
view.addSubview(mapView)
}
func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
let source = MGLShapeSource(identifier: "pictures", features: [], options: nil)
let blueBoxImage = TestMapController.singleColoredImage(of: .blue, and: CGSize(width: 50, height: 50))
style.setImage(blueBoxImage, forName: "picture")
let layer = TestMapController.getLayer(for: source)
style.addSource(source)
style.addLayer(layer)
}
static func singleColoredImage(of color: UIColor, and size: CGSize) -> UIImage {
let format = UIGraphicsImageRendererFormat()
return UIGraphicsImageRenderer(size: size, format: format).image { (context) in
color.setFill()
context.fill(CGRect(origin: .zero, size: size))
}
}
static func getLayer(for source: MGLShapeSource) -> MGLStyleLayer {
let layer = MGLSymbolStyleLayer(identifier: "pictures", source: source)
layer.iconAllowsOverlap = NSExpression(forConstantValue: true)
layer.minimumZoomLevel = 6.0
let nameOfPictures = "picture"
let matching = "'\(nameOfPictures)', '\(nameOfPictures)'"
let formatImageName = "MGL_MATCH(highlight, \(matching), '\(nameOfPictures)')"
let functionImage = NSExpression(format: formatImageName)
layer.iconImageName = functionImage
layer.keepsIconUpright = NSExpression(forConstantValue: 1)
let formatScale = "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1, %@)"
layer.iconScale = NSExpression(format: formatScale, [6: 0.3, 11: 0.6, 14: 0.88])
return layer
}
}