summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-03-22 20:49:38 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-04-01 20:42:09 +0300
commit760dc3a59974d5c5b7c6c6aae7f750474c0fb68e (patch)
treec3867f26a45c30382cd87bce71e57f966e8f7ae7
parentbfac9d700f816041f2205924c1dea1e018d6bc8b (diff)
downloadqtlocation-mapboxgl-760dc3a59974d5c5b7c6c6aae7f750474c0fb68e.tar.gz
[core] Single line optimization for variable label placement
-rw-r--r--platform/node/test/ignores.json4
-rw-r--r--src/mbgl/layout/symbol_instance.cpp27
-rw-r--r--src/mbgl/layout/symbol_instance.hpp5
-rw-r--r--src/mbgl/layout/symbol_layout.cpp33
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp4
-rw-r--r--src/mbgl/style/conversion/constant.cpp5
-rw-r--r--src/mbgl/text/placement.cpp4
-rw-r--r--src/mbgl/text/shaping.cpp1
8 files changed, 50 insertions, 33 deletions
diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json
index 11dff4d716..060f4935a6 100644
--- a/platform/node/test/ignores.json
+++ b/platform/node/test/ignores.json
@@ -149,8 +149,8 @@
"render-tests/symbol-sort-key/text-expression": "https://github.com/mapbox/mapbox-gl-native/issues/14028",
"render-tests/symbol-sort-key/text-placement": "https://github.com/mapbox/mapbox-gl-native/issues/14028",
"render-tests/fill-opacity/opaque-fill-over-symbol-layer": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/7612",
- "render-tests/text-variable-anchor/pitched-rotated-debug": "skip - fails on gl-native due to worse accuracy at collision detection (float vs double) - needs issue",
- "render-tests/text-variable-anchor/rotated-offset": "skip - fails on gl-native due to worse accuracy at collision detection (float vs double) - needs issue",
+ "render-tests/text-variable-anchor/pitched-rotated-debug": "https://github.com/mapbox/mapbox-gl-native/issues/14211",
+ "render-tests/text-variable-anchor/rotated-offset": "https://github.com/mapbox/mapbox-gl-native/issues/14211",
"render-tests/text-variable-anchor/remember-last-placement": "skip - fails on gl-native, as symbol index is not functional at static map mode - needs issue",
"render-tests/geojson/clustered-properties": "https://github.com/mapbox/mapbox-gl-native/issues/14043",
"render-tests/remove-feature-state/composite-expression": "https://github.com/mapbox/mapbox-gl-native/issues/12413",
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp
index fddaaf7c2d..0197df1066 100644
--- a/src/mbgl/layout/symbol_instance.cpp
+++ b/src/mbgl/layout/symbol_instance.cpp
@@ -54,26 +54,37 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
iconOffset(iconOffset_),
key(key_),
textBoxScale(textBoxScale_),
- radialTextOffset(radialTextOffset_) {
+ radialTextOffset(radialTextOffset_),
+ singleLine(shapedTextOrientations.singleLine) {
// Create the quads used for rendering the icon and glyphs.
if (shapedIcon) {
iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.horizontal);
}
-
- if (shapedTextOrientations.right) {
+
+ bool singleLineInitialized = false;
+ const auto initHorizontalGlyphQuads = [&] (SymbolQuads& quads, const Shaping& shaping) {
writingModes |= WritingModeType::Horizontal;
- rightJustifiedGlyphQuads = getGlyphQuads(shapedTextOrientations.right, textOffset, layout, textPlacement, positions);
+ if (!singleLine) {
+ quads = getGlyphQuads(shaping, textOffset, layout, textPlacement, positions);
+ return;
+ }
+ if (!singleLineInitialized) {
+ rightJustifiedGlyphQuads = getGlyphQuads(shaping, textOffset, layout, textPlacement, positions);
+ singleLineInitialized = true;
+ }
+ };
+
+ if (shapedTextOrientations.right) {
+ initHorizontalGlyphQuads(rightJustifiedGlyphQuads, shapedTextOrientations.right);
}
if (shapedTextOrientations.center) {
- writingModes |= WritingModeType::Horizontal;
- centerJustifiedGlyphQuads = getGlyphQuads(shapedTextOrientations.center, textOffset, layout, textPlacement, positions);
+ initHorizontalGlyphQuads(centerJustifiedGlyphQuads, shapedTextOrientations.center);
}
if (shapedTextOrientations.left) {
- writingModes |= WritingModeType::Horizontal;
- leftJustifiedGlyphQuads = getGlyphQuads(shapedTextOrientations.left, textOffset, layout, textPlacement, positions);
+ initHorizontalGlyphQuads(leftJustifiedGlyphQuads, shapedTextOrientations.left);
}
if (shapedTextOrientations.vertical) {
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index 44d81ae1e5..5169b16adb 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -18,6 +18,7 @@ struct ShapedTextOrientations {
Shaping& right = horizontal;
Shaping center;
Shaping left;
+ bool singleLine = false;
};
class SymbolInstance {
@@ -45,14 +46,15 @@ public:
float radialTextOffset);
optional<size_t> getDefaultHorizontalPlacedTextIndex() const;
-
Anchor anchor;
GeometryCoordinates line;
bool hasText;
bool hasIcon;
+ // Note: When singleLine == true, only `rightJustifiedGlyphQuads` is populated.
SymbolQuads rightJustifiedGlyphQuads;
SymbolQuads centerJustifiedGlyphQuads;
SymbolQuads leftJustifiedGlyphQuads;
+
SymbolQuads verticalGlyphQuads;
optional<SymbolQuad> iconQuad;
@@ -72,6 +74,7 @@ public:
optional<size_t> placedIconIndex;
float textBoxScale;
float radialTextOffset;
+ bool singleLine;
uint32_t crossTileID = 0;
};
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index f691d406f1..d1c50d7773 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -312,7 +312,6 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
justifications.push_back(getAnchorJustification(anchor));
}
}
-
for (TextJustifyType justification: justifications) {
Shaping& shapingForJustification = shapingForTextJustifyType(shapedTextOrientations, justification);
if (shapingForJustification) {
@@ -323,8 +322,11 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
Shaping shaping = applyShaping(*feature.formattedText, WritingModeType::Horizontal, SymbolAnchorType::Center, justification);
if (shaping) {
shapingForJustification = std::move(shaping);
+ if (shaping.lineCount == 1u) {
+ shapedTextOrientations.singleLine = true;
+ break;
+ }
}
- // TODO: use 'singleLine' optimization.
}
} else {
if (textJustify == TextJustifyType::Auto) {
@@ -547,9 +549,9 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn
auto bucket = std::make_shared<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), tilePixelRatio);
for (SymbolInstance &symbolInstance : bucket->symbolInstances) {
-
const bool hasText = symbolInstance.hasText;
const bool hasIcon = symbolInstance.hasIcon;
+ const bool singleLine = symbolInstance.singleLine;
const auto& feature = features.at(symbolInstance.layoutFeatureIndex);
@@ -557,16 +559,23 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn
if (hasText && feature.formattedText) {
optional<std::size_t> lastAddedSection;
- if (!symbolInstance.rightJustifiedGlyphQuads.empty()) {
- lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedRightTextIndex, symbolInstance.rightJustifiedGlyphQuads, lastAddedSection);
- }
- if (!symbolInstance.centerJustifiedGlyphQuads.empty()) {
- lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedCenterTextIndex, symbolInstance.centerJustifiedGlyphQuads, lastAddedSection);
- }
- if (!symbolInstance.leftJustifiedGlyphQuads.empty()) {
- lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedLeftTextIndex, symbolInstance.leftJustifiedGlyphQuads, lastAddedSection);
+ if (singleLine) {
+ optional<std::size_t> placedTextIndex;
+ lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, placedTextIndex, symbolInstance.rightJustifiedGlyphQuads, lastAddedSection);
+ symbolInstance.placedRightTextIndex = placedTextIndex;
+ symbolInstance.placedCenterTextIndex = placedTextIndex;
+ symbolInstance.placedLeftTextIndex = placedTextIndex;
+ } else {
+ if (!symbolInstance.rightJustifiedGlyphQuads.empty()) {
+ lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedRightTextIndex, symbolInstance.rightJustifiedGlyphQuads, lastAddedSection);
+ }
+ if (!symbolInstance.centerJustifiedGlyphQuads.empty()) {
+ lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedCenterTextIndex, symbolInstance.centerJustifiedGlyphQuads, lastAddedSection);
+ }
+ if (!symbolInstance.leftJustifiedGlyphQuads.empty()) {
+ lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedLeftTextIndex, symbolInstance.leftJustifiedGlyphQuads, lastAddedSection);
+ }
}
-
if (symbolInstance.writingModes & WritingModeType::Vertical) {
lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, WritingModeType::Vertical, symbolInstance.placedVerticalTextIndex, symbolInstance.verticalGlyphQuads, lastAddedSection);
}
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp
index 38342b44ee..68f683c8d6 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.cpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp
@@ -224,11 +224,11 @@ void SymbolBucket::sortFeatures(const float angle) {
addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedRightTextIndex]);
}
- if (symbolInstance.placedCenterTextIndex) {
+ if (symbolInstance.placedCenterTextIndex && !symbolInstance.singleLine) {
addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedCenterTextIndex]);
}
- if (symbolInstance.placedLeftTextIndex) {
+ if (symbolInstance.placedLeftTextIndex && !symbolInstance.singleLine) {
addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedLeftTextIndex]);
}
diff --git a/src/mbgl/style/conversion/constant.cpp b/src/mbgl/style/conversion/constant.cpp
index 1942779aaa..0fcaab433b 100644
--- a/src/mbgl/style/conversion/constant.cpp
+++ b/src/mbgl/style/conversion/constant.cpp
@@ -147,11 +147,6 @@ optional<std::vector<float>> Converter<std::vector<float>>::operator()(const Con
return result;
}
-
-namespace {
-
-} // namespace
-
optional<std::vector<std::string>> Converter<std::vector<std::string>>::operator()(const Convertible& value, Error& error) const {
if (!isArray(value)) {
error.message = "value must be an array";
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index 9d0fcf7b32..f6c4ac1eb6 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -464,14 +464,14 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedRightTextIndex];
placed.hidden = opacityState.isHidden();
}
- if (symbolInstance.placedCenterTextIndex) {
+ if (symbolInstance.placedCenterTextIndex && !symbolInstance.singleLine) {
for (size_t i = 0; i < symbolInstance.centerJustifiedGlyphQuads.size() * 4; i++) {
bucket.text.opacityVertices.emplace_back(opacityVertex);
}
PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedCenterTextIndex];
placed.hidden = opacityState.isHidden();
}
- if (symbolInstance.placedLeftTextIndex) {
+ if (symbolInstance.placedLeftTextIndex && !symbolInstance.singleLine) {
for (size_t i = 0; i < symbolInstance.leftJustifiedGlyphQuads.size() * 4; i++) {
bucket.text.opacityVertices.emplace_back(opacityVertex);
}
diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp
index 348c2ddccc..ba21b97389 100644
--- a/src/mbgl/text/shaping.cpp
+++ b/src/mbgl/text/shaping.cpp
@@ -363,7 +363,6 @@ const Shaping getShaping(const TaggedString& formattedString,
const style::TextJustifyType textJustify,
const float spacing,
const Point<float>& translate,
- //const float verticalHeight,
const WritingModeType writingMode,
BiDi& bidi,
const GlyphMap& glyphs) {