diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 815a20a5722..952c95377b6 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -6,6 +6,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to ### Bug fixes - Fixed the rendering bug caused by redundant pending requests for already requested images [#15864](https://github.com/mapbox/mapbox-gl-native/pull/15864) + - Fixed Geo JSON source flickering on style transition [#15907](https://github.com/mapbox/mapbox-gl-native/pull/15907) ### Performance improvements - Enable incremental vacuum for the offline database in order to make data removal requests faster and to avoid the excessive disk space usage (creating a backup file on VACUUM call) [#15837](https://github.com/mapbox/mapbox-gl-native/pull/15837) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index da4334db89f..9978e622f1a 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -10,6 +10,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Bug fixes * Fixed the rendering bug caused by redundant pending requests for already requested images [#15864](https://github.com/mapbox/mapbox-gl-native/pull/15864) * Enable incremental vacuum for the offline database in order to make data removal requests faster and to avoid the excessive disk space usage (creating a backup file on VACUUM call). ([#15837](https://github.com/mapbox/mapbox-gl-native/pull/15837)) +* Fixed Geo JSON source flickering on style transition. ([#15907](https://github.com/mapbox/mapbox-gl-native/pull/15907)) ## 5.5.0 diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp index 035244e3717..67b4c48d9b7 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -85,26 +85,27 @@ void RenderGeoJSONSource::update(Immutable baseImpl_, enabled = needsRendering; auto data_ = impl().getData().lock(); + if (!data_) { + // In Continuous mode, keep the existing tiles if the new data_ is not + // yet available, thus providing smart style transitions without flickering. + // In other modes, allow clearing the tile pyramid first, before the early + // return in order to avoid render tests being flaky. + if (parameters.mode != MapMode::Continuous) tilePyramid.clearAll(); + return; + } if (data.lock() != data_) { data = data_; tilePyramid.reduceMemoryUse(); - - if (data_) { - const uint8_t maxZ = impl().getZoomRange().max; - for (const auto& pair : tilePyramid.getTiles()) { - if (pair.first.canonical.z <= maxZ) { - static_cast(pair.second.get())->updateData(data_->getTile(pair.first.canonical), needsRelayout); - } + const uint8_t maxZ = impl().getZoomRange().max; + for (const auto& pair : tilePyramid.getTiles()) { + if (pair.first.canonical.z <= maxZ) { + static_cast(pair.second.get()) + ->updateData(data_->getTile(pair.first.canonical), needsRelayout); } } } - if (!data_) { - tilePyramid.clearAll(); - return; - } - tilePyramid.update(layers, needsRendering, needsRelayout, diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp index a08d11c7ad8..d9dc0d9d8e5 100644 --- a/test/style/source.test.cpp +++ b/test/style/source.test.cpp @@ -3,20 +3,22 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include #include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -906,3 +908,25 @@ TEST(Source, RenderTileSetSourceUpdate) { VectorSource uninitialized("source", "http://url"); renderSource->update(uninitialized.baseImpl, layers, true, true, test.tileParameters); } + +TEST(Source, GeoJSONSourceTilesRemainAfterDataReset) { + SourceTest test; + GeoJSONSource source("source"); + source.setGeoJSONData(GeoJSONData::create( + mapbox::geojson::parse( + R"({"geometry": {"type": "Point", "coordinates": [1.1, 1.1]}, "type": "Feature", "properties": {}})"), + {})); + RenderGeoJSONSource renderSource{staticImmutableCast(source.baseImpl)}; + + CircleLayer layer("id", "source"); + Immutable layerProperties = + makeMutable(staticImmutableCast(layer.baseImpl)); + std::vector> layers{layerProperties}; + + static_cast(renderSource).update(source.baseImpl, layers, true, true, test.tileParameters); + EXPECT_FALSE(renderSource.isLoaded()); // loaded == false, means that the source contains pending tiles. + + source.setGeoJSONData(nullptr); + static_cast(renderSource).update(source.baseImpl, layers, true, true, test.tileParameters); + EXPECT_FALSE(renderSource.isLoaded()); // Tiles remain. +} \ No newline at end of file