diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-11-03 11:23:14 -0700 |
---|---|---|
committer | Chris Loer <chris.loer@mapbox.com> | 2017-11-06 11:54:27 -0800 |
commit | 3b3009014fff3704a4d836dc4617cd603e6f40ee (patch) | |
tree | d9103eb291cb86eafae76cee56944a5546c92d7d | |
parent | b28fc5d71133f46bc79c8918796a3375286eb161 (diff) | |
download | qtlocation-mapboxgl-3b3009014fff3704a4d836dc4617cd603e6f40ee.tar.gz |
Switch to "one-phase" tile loading:
- Don't render tiles that don't have a symbol layer
- Remove unused tiles/bucket from the cross tile symbol index
- Clear cached "crossTileIDs" from symbol buckets that are removed from the symbol index
-rw-r--r-- | src/mbgl/renderer/tile_pyramid.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/text/cross_tile_symbol_index.cpp | 29 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.cpp | 17 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/tile/tile.hpp | 2 |
5 files changed, 48 insertions, 11 deletions
diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index 4acc67daa8..fae16c9ce6 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -119,6 +119,7 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer // use because they're still loading. In addition to that, we also need to retain all tiles that // we're actively using, e.g. as a replacement for tile that aren't loaded yet. std::set<OverscaledTileID> retain; + std::set<UnwrappedTileID> rendered; auto retainTileFn = [&](Tile& tile, TileNecessity necessity) -> void { if (retain.emplace(tile.id).second) { @@ -149,6 +150,7 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer }; auto renderTileFn = [&](const UnwrappedTileID& tileID, Tile& tile) { renderTiles.emplace_back(tileID, tile); + rendered.emplace(tileID); }; renderTiles.clear(); @@ -176,6 +178,13 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer auto tilesIt = tiles.begin(); auto retainIt = retain.begin(); while (tilesIt != tiles.end()) { + auto renderedIt = rendered.find(tilesIt->first.toUnwrapped()); + if (renderedIt == rendered.end()) { + // Since this tile isn't in the render set, crossTileIDs won't be kept + // updated by CrossTileSymbolIndex. We need to reset the stored crossTileIDs + // so they're not reused if/when this tile is re-added to the render set + tilesIt->second->resetCrossTileIDs(); + } if (retainIt == retain.end() || tilesIt->first < *retainIt) { if (!needsRelayout) { tilesIt->second->setNecessity(TileNecessity::Optional); diff --git a/src/mbgl/text/cross_tile_symbol_index.cpp b/src/mbgl/text/cross_tile_symbol_index.cpp index 13771fcd9b..8655e45804 100644 --- a/src/mbgl/text/cross_tile_symbol_index.cpp +++ b/src/mbgl/text/cross_tile_symbol_index.cpp @@ -7,7 +7,7 @@ namespace mbgl { -TileLayerIndex::TileLayerIndex(OverscaledTileID coord_, std::vector<SymbolInstance>& symbolInstances, uint32_t bucketInstanceId_) +TileLayerIndex::TileLayerIndex(OverscaledTileID coord_, std::vector<SymbolInstance>& symbolInstances, uint32_t bucketInstanceId_) : coord(coord_), bucketInstanceId(bucketInstanceId_) { for (SymbolInstance& symbolInstance : symbolInstances) { indexedSymbolInstances[symbolInstance.key].emplace_back(symbolInstance.crossTileID, getScaledCoordinates(symbolInstance, coord)); @@ -28,11 +28,16 @@ void TileLayerIndex::findMatches(std::vector<SymbolInstance>& symbolInstances, c float tolerance = coord.canonical.z < newCoord.canonical.z ? 1 : std::pow(2, coord.canonical.z - newCoord.canonical.z); for (auto& symbolInstance : symbolInstances) { - // already has a match, skip - if (symbolInstance.crossTileID) continue; + if (symbolInstance.crossTileID) { + // already has a match, skip + continue; + } auto it = indexedSymbolInstances.find(symbolInstance.key); - if (it == indexedSymbolInstances.end()) continue; + if (it == indexedSymbolInstances.end()) { + // No symbol with this key in this bucket + continue; + } auto scaledSymbolCoord = getScaledCoordinates(symbolInstance, newCoord); @@ -72,7 +77,9 @@ void CrossTileSymbolLayerIndex::addBucket(const OverscaledTileID& coord, SymbolB auto zoomIndexes = indexes.find(z); if (zoomIndexes != indexes.end()) { for (auto& childIndex : zoomIndexes->second) { - if (!childIndex.second.coord.isChildOf(coord)) continue; + if (!childIndex.second.coord.isChildOf(coord)) { + continue; + } childIndex.second.findMatches(bucket.symbolInstances, coord); } } @@ -110,8 +117,7 @@ bool CrossTileSymbolLayerIndex::removeStaleBuckets(const std::unordered_set<uint bool tilesChanged = false; for (auto& zoomIndexes : indexes) { for (auto it = zoomIndexes.second.begin(); it != zoomIndexes.second.end();) { - // TODO remove false condition when pyramid flickering is fixed - if (false && !currentIDs.count(it->second.bucketInstanceId)) { + if (!currentIDs.count(it->second.bucketInstanceId)) { it = zoomIndexes.second.erase(it); tilesChanged = true; } else { @@ -140,12 +146,17 @@ bool CrossTileSymbolIndex::addLayer(RenderSymbolLayer& symbolLayer) { assert(dynamic_cast<SymbolBucket*>(bucket)); SymbolBucket& symbolBucket = *reinterpret_cast<SymbolBucket*>(bucket); - if (!symbolBucket.bucketInstanceId) symbolBucketsChanged = true; + if (!symbolBucket.bucketInstanceId) { + symbolBucketsChanged = true; + } layerIndex.addBucket(renderTile.tile.id, symbolBucket); currentBucketIDs.insert(symbolBucket.bucketInstanceId); } - if (layerIndex.removeStaleBuckets(currentBucketIDs)) symbolBucketsChanged = true; + if (layerIndex.removeStaleBuckets(currentBucketIDs)) { + symbolBucketsChanged = true; + } return symbolBucketsChanged; } } // namespace mbgl + diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index e1a5c272f9..02f1e53093 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -125,8 +125,9 @@ void GeometryTile::setShowCollisionBoxes(const bool showCollisionBoxes_) { } void GeometryTile::onLayout(LayoutResult result, const uint64_t resultCorrelationID) { - loaded = true; - renderable = true; + // Don't mark ourselves loaded or renderable until the first successful placement + // TODO: Ideally we'd render this tile without symbols as long as this tile wasn't + // replacing a tile at a different zoom that _did_ have symbols. (void)resultCorrelationID; nonSymbolBuckets = std::move(result.nonSymbolBuckets); featureIndex = std::move(result.featureIndex); @@ -281,4 +282,16 @@ void GeometryTile::querySourceFeatures( } } +void GeometryTile::resetCrossTileIDs() { + for (auto& bucket : symbolBuckets) { + SymbolBucket* symbolBucket = dynamic_cast<SymbolBucket*>(bucket.second.get()); + if (symbolBucket && symbolBucket->bucketInstanceId) { + symbolBucket->bucketInstanceId = 0; + for (auto& symbolInstance : symbolBucket->symbolInstances) { + symbolInstance.crossTileID = 0; + } + } + } +} + } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index 80f2f8c6d7..3f4b36984b 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -96,6 +96,8 @@ public: void onError(std::exception_ptr, uint64_t correlationID); + void resetCrossTileIDs() override; + protected: const GeometryTileData* getData() { return data.get(); diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index 0aa2a1bcad..6c163c93bb 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -95,6 +95,8 @@ public: bool isComplete() const { return loaded && !pending; } + + virtual void resetCrossTileIDs() {}; void dumpDebugLogs() const; |