diff options
author | Ansis Brammanis <ansis.brammanis@gmail.com> | 2017-11-02 14:26:38 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-02 14:26:38 -0400 |
commit | 486902be46974ae9829a7f42280153429a102a01 (patch) | |
tree | a88de1fb3d483e22704e2c321a38d1d849794735 | |
parent | 6c575d0559c9b9304d88187e9518a873aaee7c55 (diff) | |
download | qtlocation-mapboxgl-486902be46974ae9829a7f42280153429a102a01.tar.gz |
fade symbols across tiles (#10361)
-rw-r--r-- | src/mbgl/layout/symbol_instance.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_instance.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/text/cross_tile_symbol_index.cpp | 193 | ||||
-rw-r--r-- | src/mbgl/text/cross_tile_symbol_index.hpp | 36 | ||||
-rw-r--r-- | src/mbgl/text/placement.cpp | 23 | ||||
-rw-r--r-- | src/mbgl/text/placement.hpp | 5 |
9 files changed, 131 insertions, 150 deletions
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index b396c05f4e..9e0c939da1 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -26,6 +26,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor_, const std::size_t featureIndex_, const std::u16string& key_) : anchor(anchor_), + insideTileBoundaries(0 <= anchor.point.x && 0 <= anchor.point.y && anchor.point.x < util::EXTENT && anchor.point.y < util::EXTENT), line(line_), index(index_), hasText(shapedTextOrientations.first || shapedTextOrientations.second), diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 231d1ca079..e8006e37b6 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -35,6 +35,7 @@ public: const std::u16string& key); Anchor anchor; + bool insideTileBoundaries; GeometryCoordinates line; uint32_t index; bool hasText; diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index 39d8dbf804..5fc3fae8a9 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -128,6 +128,8 @@ public: gl::IndexVector<gl::Triangles> triangles; optional<gl::IndexBuffer<gl::Triangles>> indexBuffer; } collisionCircle; + + uint32_t bucketInstanceId = 0; }; } // namespace mbgl diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index c8bf0f9739..d96215a550 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -23,6 +23,7 @@ #include <mbgl/style/source_impl.hpp> #include <mbgl/style/transition_options.hpp> #include <mbgl/text/glyph_manager.hpp> +#include <mbgl/text/cross_tile_symbol_index.hpp> #include <mbgl/tile/tile.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/string.hpp> @@ -57,6 +58,7 @@ Renderer::Impl::Impl(RendererBackend& backend_, , sourceImpls(makeMutable<std::vector<Immutable<style::Source::Impl>>>()) , layerImpls(makeMutable<std::vector<Immutable<style::Layer::Impl>>>()) , renderLight(makeMutable<Light::Impl>()) + , crossTileSymbolIndex(std::make_unique<CrossTileSymbolIndex>()) , placement(std::make_unique<Placement>(TransformState{}, MapMode::Still)) { glyphManager->setObserver(this); } @@ -364,6 +366,13 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { order.emplace_back(RenderItem { *layer, source }); } + bool symbolBucketsChanged = false; + for (auto it = order.rbegin(); it != order.rend(); ++it) { + if (it->layer.is<RenderSymbolLayer>()) { + if (crossTileSymbolIndex->addLayer(*it->layer.as<RenderSymbolLayer>())) symbolBucketsChanged = true; + } + } + auto newPlacement = std::make_unique<Placement>(parameters.state, parameters.mapMode); for (auto it = order.rbegin(); it != order.rend(); ++it) { if (it->layer.is<RenderSymbolLayer>()) { @@ -375,10 +384,11 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { if (placementChanged) placement = std::move(newPlacement); parameters.symbolFadeChange = placement->symbolFadeChange(parameters.timePoint); - // TODO only update when necessary - for (auto it = order.rbegin(); it != order.rend(); ++it) { - if (it->layer.is<RenderSymbolLayer>()) { - placement->updateLayerOpacities(*it->layer.as<RenderSymbolLayer>()); + if (placementChanged || symbolBucketsChanged) { + for (auto it = order.rbegin(); it != order.rend(); ++it) { + if (it->layer.is<RenderSymbolLayer>()) { + placement->updateLayerOpacities(*it->layer.as<RenderSymbolLayer>()); + } } } diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp index e0252e748d..dc19e84995 100644 --- a/src/mbgl/renderer/renderer_impl.hpp +++ b/src/mbgl/renderer/renderer_impl.hpp @@ -31,6 +31,7 @@ class Scheduler; class GlyphManager; class ImageManager; class LineAtlas; +class CrossTileSymbolIndex; class Renderer::Impl : public GlyphManagerObserver, public RenderSourceObserver{ @@ -104,6 +105,7 @@ private: std::unordered_map<std::string, std::unique_ptr<RenderLayer>> renderLayers; RenderLight renderLight; + std::unique_ptr<CrossTileSymbolIndex> crossTileSymbolIndex; std::unique_ptr<Placement> placement; bool contextLost = false; diff --git a/src/mbgl/text/cross_tile_symbol_index.cpp b/src/mbgl/text/cross_tile_symbol_index.cpp index 8047eaec0d..5597e058ac 100644 --- a/src/mbgl/text/cross_tile_symbol_index.cpp +++ b/src/mbgl/text/cross_tile_symbol_index.cpp @@ -1,60 +1,65 @@ #include <mbgl/text/cross_tile_symbol_index.hpp> #include <mbgl/layout/symbol_instance.hpp> +#include <mbgl/renderer/buckets/symbol_bucket.hpp> +#include <mbgl/renderer/render_tile.hpp> +#include <mbgl/tile/tile.hpp> namespace mbgl { -TileLayerIndex::TileLayerIndex(OverscaledTileID coord_, std::shared_ptr<std::vector<SymbolInstance>> symbolInstances_) - : coord(coord_), symbolInstances(symbolInstances_) { - for (SymbolInstance& symbolInstance : *symbolInstances) { - if (indexedSymbolInstances.find(symbolInstance.key) == indexedSymbolInstances.end()) { - indexedSymbolInstances.emplace(symbolInstance.key, std::vector<IndexedSymbolInstance>()); +TileLayerIndex::TileLayerIndex(OverscaledTileID coord_, std::vector<SymbolInstance>& symbolInstances, uint32_t bucketInstanceId_) + : coord(coord_), bucketInstanceId(bucketInstanceId_) { + for (SymbolInstance& symbolInstance : symbolInstances) { + if (symbolInstance.insideTileBoundaries) { + indexedSymbolInstances[symbolInstance.key].emplace_back(symbolInstance.crossTileID, getScaledCoordinates(symbolInstance, coord)); } - - indexedSymbolInstances.at(symbolInstance.key).emplace_back(symbolInstance, getScaledCoordinates(symbolInstance, coord)); - - symbolInstance.isDuplicate = false; - // symbolInstance.isDuplicate = false; - // If we don't pick up an opacity from our parent or child tiles - // Reset so that symbols in cached tiles fade in the same - // way as freshly loaded tiles - //symbolInstance.textOpacityState = OpacityState(); - //symbolInstance.iconOpacityState = OpacityState(); } } -Point<double> TileLayerIndex::getScaledCoordinates(SymbolInstance& symbolInstance, OverscaledTileID& childTileCoord) { +Point<int64_t> TileLayerIndex::getScaledCoordinates(SymbolInstance& symbolInstance, const OverscaledTileID& childTileCoord) { // Round anchor positions to roughly 4 pixel grid const double roundingFactor = 512.0 / util::EXTENT / 2.0; const double scale = roundingFactor / std::pow(2, childTileCoord.canonical.z - coord.canonical.z); return { - std::floor((childTileCoord.canonical.x * util::EXTENT + symbolInstance.anchor.point.x) * scale), - std::floor((childTileCoord.canonical.y * util::EXTENT + symbolInstance.anchor.point.y) * scale) + static_cast<int64_t>(std::floor((childTileCoord.canonical.x * util::EXTENT + symbolInstance.anchor.point.x) * scale)), + static_cast<int64_t>(std::floor((childTileCoord.canonical.y * util::EXTENT + symbolInstance.anchor.point.y) * scale)) }; } -optional<SymbolInstance> TileLayerIndex::getMatchingSymbol(SymbolInstance& childTileSymbol, OverscaledTileID& childTileCoord) { - auto it = indexedSymbolInstances.find(childTileSymbol.key); - if (it == indexedSymbolInstances.end()) return {}; +void TileLayerIndex::findMatches(std::vector<SymbolInstance>& symbolInstances, const OverscaledTileID& newCoord) { + 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; + + auto it = indexedSymbolInstances.find(symbolInstance.key); + if (it == indexedSymbolInstances.end()) continue; + + auto scaledSymbolCoord = getScaledCoordinates(symbolInstance, newCoord); - Point<double> childTileSymbolCoord = getScaledCoordinates(childTileSymbol, childTileCoord); + for (IndexedSymbolInstance& thisTileSymbol: it->second) { + // Return any symbol with the same keys whose coordinates are within 1 + // grid unit. (with a 4px grid, this covers a 12px by 12px area) + if (std::abs(thisTileSymbol.coord.x - scaledSymbolCoord.x) <= tolerance && + std::abs(thisTileSymbol.coord.y - scaledSymbolCoord.y) <= tolerance) { - for (IndexedSymbolInstance& thisTileSymbol: it->second) { - // Return any symbol with the same keys whose coordinates are within 1 - // grid unit. (with a 4px grid, this covers a 12px by 12px area) - if (std::fabs(thisTileSymbol.coord.x - childTileSymbolCoord.x) <= 1 && - std::fabs(thisTileSymbol.coord.y - childTileSymbolCoord.y) <= 1) { - return { thisTileSymbol.instance }; + symbolInstance.crossTileID = thisTileSymbol.crossTileID; + break; + } } } - - return {}; } CrossTileSymbolLayerIndex::CrossTileSymbolLayerIndex() { } -void CrossTileSymbolLayerIndex::addTile(const OverscaledTileID& coord, std::shared_ptr<std::vector<SymbolInstance>> symbolInstances) { +uint32_t CrossTileSymbolLayerIndex::maxCrossTileID = 0; + +void CrossTileSymbolLayerIndex::addBucket(const OverscaledTileID& coord, SymbolBucket& bucket) { + if (bucket.bucketInstanceId) return; + bucket.bucketInstanceId = ++maxBucketInstanceId; + uint8_t minZoom = 25; uint8_t maxZoom = 0; for (auto& it : indexes) { @@ -63,126 +68,80 @@ void CrossTileSymbolLayerIndex::addTile(const OverscaledTileID& coord, std::shar maxZoom = std::max(maxZoom, z); } - TileLayerIndex tileIndex(coord, symbolInstances); // make all higher-res child tiles block duplicate labels in this tile for (auto z = maxZoom; z > coord.overscaledZ; z--) { - auto zoomIndexes = indexes.find(coord.overscaledZ); + auto zoomIndexes = indexes.find(z); if (zoomIndexes != indexes.end()) { for (auto& childIndex : zoomIndexes->second) { if (!childIndex.second.coord.isChildOf(coord)) continue; - // Mark labels in this tile blocked, and don't copy opacity state - // into this tile - blockLabels(childIndex.second, tileIndex, false); + childIndex.second.findMatches(bucket.symbolInstances, coord); } } } // make this tile block duplicate labels in lower-res parent tiles - for (auto z = coord.overscaledZ - 1; z >= minZoom; z--) { + for (auto z = coord.overscaledZ; z >= minZoom; z--) { auto parentCoord = coord.scaledTo(z); auto zoomIndexes = indexes.find(z); if (zoomIndexes != indexes.end()) { auto parentIndex = zoomIndexes->second.find(parentCoord); if (parentIndex != zoomIndexes->second.end()) { - // Mark labels in the parent tile blocked, and copy opacity state - // into this tile - blockLabels(tileIndex, parentIndex->second, true); + parentIndex->second.findMatches(bucket.symbolInstances, coord); } } } - if (indexes.find(coord.overscaledZ) == indexes.end()) { - indexes.emplace(coord.overscaledZ, std::map<OverscaledTileID,TileLayerIndex>()); - } - - indexes.at(coord.overscaledZ).emplace(coord, std::move(tileIndex)); -} - -void CrossTileSymbolLayerIndex::removeTile(const OverscaledTileID& coord) { - - auto removedIndex = indexes.at(coord.overscaledZ).at(coord); - - uint8_t minZoom = 25; - for (auto& it : indexes) { - auto z = it.first; - minZoom = std::min(minZoom, z); - } - - for (auto z = coord.overscaledZ - 1; z >= minZoom; z--) { - auto parentCoord = coord.scaledTo(z); - auto zoomIndexes = indexes.find(z); - if (zoomIndexes != indexes.end()) { - auto parentIndex = zoomIndexes->second.find(parentCoord); - if (parentIndex != zoomIndexes->second.end()) { - unblockLabels(removedIndex, parentIndex->second); - } + for (auto& symbolInstance : bucket.symbolInstances) { + if (!symbolInstance.crossTileID && symbolInstance.insideTileBoundaries) { + // symbol did not match any known symbol, assign a new id + symbolInstance.crossTileID = ++maxCrossTileID; } } - indexes.at(coord.overscaledZ).erase(coord); - if (indexes.at(coord.overscaledZ).size() == 0) { - indexes.erase(coord.overscaledZ); - } -} - -void CrossTileSymbolLayerIndex::blockLabels(TileLayerIndex& childIndex, TileLayerIndex& parentIndex, bool copyParentOpacity) { - for (auto& symbolInstance : *childIndex.symbolInstances) { - // only non-duplicate labels can block other labels - if (!symbolInstance.isDuplicate) { - auto parentSymbolInstance = parentIndex.getMatchingSymbol(symbolInstance, childIndex.coord); - if (parentSymbolInstance) { - // if the parent label was previously non-duplicate, make it duplicate because it's now blocked - if (!parentSymbolInstance->isDuplicate) { - parentSymbolInstance->isDuplicate = true; - - // If the child label is the one being added to the index, - // copy the parent's opacity to the child - if (copyParentOpacity) { - //symbolInstance.textOpacityState = parentSymbolInstance->textOpacityState; - //symbolInstance.iconOpacityState = parentSymbolInstance->iconOpacityState; - } - } - } - } - } + indexes[coord.overscaledZ].emplace(coord, TileLayerIndex(coord, bucket.symbolInstances, bucket.bucketInstanceId)); } -void CrossTileSymbolLayerIndex::unblockLabels(TileLayerIndex& childIndex, TileLayerIndex& parentIndex) { - assert(childIndex.coord.overscaledZ > parentIndex.coord.overscaledZ); - for (auto& symbolInstance : *childIndex.symbolInstances) { - // only non-duplicate labels were blocking other labels - if (!symbolInstance.isDuplicate) { - auto parentSymbolInstance = parentIndex.getMatchingSymbol(symbolInstance, childIndex.coord); - if (parentSymbolInstance) { - // this label is now unblocked, copy its opacity state - parentSymbolInstance->isDuplicate = false; - //parentSymbolInstance->textOpacityState = symbolInstance.textOpacityState; - //parentSymbolInstance->iconOpacityState = symbolInstance.iconOpacityState; - - // mark child as duplicate so that it doesn't unblock further tiles at lower res - // in the remaining calls to unblockLabels before it's fully removed - symbolInstance.isDuplicate = true; +bool CrossTileSymbolLayerIndex::removeStaleBuckets(const std::unordered_set<uint32_t>& currentIDs) { + 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)) { + it = zoomIndexes.second.erase(it); + tilesChanged = true; + } else { + ++it; } } } + return tilesChanged; } CrossTileSymbolIndex::CrossTileSymbolIndex() {} -void CrossTileSymbolIndex::addTileLayer(std::string& layerId, const OverscaledTileID& coord, std::shared_ptr<std::vector<SymbolInstance>> symbolInstances) { - if (layerIndexes.find(layerId) == layerIndexes.end()) { - layerIndexes.emplace(layerId, CrossTileSymbolLayerIndex()); - } +bool CrossTileSymbolIndex::addLayer(RenderSymbolLayer& symbolLayer) { - CrossTileSymbolLayerIndex& layerIndex = layerIndexes.at(layerId); - layerIndex.addTile(coord, symbolInstances); -} + auto& layerIndex = layerIndexes[symbolLayer.getID()]; -void CrossTileSymbolIndex::removeTileLayer(std::string& layerId, const OverscaledTileID& coord) { - auto it = layerIndexes.find(layerId); - if (it != layerIndexes.end()) { - it->second.removeTile(coord); + bool symbolBucketsChanged = false; + std::unordered_set<uint32_t> currentBucketIDs; + + for (RenderTile& renderTile : symbolLayer.renderTiles) { + if (!renderTile.tile.isRenderable()) { + continue; + } + + auto bucket = renderTile.tile.getBucket(*symbolLayer.baseImpl); + assert(dynamic_cast<SymbolBucket*>(bucket)); + SymbolBucket& symbolBucket = *reinterpret_cast<SymbolBucket*>(bucket); + + if (!symbolBucket.bucketInstanceId) symbolBucketsChanged = true; + layerIndex.addBucket(renderTile.tile.id, symbolBucket); + currentBucketIDs.insert(symbolBucket.bucketInstanceId); } + + if (layerIndex.removeStaleBuckets(currentBucketIDs)) symbolBucketsChanged = true; + return symbolBucketsChanged; } } // namespace mbgl diff --git a/src/mbgl/text/cross_tile_symbol_index.hpp b/src/mbgl/text/cross_tile_symbol_index.hpp index 6cb2ec8707..a9e1356059 100644 --- a/src/mbgl/text/cross_tile_symbol_index.hpp +++ b/src/mbgl/text/cross_tile_symbol_index.hpp @@ -9,49 +9,55 @@ #include <vector> #include <string> #include <memory> +#include <unordered_set> namespace mbgl { class SymbolInstance; +class RenderSymbolLayer; +class SymbolBucket; + +class IndexEntry { + Point<float> anchorPoint; + +}; class IndexedSymbolInstance { public: - IndexedSymbolInstance(SymbolInstance& symbolInstance, Point<double> coord_) - : instance(symbolInstance), coord(std::move(coord_)) {}; - SymbolInstance& instance; - Point<double> coord; + IndexedSymbolInstance(uint32_t crossTileID_, Point<int64_t> coord_) + : crossTileID(crossTileID_), coord(coord_) {}; + uint32_t crossTileID; + Point<int64_t> coord; }; class TileLayerIndex { public: - TileLayerIndex(OverscaledTileID coord, std::shared_ptr<std::vector<SymbolInstance>>); + TileLayerIndex(OverscaledTileID coord, std::vector<SymbolInstance>&, uint32_t bucketInstanceId); - Point<double> getScaledCoordinates(SymbolInstance&, OverscaledTileID&); - optional<SymbolInstance> getMatchingSymbol(SymbolInstance& childTileSymbol, OverscaledTileID& childTileCoord); + Point<int64_t> getScaledCoordinates(SymbolInstance&, const OverscaledTileID&); + void findMatches(std::vector<SymbolInstance>&, const OverscaledTileID&); OverscaledTileID coord; + uint32_t bucketInstanceId; std::map<std::u16string,std::vector<IndexedSymbolInstance>> indexedSymbolInstances; - std::shared_ptr<std::vector<SymbolInstance>> symbolInstances; }; class CrossTileSymbolLayerIndex { public: CrossTileSymbolLayerIndex(); - - void addTile(const OverscaledTileID&, std::shared_ptr<std::vector<SymbolInstance>>); - void removeTile(const OverscaledTileID&); - void blockLabels(TileLayerIndex& childIndex, TileLayerIndex& parentIndex, bool copyParentOpacity); - void unblockLabels(TileLayerIndex& childIndex, TileLayerIndex& parentIndex); + void addBucket(const OverscaledTileID&, SymbolBucket&); + bool removeStaleBuckets(const std::unordered_set<uint32_t>& currentIDs); private: std::map<uint8_t,std::map<OverscaledTileID,TileLayerIndex>> indexes; + uint32_t maxBucketInstanceId = 0; + static uint32_t maxCrossTileID; }; class CrossTileSymbolIndex { public: CrossTileSymbolIndex(); - void addTileLayer(std::string& layerId, const OverscaledTileID&, std::shared_ptr<std::vector<SymbolInstance>>); - void removeTileLayer(std::string& layerId, const OverscaledTileID&); + bool addLayer(RenderSymbolLayer&); private: std::map<std::string,CrossTileSymbolLayerIndex> layerIndexes; }; diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 8fdc26f49a..99bb2f9d6d 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -30,8 +30,6 @@ bool JointOpacityState::isHidden() const { return icon.isHidden() && text.isHidden(); } -uint32_t Placement::maxCrossTileID = 0; - Placement::Placement(const TransformState& state_, MapMode mapMode_) : collisionIndex(state_) , state(state_) @@ -39,6 +37,9 @@ Placement::Placement(const TransformState& state_, MapMode mapMode_) {} void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatrix, bool showCollisionBoxes) { + + std::unordered_set<uint32_t> seenCrossTileIDs; + for (RenderTile& renderTile : symbolLayer.renderTiles) { if (!renderTile.tile.isRenderable()) { @@ -73,7 +74,7 @@ void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatri state, pixelsToTileUnits); - placeLayerBucket(symbolBucket, posMatrix, textLabelPlaneMatrix, iconLabelPlaneMatrix, scale, pixelRatio, showCollisionBoxes); + placeLayerBucket(symbolBucket, posMatrix, textLabelPlaneMatrix, iconLabelPlaneMatrix, scale, pixelRatio, showCollisionBoxes, seenCrossTileIDs); } } @@ -84,7 +85,8 @@ void Placement::placeLayerBucket( const mat4& iconLabelPlaneMatrix, const float scale, const float pixelRatio, - const bool showCollisionBoxes) { + const bool showCollisionBoxes, + std::unordered_set<uint32_t>& seenCrossTileIDs) { // TODO collision debug array clearing @@ -101,10 +103,9 @@ void Placement::placeLayerBucket( const bool withinPlus0 = anchor.point.x >= 0 && anchor.point.x < util::EXTENT && anchor.point.y >= 0 && anchor.point.y < util::EXTENT; if (!withinPlus0) continue; - bool placeText = false; - bool placeIcon = false; - - if (true || !symbolInstance.isDuplicate) { + if (seenCrossTileIDs.count(symbolInstance.crossTileID) == 0) { + bool placeText = false; + bool placeIcon = false; if (symbolInstance.placedTextIndices.size()) { assert(symbolInstance.placedTextIndices.size() != 0); @@ -150,12 +151,10 @@ void Placement::placeLayerBucket( collisionIndex.insertFeature(symbolInstance.iconCollisionFeature, bucket.layout.get<IconIgnorePlacement>()); } - if (symbolInstance.crossTileID == 0) { - // TODO properly assign these - symbolInstance.crossTileID = ++maxCrossTileID; - } + assert(symbolInstance.crossTileID != 0); placements.emplace(symbolInstance.crossTileID, PlacementPair(placeText, placeIcon)); + seenCrossTileIDs.insert(symbolInstance.crossTileID); } } } diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index dee7c13dc7..2902192b52 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -5,6 +5,7 @@ #include <mbgl/util/chrono.hpp> #include <mbgl/text/collision_index.hpp> #include <mbgl/layout/symbol_projection.hpp> +#include <unordered_set> namespace mbgl { @@ -58,7 +59,8 @@ namespace mbgl { const mat4& iconLabelPlaneMatrix, const float scale, const float pixelRatio, - const bool showCollisionBoxes); + const bool showCollisionBoxes, + std::unordered_set<uint32_t>& seenCrossTileIDs); void updateBucketOpacities(SymbolBucket&); @@ -66,7 +68,6 @@ namespace mbgl { MapMode mapMode; TimePoint commitTime; - static uint32_t maxCrossTileID; // TODO remove std::unordered_map<uint32_t,PlacementPair> placements; std::unordered_map<uint32_t,JointOpacityState> opacities; }; |