mapbox-maps-ios icon indicating copy to clipboard operation
mapbox-maps-ios copied to clipboard

CircleLayer animations consume the CPU

Open johnnewman opened this issue 3 years ago • 11 comments

Environment

  • Xcode version: 13.2.1
  • iOS version: 15.3.1
  • Devices affected: All
  • Maps SDK Version: 10.3.0

Thank you for making such a wonderful SDK!

Observed behavior and steps to reproduce

I'm implementing a style-driven pulse animation using a CircleLayer. The pulse is a colored circle border that grows from its center coordinate while simultaneously fading out. My goal is to avoid a UIView-backed annotation because I want the pulse to render underneath certain style layers within the map.

https://user-images.githubusercontent.com/1591735/157763500-dc724474-909b-4c69-91ff-46066c4f6282.mov

I have tried two approaches for this style layer animation:

  1. Use the circleRadiusTransition, circleStrokeWidthTransition, and circleStrokeOpacityTransition properties to allow the MapView to automatically animate the corresponding circleRadius, circleStroke and circleStrokeWidth properties. The Here is a Gist containing this transition approach.
  2. Manually update the circleRadius, circleStroke and circleStrokeWidth 60 times a second on the main queue. Here is the Gist with the manual/rapid updates.

In either approach, on an iPhone 12 Pro with iOS 15.3.1, the Xcode debugger reports my CPU utilization around 40% while the pulse animation is running. This consumes a lot of energy and slows down the app. Similarly, either approach on an iPad mini 4 with iOS 15 utilizes 100% of the CPU.

Expected behavior

Animating a CircleLayer via the provided transition properties should be relatively performant. When using the transition properties, CPU utilization under 20% on a recent iOS device, like an iPhone 12, would be ideal.

Notes / preliminary analysis

I have also implemented this same animation using a UIView-based annotation with Core Animation. This approach is much more performant and utilizes around 3 to 7% CPU. Knowing that, my goal is to still run the animation nested in the stack of style layers so that I have better Z-level control.

Additional links and references

johnnewman avatar Mar 10 '22 22:03 johnnewman

[pages-build-deployment](https://github.com/jgraph/drawio-integration/actions/humpook2@/pages/https://gist.github.com/johnnewman/266f921682ce799aed24765e04a10a04

https://gist.github.com/johnnewman/266f921682ce799aed24765e04a10a04

kaku-io avatar Mar 15 '22 09:03 kaku-io

@johnnewman thank you for reporting this, we will investigate the root cause of this CPU consumption.

ZiZasaurus avatar Mar 22 '22 14:03 ZiZasaurus

any updates on this?

ibmeister avatar Jul 26 '22 20:07 ibmeister

@johnnewman, @ibmeister is this circle animation being used as a workaround for location puck pulsating accuracy or a different feature entirely?

ZiZasaurus avatar Aug 09 '22 15:08 ZiZasaurus

@ZiZasaurus Thanks for looking into this. I am running the circle animation on the annotation that is currently selected by the user. I'm not using this animation for the location puck.

johnnewman avatar Sep 07 '22 13:09 johnnewman

@johnnewman, thank you for following up. Are you able to verify this behavior in the newest version of our SDK?

ZiZasaurus avatar Oct 24 '22 22:10 ZiZasaurus

Hi @ZiZasaurus, I've tried style layer pulses on SDK 10.9.1 using both approaches from the description. Unfortunately, both still consume around 40% of the CPU on an iPhone 12 Pro running iOS 16.0. View-based CoreAnimation APIs are still consuming around 3% of the CPU. Below are some Xcode debugger screenshots.

Style layer transition properties (gist) consistently consume 40% of the CPU: Style transition properties

Manually updating the layer properties 60 times a second (gist) consumes 40% per pulse at peak: Manual updates

Core Animation doesn't have much CPU impact: Core Animation

johnnewman avatar Nov 18 '22 16:11 johnnewman

Hello, do you have any updates on this? Thanks!

emixb avatar Mar 25 '23 21:03 emixb

@ZiZasaurus @OdNairy Hi guys, our product is also affected by this problem. With the map idling, the CPU is constantly at 40% on my iPhone 14 Plus when we use Puck2DConfiguration with the default pulsing animation enabled. Removing the pulsing animation fixes this and the CPU will stay at 0%-1% while the map is idling. It seems that too much resources are used for this animation and at this point, it can't be used in production. Cheers!

vladpre92 avatar Mar 25 '23 21:03 vladpre92

Manually update the circleRadius, circleStroke and circleStrokeWidth 60 times a second on the main queue.

Changing style property on every frame is expected to behave like this. All of the map style layers get re-rendered.

Suggest throttling down the animation refresh rate, to e.g. 25 FPS.

astojilj avatar Mar 27 '23 08:03 astojilj

Still happening on MapboxMaps v11.4.0. Disabling pulsing helps when not updating location at least.

teradyl avatar May 30 '24 23:05 teradyl