summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnsis Brammanis <ansis@mapbox.com>2017-11-02 09:37:56 -0400
committerAnsis Brammanis <ansis@mapbox.com>2017-11-02 09:53:34 -0400
commitbdf9cf23ec197e8d83f9714b2336e4d17881d719 (patch)
treec837e7bae545b1880a69c03cbe42b1d82c922abd
parent6c575d0559c9b9304d88187e9518a873aaee7c55 (diff)
downloadqtlocation-mapboxgl-bdf9cf23ec197e8d83f9714b2336e4d17881d719.tar.gz
crosstile fading
-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.cpp8
-rw-r--r--src/mbgl/renderer/renderer_impl.hpp2
-rw-r--r--src/mbgl/text/cross_tile_symbol_index.cpp150
-rw-r--r--src/mbgl/text/cross_tile_symbol_index.hpp31
-rw-r--r--src/mbgl/text/placement.cpp7
-rw-r--r--src/mbgl/text/placement.hpp1
9 files changed, 100 insertions, 103 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..2801fb5d90 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,12 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
order.emplace_back(RenderItem { *layer, source });
}
+ for (auto it = order.rbegin(); it != order.rend(); ++it) {
+ if (it->layer.is<RenderSymbolLayer>()) {
+ crossTileSymbolIndex->addLayer(*it->layer.as<RenderSymbolLayer>());
+ }
+ }
+
auto newPlacement = std::make_unique<Placement>(parameters.state, parameters.mapMode);
for (auto it = order.rbegin(); it != order.rend(); ++it) {
if (it->layer.is<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..316c3505dc 100644
--- a/src/mbgl/text/cross_tile_symbol_index.cpp
+++ b/src/mbgl/text/cross_tile_symbol_index.cpp
@@ -1,29 +1,22 @@
#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)
+ : coord(coord_) {
+ 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<double> 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);
@@ -33,28 +26,41 @@ Point<double> TileLayerIndex::getScaledCoordinates(SymbolInstance& symbolInstanc
};
}
-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);
+ tolerance = 100;
+
+ for (auto& symbolInstance : symbolInstances) {
+ // already has a match, skip
+ if (symbolInstance.crossTileID) continue;
+
+ auto it = indexedSymbolInstances.find(symbolInstance.key);
+ if (it == indexedSymbolInstances.end()) continue;
- Point<double> childTileSymbolCoord = getScaledCoordinates(childTileSymbol, childTileCoord);
+ Point<double> scaledSymbolCoord = getScaledCoordinates(symbolInstance, newCoord);
- 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 };
+ 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 - scaledSymbolCoord.x) <= tolerance &&
+ std::fabs(thisTileSymbol.coord.y - scaledSymbolCoord.y) <= tolerance) {
+
+ 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,42 +69,42 @@ 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>());
+ 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).emplace(coord, std::move(tileIndex));
+ TileLayerIndex tileIndex(coord, bucket.symbolInstances);
+ indexes[coord.overscaledZ].emplace(coord, std::move(tileIndex));
}
+/*
void CrossTileSymbolLayerIndex::removeTile(const OverscaledTileID& coord) {
auto removedIndex = indexes.at(coord.overscaledZ).at(coord);
@@ -125,51 +131,30 @@ void CrossTileSymbolLayerIndex::removeTile(const OverscaledTileID& coord) {
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;
- }
- }
- }
- }
- }
-}
+CrossTileSymbolIndex::CrossTileSymbolIndex() {}
-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;
- }
- }
- }
-}
+void CrossTileSymbolIndex::addLayer(RenderSymbolLayer& symbolLayer) {
-CrossTileSymbolIndex::CrossTileSymbolIndex() {}
+ auto& layerIndex = layerIndexes[symbolLayer.getID()];
+
+ 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);
+
+ layerIndex.addBucket(renderTile.tile.id, symbolBucket);
+ }
+}
+/*
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());
@@ -185,4 +170,5 @@ void CrossTileSymbolIndex::removeTileLayer(std::string& layerId, const Overscale
it->second.removeTile(coord);
}
}
+*/
} // namespace mbgl
diff --git a/src/mbgl/text/cross_tile_symbol_index.hpp b/src/mbgl/text/cross_tile_symbol_index.hpp
index 6cb2ec8707..187149429b 100644
--- a/src/mbgl/text/cross_tile_symbol_index.hpp
+++ b/src/mbgl/text/cross_tile_symbol_index.hpp
@@ -13,45 +13,48 @@
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;
+ IndexedSymbolInstance(uint32_t crossTileID_, Point<double> coord_)
+ : crossTileID(crossTileID_), coord(coord_) {};
+ uint32_t crossTileID;
Point<double> coord;
};
class TileLayerIndex {
public:
- TileLayerIndex(OverscaledTileID coord, std::shared_ptr<std::vector<SymbolInstance>>);
+ TileLayerIndex(OverscaledTileID coord, std::vector<SymbolInstance>&);
- Point<double> getScaledCoordinates(SymbolInstance&, OverscaledTileID&);
- optional<SymbolInstance> getMatchingSymbol(SymbolInstance& childTileSymbol, OverscaledTileID& childTileCoord);
+ Point<double> getScaledCoordinates(SymbolInstance&, const OverscaledTileID&);
+ void findMatches(std::vector<SymbolInstance>&, const OverscaledTileID&);
OverscaledTileID coord;
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&);
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&);
+ void 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..ca067e6227 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_)
@@ -150,10 +148,7 @@ 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));
}
diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp
index dee7c13dc7..40c46fd103 100644
--- a/src/mbgl/text/placement.hpp
+++ b/src/mbgl/text/placement.hpp
@@ -66,7 +66,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;
};