mapbox / mapbox/mapbox-maps-ios

CustomRasterSource tiles flash on zoom-level switches since 11.28.0 (async raster GPU upload)

Open
#2,439 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auto-triaged bug :beetle:
Dominant language
Swift
Stars
601
Forks
196
PR merge metrics
No merged PRs in 30d

Description

## Environment

- Xcode version: 26.6 & 27.0 beta 6
- iOS version: 26.6.2 (and 27.0 simulator)
- Devices affected: iPhone 16 Pro (and simulators)
- Maps SDK Version: everyone since 11.28.0

## Observed behavior and steps to reproduce

A `CustomRasterSource` rendered through a `RasterLayer` shows blank areas for short time each time the camera crosses a raster zoom-level boundary. The previous level's tiles disappear before the new level's tiles are on screen, so the base map under the layer is visible for a flashing period. On 11.27.3 and earlier the switch is seamless with identical code, everything works smoothly.

Our setup:
- `CustomRasterSourceOptions(clientCallback:minZoom: 10, maxZoom: 20, tileSize: 256)`
- The client callback receives `.required`, renders the tile on a background task and calls `setCustomRasterSourceTileData(forSourceId:tiles:)` on the main thread. We never remove tile data ourselves.
- `RasterLayer` on that source, no slot, added above a Standard style.
- The source covers a few km² (a georeferenced map image); tiles outside it are not answered.

Steps to reproduce:
1. Add a `CustomRasterSource` as above and supply tiles asynchronously from the status callback.
2. Zoom the camera slowly back and forth across a zoom-level boundary (for example 15.4 → 15.6 → 15.4).
3. On 11.28.x and later the covered area flashes at each crossing. On 11.27.3 it does not.

Here you can see the 11.29.1 behavior with flashes:

https://github.com/user-attachments/assets/fbda3182-f9b0-45a7-9e84-1a070d13b614

Here you can see 11.27.3, no flashing:

https://github.com/user-attachments/assets/db3b92b8-afd7-499e-99e1-892e661ae311

## Expected behavior

Tiles already provided for a custom raster source keep drawing until the replacement tiles are uploaded and ready, as on 11.27.3.

## Notes / preliminary analysis

Suspected cause: The 11.28.0 release notes list "Raster tiles upload to the GPU asynchronously — a tile draws after its upload finishes instead of holding up the render pass". For a custom raster source the new level's tile appears to be committed to the tile pyramid while its texture is still uploading, so for those frames neither the old nor the new tile is drawn.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the issue with the described CustomRasterSource and RasterLayer setup, comparing SDK 11.27.3 with 11.28.x. Read the 11.28.0 change for asynchronous raster GPU uploads and trace the tile transition; done means previously provided tiles remain visible until replacement tiles are ready, with no flashes at zoom boundaries.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, swift
Domain
computer-graphics, mobile-dev, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.