summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnsis Brammanis <ansis.brammanis@gmail.com>2017-11-02 14:26:38 -0400
committerGitHub <noreply@github.com>2017-11-02 14:26:38 -0400
commit486902be46974ae9829a7f42280153429a102a01 (patch)
treea88de1fb3d483e22704e2c321a38d1d849794735
parent6c575d0559c9b9304d88187e9518a873aaee7c55 (diff)
downloadqtlocation-mapboxgl-486902be46974ae9829a7f42280153429a102a01.tar.gz
fade symbols across tiles (#10361)
-rw-r--r--src/mbgl/layout/symbol_instance.cpp1
-rw-r--r--src/mbgl/layout/symbol_instance.hpp1
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp2
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp18
-rw-r--r--src/mbgl/renderer/renderer_impl.hpp2
-rw-r--r--src/mbgl/text/cross_tile_symbol_index.cpp193
-rw-r--r--src/mbgl/text/cross_tile_symbol_index.hpp36
-rw-r--r--src/mbgl/text/placement.cpp23
-rw-r--r--src/mbgl/text/placement.hpp5
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;
};