mapbox / mapbox-maps-ios

Interactive, thoroughly customizable maps for iOS powered by vector tiles and Metal
https://www.mapbox.com/mapbox-mobile-sdk
Other
481 stars 157 forks source link

Updating layer property on a timer causes 'MTLTextureDescriptor has height of zero' error #1922

Open maxmiranda opened 1 year ago

maxmiranda commented 1 year ago

Environment

Observed behavior and steps to reproduce

Similar to this link, I was trying to create an animation showing a route that one of my users ran using the .lineGradient property and the .lineProgress operator. Code is linked below in a gist, but the idea is I'm trying to update the line gradient property with a new expression every 3 seconds to account for where we're at in the animation. Here's the code run every 3 seconds:

@objc func tick() {
        DispatchQueue.global().async(execute: {
            DispatchQueue.main.sync { [self] in
                let animationPhase = (Date().timeIntervalSince1970 - startTime.timeIntervalSince1970) / 10;
                let exp = Exp(.step) {
                    Exp(.lineProgress)
                    UIColor.red
                    animationPhase
                    UIColor.purple
                }
                do {
                    if let data = try? JSONEncoder().encode(exp.self),
                       let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []) {
                        try mapView.mapboxMap.style.setLayerProperty(for: "route-layer", property: "line-gradient", value: jsonObject)
                    }
                } catch {
                    // no op
                }
            }
        })
    }

The Error I get occurs after one or two times running the above code and looks like this:

image

To reproduce here's a gist I created with all my code: https://gist.github.com/maxmiranda/730c70c862bcff18af43cdba9791c9e5.

Expected behavior

We should get a nice smooth animation of the route slowly appearing on the screen, like this: https://twitter.com/i/status/1549692421096751106.

Notes / preliminary analysis

I've double checked that the Expression I'm trying to set for the line gradient is accurate and even tried to move the logic to the main thread in case it was a threading issue, but nothing is working.

I believe this is an issue with Mapbox trying to render the map on a set schedule and then I come in and try to update the map on a regular time interval and it's throwing the map out of sync in some way. If we are not allowed to set layer properties on a regular basis as I did, please provide some alternative to be able to create an animation of the route slowly appearing as they do in the article linked below.

Additional links and references

https://www.mapbox.com/blog/building-cinematic-route-animations-with-mapboxgl

maxmiranda commented 1 year ago

Also tried to add mapView.mapboxMap.beginAnimation() & endAnimation() before and after to try to let the renderer know I was adding my own animation, that didn't work.

maxmiranda commented 1 year ago

Instead of creating my own custom timer, I also tried to perform this layer property updated on every renderFrame, it gave the same result.

persidskiy commented 1 year ago

Hi @maxmiranda, thank you for reporting this!

I've tried to build your code from the gist, but didn't manage to reproduce the crash. Is it stable on your end?

please provide some alternative to be able to create an animation of the route slowly appearing as they do in the article linked below.

Please, check out the Examples application, it contains several use-cases very similar to yours: