summaryrefslogtreecommitdiff
path: root/src/mbgl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl')
-rw-r--r--src/mbgl/layout/symbol_instance.hpp7
-rw-r--r--src/mbgl/layout/symbol_layout.cpp23
-rw-r--r--src/mbgl/layout/symbol_layout.hpp2
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp2
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp2
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp25
-rw-r--r--src/mbgl/renderer/render_layer.hpp16
-rw-r--r--src/mbgl/text/placement.cpp29
-rw-r--r--src/mbgl/text/placement.hpp3
9 files changed, 89 insertions, 20 deletions
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index 4a57b527f7..35426ba9cf 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -122,4 +122,11 @@ public:
uint32_t crossTileID = 0;
};
+class SortKeyRange {
+public:
+ float sortKey;
+ size_t symbolInstanceStart;
+ size_t symbolInstanceEnd;
+};
+
} // namespace mbgl
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index d0227c36c5..f25147f6de 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -107,7 +107,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
const bool hasSymbolSortKey = !leader.layout.get<SymbolSortKey>().isUndefined();
const auto symbolZOrder = layout->get<SymbolZOrder>();
- const bool sortFeaturesByKey = symbolZOrder != SymbolZOrderType::ViewportY && hasSymbolSortKey;
+ sortFeaturesByKey = symbolZOrder != SymbolZOrderType::ViewportY && hasSymbolSortKey;
const bool zOrderByViewportY = symbolZOrder == SymbolZOrderType::ViewportY || (symbolZOrder == SymbolZOrderType::Auto && !sortFeaturesByKey);
sortFeaturesByY = zOrderByViewportY && (layout->get<TextAllowOverlap>() || layout->get<IconAllowOverlap>() ||
layout->get<TextIgnorePlacement>() || layout->get<IconIgnorePlacement>());
@@ -560,6 +560,14 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
layoutFeatureIndex, feature.index,
feature.formattedText ? feature.formattedText->rawText() : std::u16string(),
overscaling, iconRotation, textRotation, variableTextOffset, allowVerticalPlacement, iconType);
+
+ if (sortFeaturesByKey) {
+ if (sortKeyRanges.size() && sortKeyRanges.back().sortKey == feature.sortKey) {
+ sortKeyRanges.back().symbolInstanceEnd = symbolInstances.size();
+ } else {
+ sortKeyRanges.push_back({feature.sortKey, symbolInstances.size() - 1, symbolInstances.size()});
+ }
+ }
}
};
@@ -679,8 +687,17 @@ std::vector<float> CalculateTileDistances(const GeometryCoordinates& line, const
}
void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIndex>&, std::unordered_map<std::string, LayerRenderData>& renderData, const bool firstLoad, const bool showCollisionBoxes) {
- auto bucket = std::make_shared<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, iconsNeedLinear,
- sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), tilePixelRatio,
+ auto bucket = std::make_shared<SymbolBucket>(layout,
+ layerPaintProperties,
+ textSize,
+ iconSize,
+ zoom,
+ iconsNeedLinear,
+ sortFeaturesByY,
+ bucketLeaderID,
+ std::move(symbolInstances),
+ std::move(sortKeyRanges),
+ tilePixelRatio,
allowVerticalPlacement,
std::move(placementModes));
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index 1abcaaa5d6..e8472a7406 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -44,6 +44,7 @@ public:
const std::string bucketLeaderID;
std::vector<SymbolInstance> symbolInstances;
+ std::vector<SortKeyRange> sortKeyRanges;
static constexpr float INVALID_OFFSET_VALUE = std::numeric_limits<float>::max();
/**
@@ -105,6 +106,7 @@ private:
bool iconsNeedLinear = false;
bool sortFeaturesByY = false;
+ bool sortFeaturesByKey = false;
bool allowVerticalPlacement = false;
std::vector<style::TextWritingModeType> placementModes;
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp
index 03ab1c87d1..846161cacc 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.cpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp
@@ -22,6 +22,7 @@ SymbolBucket::SymbolBucket(Immutable<style::SymbolLayoutProperties::PossiblyEval
bool sortFeaturesByY_,
const std::string bucketName_,
const std::vector<SymbolInstance>&& symbolInstances_,
+ const std::vector<SortKeyRange>&& sortKeyRanges_,
float tilePixelRatio_,
bool allowVerticalPlacement_,
std::vector<style::TextWritingModeType> placementModes_)
@@ -36,6 +37,7 @@ SymbolBucket::SymbolBucket(Immutable<style::SymbolLayoutProperties::PossiblyEval
justReloaded(false),
hasVariablePlacement(false),
symbolInstances(symbolInstances_),
+ sortKeyRanges(sortKeyRanges_),
textSizeBinder(SymbolSizeBinder::create(zoom, textSize, TextSize::defaultValue())),
iconSizeBinder(SymbolSizeBinder::create(zoom, iconSize, IconSize::defaultValue())),
tilePixelRatio(tilePixelRatio_),
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index 3fe6cf20c4..f6449a8906 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -59,6 +59,7 @@ public:
bool sortFeaturesByY,
const std::string bucketLeaderID,
const std::vector<SymbolInstance>&&,
+ const std::vector<SortKeyRange>&&,
const float tilePixelRatio,
bool allowVerticalPlacement,
std::vector<style::TextWritingModeType> placementModes);
@@ -100,6 +101,7 @@ public:
bool hasVariablePlacement : 1;
std::vector<SymbolInstance> symbolInstances;
+ std::vector<SortKeyRange> sortKeyRanges;
struct PaintProperties {
SymbolIconProgram::Binders iconBinders;
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp
index a4a73d3fe5..23ee215705 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp
@@ -362,6 +362,8 @@ void RenderSymbolLayer::render(PaintParameters& parameters) {
assert(bucket.paintProperties.find(getID()) != bucket.paintProperties.end());
const auto& bucketPaintProperties = bucket.paintProperties.at(getID());
+ bucket.justReloaded = false;
+
auto addRenderables = [&renderableSegments, &tile, renderData, &bucketPaintProperties, it = renderableSegments.begin()] (auto& segments, const SymbolType type) mutable {
for (auto& segment : segments) {
it = renderableSegments.emplace_hint(it, SegmentWrapper{std::ref(segment)}, tile, *renderData, bucketPaintProperties, segment.sortKey, type);
@@ -518,7 +520,28 @@ void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
const Tile* tile = params.source->getRenderedTile(renderTile.id);
assert(tile);
assert(tile->kind == Tile::Kind::Geometry);
- placementData.push_back({*bucket, renderTile, static_cast<const GeometryTile*>(tile)->getFeatureIndex()});
+
+ bool firstInBucket = true;
+ auto featureIndex = static_cast<const GeometryTile*>(tile)->getFeatureIndex();
+
+ if (bucket->sortKeyRanges.empty()) {
+ placementData.push_back(
+ {*bucket, renderTile, featureIndex, firstInBucket, 0.0f, 0, bucket->symbolInstances.size()});
+ } else {
+ for (const SortKeyRange& sortKeyRange : bucket->sortKeyRanges) {
+ LayerPlacementData layerData{*bucket,
+ renderTile,
+ featureIndex,
+ firstInBucket,
+ sortKeyRange.sortKey,
+ sortKeyRange.symbolInstanceStart,
+ sortKeyRange.symbolInstanceEnd};
+ auto sortPosition = std::upper_bound(placementData.cbegin(), placementData.cend(), layerData);
+ placementData.insert(sortPosition, std::move(layerData));
+
+ firstInBucket = false;
+ }
+ }
}
}
}
diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp
index ba3c638f88..4931893271 100644
--- a/src/mbgl/renderer/render_layer.hpp
+++ b/src/mbgl/renderer/render_layer.hpp
@@ -1,11 +1,11 @@
#pragma once
+#include <list>
#include <mbgl/layout/layout.hpp>
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/style/layer_properties.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/util/mat4.hpp>
-
#include <memory>
#include <string>
@@ -20,6 +20,7 @@ class RenderTile;
class TransformState;
class PatternAtlas;
class LineAtlas;
+class SymbolBucket;
class LayerRenderData {
public:
@@ -29,9 +30,16 @@ public:
class LayerPlacementData {
public:
+ friend bool operator<(const LayerPlacementData& lhs, const LayerPlacementData& rhs) {
+ return lhs.sortKey < rhs.sortKey;
+ }
std::reference_wrapper<Bucket> bucket;
std::reference_wrapper<const RenderTile> tile;
std::shared_ptr<FeatureIndex> featureIndex;
+ bool firstInBucket;
+ float sortKey;
+ size_t symbolInstanceStart;
+ size_t symbolInstanceEnd;
};
class LayerPrepareParameters {
@@ -95,9 +103,7 @@ public:
virtual void prepare(const LayerPrepareParameters&);
- const std::vector<LayerPlacementData>& getPlacementData() const {
- return placementData;
- }
+ const std::list<LayerPlacementData>& getPlacementData() const { return placementData; }
// Latest evaluated properties.
Immutable<style::LayerProperties> evaluatedProperties;
@@ -126,7 +132,7 @@ protected:
// evaluated StyleProperties object and is updated accordingly.
RenderPass passes = RenderPass::None;
- std::vector<LayerPlacementData> placementData;
+ std::list<LayerPlacementData> placementData;
private:
// Some layers may not render correctly on some hardware when the vertex attribute limit of
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index ecc8f93032..fc6db89cd6 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -1,3 +1,4 @@
+#include <list>
#include <mbgl/text/placement.hpp>
#include <mbgl/layout/symbol_layout.hpp>
@@ -110,12 +111,14 @@ void Placement::placeLayer(const RenderLayer& layer, const mat4& projMatrix, boo
std::set<uint32_t> seenCrossTileIDs;
for (const auto& item : layer.getPlacementData()) {
Bucket& bucket = item.bucket;
- BucketPlacementParameters params{
- item.tile,
- projMatrix,
- layer.baseImpl->source,
- item.featureIndex,
- showCollisionBoxes};
+ BucketPlacementParameters params{item.tile,
+ projMatrix,
+ layer.baseImpl->source,
+ item.featureIndex,
+ item.sortKey,
+ item.symbolInstanceStart,
+ item.symbolInstanceEnd,
+ showCollisionBoxes};
bucket.place(*this, params, seenCrossTileIDs);
}
}
@@ -518,13 +521,15 @@ void Placement::placeBucket(
placeSymbol(*it);
}
} else {
- for (const SymbolInstance& symbol : bucket.symbolInstances) {
- placeSymbol(symbol);
+ auto beginIt = bucket.symbolInstances.begin() + params.symbolInstanceStart;
+ auto endIt = bucket.symbolInstances.begin() + params.symbolInstanceEnd;
+ assert(params.symbolInstanceStart < params.symbolInstanceEnd);
+ assert(params.symbolInstanceEnd <= bucket.symbolInstances.size());
+ for (auto it = beginIt; it != endIt; ++it) {
+ placeSymbol(*it);
}
}
- bucket.justReloaded = false;
-
// As long as this placement lives, we have to hold onto this bucket's
// matching FeatureIndex/data for querying purposes
retainedQueryData.emplace(std::piecewise_construct,
@@ -590,7 +595,9 @@ void Placement::commit(TimePoint now, const double zoom) {
void Placement::updateLayerBuckets(const RenderLayer& layer, const TransformState& state, bool updateOpacities) const {
std::set<uint32_t> seenCrossTileIDs;
for (const auto& item : layer.getPlacementData()) {
- item.bucket.get().updateVertices(*this, updateOpacities, state, item.tile, seenCrossTileIDs);
+ if (item.firstInBucket) {
+ item.bucket.get().updateVertices(*this, updateOpacities, state, item.tile, seenCrossTileIDs);
+ }
}
}
diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp
index e2d634c54b..595515d9e9 100644
--- a/src/mbgl/text/placement.hpp
+++ b/src/mbgl/text/placement.hpp
@@ -91,6 +91,9 @@ public:
const mat4& projMatrix;
std::string sourceId;
std::shared_ptr<FeatureIndex> featureIndex;
+ float sortKey;
+ size_t symbolInstanceStart;
+ size_t symbolInstanceEnd;
bool showCollisionBoxes;
};