mapbox / mapbox-gl-native

Interactive, thoroughly customizable maps in native Android, iOS, macOS, Node.js, and Qt applications, powered by vector tiles and OpenGL
https://mapbox.com/mobile
Other
4.37k stars 1.32k forks source link

Updating lineDashPattern too many times causes error #14491

Closed maxmeyers closed 4 years ago

maxmeyers commented 5 years ago

I'm updating MGLLineStyleLayer.lineDashPattern every frame using a CADisplayLink. This works and looks great, and gives the effect of moving the dashes through the line.

However, after about 2 minutes (7k-8k frames), I start to get the following error:

2019-04-23 11:08:29.100222-0700 MapboxSample[543:46382] [WARNING] {}[OpenGL]: line atlas bitmap overflow

Additionally, the line starts flashing every half second or so.

This continues until I remove the layer from the map.

Steps to reproduce

  1. Add a MGLLineStyleLayer to your MGLMapView
  2. During every tick of a CADisplayLink, update the layer's lineDashPattern.
  3. Wait 2-3 minutes.

I included a sample View Controller that demonstrates the behavior.

Expected behavior

The line continues to update forever, without any flashes or errors.

Actual behavior

The line starts flashing after 2 minutes along with the above error.

Configuration

Mapbox SDK versions: 4.9.0 iOS/macOS versions: iOS 12.2 Device/simulator models: iPhone XS Max Xcode version: Xcode 10.2.1

ViewController.swift.zip

1ec5 commented 5 years ago

Instead of frequently changing the MGLLineStyleLayer.lineDashPattern property explicitly, consider setting it much less frequently but relying on the map SDK to interpolate the values for you. Set the lineDashPatternTransition property with a duration that matches the reduced interval on which you’ll set the lineDashPattern property. This should eliminate the need for a custom CADisplayLink, which has the potential to conflict with the CADisplayLink that MGLMapView uses internally to draw the map.

maxmeyers commented 5 years ago

Thanks - is there any documentation on how to use an MGLTransition in this context? It's not clear to me how it works.

1ec5 commented 5 years ago

We don’t have any examples of using a transition on iOS, as far as I know, but here are the relevant portions of the SDK’s API documentation:

For example, you could set this just once when setting up the layer:

lineLayer.lineDashPatternTransition = MGLTransition(duration: 1, delay: 0)

and your timer could run something like this once a second:

lineLayer.lineDashPattern = NSExpression(format: seconds.isMultiple(of: 2) ? "{1, 2}" : "{1, 1}")
springmeyer commented 4 years ago

Noting that this was fixed by https://github.com/mapbox/mapbox-gl-native/pull/15862