summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-23 14:10:43 +0300
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-23 16:55:25 +0300
commitcafecd3f6fedc16e7bf5dff699960978c3b5cb3d (patch)
tree978359e9f49b242333b87c2ef0f83c51d6b67983
parentd7dd35220932726e23bb3d353b32b65bf50bc198 (diff)
downloadqtlocation-mapboxgl-cafecd3f6fedc16e7bf5dff699960978c3b5cb3d.tar.gz
[core] Introduce VertexVector::extend() and use it in placement code.
-rw-r--r--src/mbgl/gfx/vertex_vector.hpp10
-rw-r--r--src/mbgl/text/placement.cpp80
2 files changed, 44 insertions, 46 deletions
diff --git a/src/mbgl/gfx/vertex_vector.hpp b/src/mbgl/gfx/vertex_vector.hpp
index f41f842294..59fe67586b 100644
--- a/src/mbgl/gfx/vertex_vector.hpp
+++ b/src/mbgl/gfx/vertex_vector.hpp
@@ -11,11 +11,13 @@ template <class V>
class VertexVector {
public:
using Vertex = V;
+ template<typename Arg>
+ void emplace_back(Arg&& vertex) {
+ v.emplace_back(std::forward<Arg>(vertex));
+ }
- template <class... Args>
- void emplace_back(Args&&... args) {
- static_assert(sizeof...(args) == 1, "wrong buffer element count");
- util::ignore({ (v.emplace_back(std::forward<Args>(args)), 0)... });
+ void extend(std::size_t n, const Vertex& val) {
+ v.resize(v.size() + n, val);
}
std::size_t elements() const {
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index b7d2189afd..79bb984aa2 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -545,46 +545,38 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
seenCrossTileIDs.insert(symbolInstance.crossTileID);
if (symbolInstance.hasText) {
- auto opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity);
+ size_t textOpacityVerticesSize = 0u;
+ const auto& opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity);
if (symbolInstance.placedRightTextIndex) {
- for (size_t i = 0; i < symbolInstance.rightJustifiedGlyphQuadsSize * 4; i++) {
- bucket.text.opacityVertices.emplace_back(opacityVertex);
- }
+ textOpacityVerticesSize += symbolInstance.rightJustifiedGlyphQuadsSize * 4;
PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedRightTextIndex];
placed.hidden = opacityState.isHidden();
}
if (symbolInstance.placedCenterTextIndex && !symbolInstance.singleLine) {
- for (size_t i = 0; i < symbolInstance.centerJustifiedGlyphQuadsSize * 4; i++) {
- bucket.text.opacityVertices.emplace_back(opacityVertex);
- }
+ textOpacityVerticesSize += symbolInstance.centerJustifiedGlyphQuadsSize * 4;
PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedCenterTextIndex];
placed.hidden = opacityState.isHidden();
}
if (symbolInstance.placedLeftTextIndex && !symbolInstance.singleLine) {
- for (size_t i = 0; i < symbolInstance.leftJustifiedGlyphQuadsSize * 4; i++) {
- bucket.text.opacityVertices.emplace_back(opacityVertex);
- }
+ textOpacityVerticesSize += symbolInstance.leftJustifiedGlyphQuadsSize * 4;
PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedLeftTextIndex];
placed.hidden = opacityState.isHidden();
}
if (symbolInstance.placedVerticalTextIndex) {
- for (size_t i = 0; i < symbolInstance.verticalGlyphQuadsSize * 4; i++) {
- bucket.text.opacityVertices.emplace_back(opacityVertex);
- }
+ textOpacityVerticesSize += symbolInstance.verticalGlyphQuadsSize * 4;
bucket.text.placedSymbols[*symbolInstance.placedVerticalTextIndex].hidden = opacityState.isHidden();
}
+ bucket.text.opacityVertices.extend(textOpacityVerticesSize, opacityVertex);
+
auto prevOffset = variableOffsets.find(symbolInstance.crossTileID);
if (prevOffset != variableOffsets.end()) {
markUsedJustification(bucket, prevOffset->second.anchor, symbolInstance);
}
}
if (symbolInstance.hasIcon) {
- auto opacityVertex = SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity);
- bucket.icon.opacityVertices.emplace_back(opacityVertex);
- bucket.icon.opacityVertices.emplace_back(opacityVertex);
- bucket.icon.opacityVertices.emplace_back(opacityVertex);
- bucket.icon.opacityVertices.emplace_back(opacityVertex);
+ const auto& opacityVertex = SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity);
+ bucket.icon.opacityVertices.extend(4, opacityVertex);
if (symbolInstance.placedIconIndex) {
bucket.icon.placedSymbols[*symbolInstance.placedIconIndex].hidden = opacityState.isHidden();
}
@@ -594,10 +586,8 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
if (feature.alongLine) {
return;
}
- auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false, {});
- for (size_t i = 0; i < feature.boxes.size() * 4; i++) {
- bucket.collisionBox->dynamicVertices.emplace_back(dynamicVertex);
- }
+ const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false, {});
+ bucket.collisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
};
auto updateCollisionTextBox = [this, &bucket, &symbolInstance, &state, variablePlacement, rotateWithMap, pitchWithMap](const auto& feature, const bool placed) {
@@ -629,10 +619,8 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
used = false;
}
}
- auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !used, shift);
- for (size_t i = 0; i < feature.boxes.size() * 4; i++) {
- bucket.collisionBox->dynamicVertices.emplace_back(dynamicVertex);
- }
+ const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !used, shift);
+ bucket.collisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
};
auto updateCollisionCircles = [&](const auto& feature, const bool placed) {
@@ -640,11 +628,8 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
return;
}
for (const CollisionBox& box : feature.boxes) {
- auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !box.used, {});
- bucket.collisionCircle->dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle->dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle->dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle->dynamicVertices.emplace_back(dynamicVertex);
+ const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !box.used, {});
+ bucket.collisionCircle->dynamicVertices.extend(4, dynamicVertex);
}
};
@@ -665,18 +650,29 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
}
}
+namespace {
+optional<size_t> justificationToIndex(style::TextJustifyType justify, const SymbolInstance& symbolInstance) {
+ switch(justify) {
+ case style::TextJustifyType::Right: return symbolInstance.placedRightTextIndex;
+ case style::TextJustifyType::Center: return symbolInstance.placedCenterTextIndex;
+ case style::TextJustifyType::Left: return symbolInstance.placedLeftTextIndex;
+ case style::TextJustifyType::Auto: break;
+ }
+ assert(false);
+ return nullopt;
+}
+
+const style::TextJustifyType justifyTypes[] = {style::TextJustifyType::Right, style::TextJustifyType::Center, style::TextJustifyType::Left};
+
+} // namespace
+
void Placement::markUsedJustification(SymbolBucket& bucket, style::TextVariableAnchorType placedAnchor, SymbolInstance& symbolInstance) {
- std::map<style::TextJustifyType, optional<size_t>> justificationToIndex {
- {style::TextJustifyType::Right, symbolInstance.placedRightTextIndex},
- {style::TextJustifyType::Center, symbolInstance.placedCenterTextIndex},
- {style::TextJustifyType::Left, symbolInstance.placedLeftTextIndex},
- };
- style::TextJustifyType justify = getAnchorJustification(placedAnchor);
- assert(justify == style::TextJustifyType::Right || justify == style::TextJustifyType::Center || justify == style::TextJustifyType::Left);
- const optional<size_t> autoIndex = justificationToIndex[justify];
-
- for (auto& pair : justificationToIndex) {
- const optional<size_t> index = pair.second;
+ style::TextJustifyType anchorJustify = getAnchorJustification(placedAnchor);
+ assert(anchorJustify != style::TextJustifyType::Auto);
+ const optional<size_t>& autoIndex = justificationToIndex(anchorJustify, symbolInstance);
+
+ for (auto& justify : justifyTypes) {
+ const optional<size_t> index = justificationToIndex(justify, symbolInstance);
if (index) {
assert(bucket.text.placedSymbols.size() > *index);
if (autoIndex && *index != *autoIndex) {