summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorm-stephen <truestyle2005@163.com>2019-07-25 10:40:26 +0800
committerGitHub <noreply@github.com>2019-07-25 10:40:26 +0800
commit73cbb0d01b2f899efb9515d00baeb62de9bde25e (patch)
tree9b08bab9c802813f390826d1ae0ecb90c88667d2
parent1a68ceef69d8f23541ed4fa9ab380a51d6b8cce2 (diff)
parenta8db681454e5173c03154e79c5f125ce26d653c1 (diff)
downloadqtlocation-mapboxgl-upstream/stephen-MGLLoggingConfiguration.tar.gz
Merge branch 'master' into stephen-MGLLoggingConfigurationupstream/stephen-MGLLoggingConfiguration
-rw-r--r--benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp2
-rw-r--r--circle.yml8
-rw-r--r--platform/android/CHANGELOG.md6
-rw-r--r--platform/ios/CHANGELOG.md22
-rw-r--r--platform/ios/Mapbox-iOS-SDK-snapshot-dynamic.podspec2
-rw-r--r--platform/ios/Mapbox-iOS-SDK-stripped.podspec2
-rw-r--r--platform/ios/Mapbox-iOS-SDK.podspec2
-rw-r--r--src/mbgl/annotation/annotation_tile.cpp2
-rw-r--r--src/mbgl/annotation/annotation_tile.hpp2
-rw-r--r--src/mbgl/geometry/feature_index.cpp2
-rw-r--r--src/mbgl/gfx/vertex_vector.hpp10
-rw-r--r--src/mbgl/layout/pattern_layout.hpp2
-rw-r--r--src/mbgl/layout/symbol_feature.hpp4
-rw-r--r--src/mbgl/layout/symbol_instance.cpp136
-rw-r--r--src/mbgl/layout/symbol_instance.hpp59
-rw-r--r--src/mbgl/layout/symbol_layout.cpp62
-rw-r--r--src/mbgl/layout/symbol_layout.hpp2
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp1
-rw-r--r--src/mbgl/renderer/layers/render_circle_layer.cpp2
-rw-r--r--src/mbgl/renderer/layers/render_line_layer.cpp35
-rw-r--r--src/mbgl/style/expression/expression.cpp1
-rw-r--r--src/mbgl/text/placement.cpp82
-rw-r--r--src/mbgl/tile/geojson_tile_data.hpp18
-rw-r--r--src/mbgl/tile/geometry_tile.cpp2
-rw-r--r--src/mbgl/tile/geometry_tile_data.cpp30
-rw-r--r--src/mbgl/tile/geometry_tile_data.hpp9
-rw-r--r--src/mbgl/tile/geometry_tile_worker.cpp2
-rw-r--r--src/mbgl/tile/vector_tile_data.cpp15
-rw-r--r--src/mbgl/tile/vector_tile_data.hpp3
-rw-r--r--test/gl/bucket.test.cpp2
-rw-r--r--test/src/mbgl/test/stub_geometry_tile_feature.hpp2
-rw-r--r--test/text/cross_tile_symbol_index.test.cpp9
-rw-r--r--test/util/merge_lines.test.cpp44
33 files changed, 363 insertions, 219 deletions
diff --git a/benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp b/benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp
index bff1a23ba8..b8f2ffb5b9 100644
--- a/benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp
+++ b/benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp
@@ -35,7 +35,7 @@ public:
return properties.count(key) ? properties.at(key) : optional<Value>();
}
- GeometryCollection getGeometries() const override {
+ const GeometryCollection& getGeometries() const override {
return geometry;
}
};
diff --git a/circle.yml b/circle.yml
index a60e83fa72..ba624dc251 100644
--- a/circle.yml
+++ b/circle.yml
@@ -1110,12 +1110,18 @@ jobs:
- install-dependencies
- install-ios-packaging-dependencies
- run:
+ name: Trigger external deploy steps
+ command: |
+ export VERSION_TAG=${CIRCLE_TAG}
+ export GITHUB_TOKEN=${DANGER_GITHUB_API_TOKEN}
+ platform/ios/scripts/trigger-external-deploy-steps.sh
+ background: true
+ - run:
name: Build, package, and upload iOS release
command: |
export VERSION_TAG=${CIRCLE_TAG}
export GITHUB_TOKEN=${DANGER_GITHUB_API_TOKEN}
platform/ios/scripts/deploy-packages.sh
- platform/ios/scripts/trigger-external-deploy-steps.sh
- save-dependencies
- collect-xcode-build-logs
- upload-xcode-build-logs
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md
index cf9e1b5819..00510c9d70 100644
--- a/platform/android/CHANGELOG.md
+++ b/platform/android/CHANGELOG.md
@@ -7,6 +7,12 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to
### Bug fixes
- Fixed flickering on style change for the same tile set [#15127](https://github.com/mapbox/mapbox-gl-native/pull/15127)
+## 8.2.0 - July 24, 2019
+[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.2.0-beta.1...android-v8.2.0) since [Mapbox Maps SDK for Android v8.2.0-beta.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.2.0-beta.1):
+
+### Bug fixes
+ - Fix rendering of layers that are on top of fill-extrusion layers [#15065](https://github.com/mapbox/mapbox-gl-native/pull/15065)
+
## 8.2.0-beta.1 - July 18, 2019
[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.2.0-alpha.3...android-v8.2.0-beta.1) since [Mapbox Maps SDK for Android v8.2.0-alpha.3](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.2.0-alpha.3):
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index a0c8188372..0a99a9d4d3 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -6,13 +6,13 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
### Styles and rendering
-* Fixed flickering on style change for the same tile set ([#15127](https://github.com/mapbox/mapbox-gl-native/pull/15127))
+* Fixed flickering on style change for the same tile set. ([#15127](https://github.com/mapbox/mapbox-gl-native/pull/15127))
### Other changes
* `MGLLoggingLevel` has been updated for better matching core log levels. Now can use `[MGLLoggingConfiguration sharedConfiguration].loggingLevel` to filter logs from core . [#15120](https://github.com/mapbox/mapbox-gl-native/pull/15120)
-## 5.2.0
+## 5.2.0 - July 24, 2019
### Networking
@@ -60,10 +60,26 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* `-[MGLMapView showAnnotations:edgePadding:animated:completionHandler:]`
* `-[MGLMapView selectAnnotation:animated:completionHandler:]`
* Deprecated variants of the above methods without completion handlers. ([#14959](https://github.com/mapbox/mapbox-gl-native/pull/14959))
-* Added `MGLMapView.compassView.visibility` and `MGLOrnamentVisibility` to allow configuration of compass visibility behavior. ([#15055](https://github.com/mapbox/mapbox-gl-native/pull/15055))
+* Added `MGLMapView.compassView.compassVisibility` and `MGLOrnamentVisibility` to allow configuration of compass visibility behavior. ([#15055](https://github.com/mapbox/mapbox-gl-native/pull/15055))
* Fixed a crash during network access. ([#15113](https://github.com/mapbox/mapbox-gl-native/pull/15113))
* Updated "map ID" to the more accurate term "tileset ID" in documentation; updated "style's Map ID" to the more accurate term "style URL". ([#15116](https://github.com/mapbox/mapbox-gl-native/pull/15116))
+## 4.10.1 - July 19, 2019
+
+* Fixed a bug in telemetry collection. ([#15077](https://github.com/mapbox/mapbox-gl-native/pull/15077))
+
+## 4.11.1 - July 19, 2019
+
+* Fixed a bug in telemetry collection. ([#15077](https://github.com/mapbox/mapbox-gl-native/pull/15077))
+
+## 5.0.1 - July 18, 2019
+
+* Fixed a bug in telemetry collection. ([#15077](https://github.com/mapbox/mapbox-gl-native/pull/15077))
+
+## 5.1.1 - July 18, 2019
+
+* Fixed a bug in telemetry collection. ([#15077](https://github.com/mapbox/mapbox-gl-native/pull/15077))
+
## 5.1.0 - June 19, 2019
### Styles and rendering
diff --git a/platform/ios/Mapbox-iOS-SDK-snapshot-dynamic.podspec b/platform/ios/Mapbox-iOS-SDK-snapshot-dynamic.podspec
index 419a083941..6c774a30c6 100644
--- a/platform/ios/Mapbox-iOS-SDK-snapshot-dynamic.podspec
+++ b/platform/ios/Mapbox-iOS-SDK-snapshot-dynamic.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |m|
- version = '5.2.0-beta.1'
+ version = '5.2.0'
m.name = 'Mapbox-iOS-SDK-snapshot-dynamic'
m.version = "#{version}-snapshot"
diff --git a/platform/ios/Mapbox-iOS-SDK-stripped.podspec b/platform/ios/Mapbox-iOS-SDK-stripped.podspec
index 2e73209888..f7502112ba 100644
--- a/platform/ios/Mapbox-iOS-SDK-stripped.podspec
+++ b/platform/ios/Mapbox-iOS-SDK-stripped.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |m|
- version = '5.2.0-beta.1'
+ version = '5.2.0'
m.name = 'Mapbox-iOS-SDK-stripped'
m.version = "#{version}-stripped"
diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec
index fd11196b57..6d3e1bd14c 100644
--- a/platform/ios/Mapbox-iOS-SDK.podspec
+++ b/platform/ios/Mapbox-iOS-SDK.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |m|
- version = '5.2.0-beta.1'
+ version = '5.2.0'
m.name = 'Mapbox-iOS-SDK'
m.version = version
diff --git a/src/mbgl/annotation/annotation_tile.cpp b/src/mbgl/annotation/annotation_tile.cpp
index 6c3c9eb617..a410adc95e 100644
--- a/src/mbgl/annotation/annotation_tile.cpp
+++ b/src/mbgl/annotation/annotation_tile.cpp
@@ -58,7 +58,7 @@ FeatureIdentifier AnnotationTileFeature::getID() const {
return data->id;
}
-GeometryCollection AnnotationTileFeature::getGeometries() const {
+const GeometryCollection& AnnotationTileFeature::getGeometries() const {
return data->geometries;
}
diff --git a/src/mbgl/annotation/annotation_tile.hpp b/src/mbgl/annotation/annotation_tile.hpp
index 1e23fdf98a..741b598a8c 100644
--- a/src/mbgl/annotation/annotation_tile.hpp
+++ b/src/mbgl/annotation/annotation_tile.hpp
@@ -28,7 +28,7 @@ public:
FeatureType getType() const override;
optional<Value> getValue(const std::string&) const override;
FeatureIdentifier getID() const override;
- GeometryCollection getGeometries() const override;
+ const GeometryCollection& getGeometries() const override;
private:
std::shared_ptr<const AnnotationTileFeatureData> data;
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index 3675e8bc6e..b76e02be3f 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -159,7 +159,7 @@ void FeatureIndex::addFeature(
continue;
}
- result[layerID].push_back(convertFeature(*geometryTileFeature, tileID));
+ result[layerID].emplace_back(convertFeature(*geometryTileFeature, tileID));
}
}
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/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp
index 95f8b181fc..858d515347 100644
--- a/src/mbgl/layout/pattern_layout.hpp
+++ b/src/mbgl/layout/pattern_layout.hpp
@@ -106,7 +106,7 @@ public:
const auto i = patternFeature.i;
std::unique_ptr<GeometryTileFeature> feature = std::move(patternFeature.feature);
const PatternLayerMap& patterns = patternFeature.patterns;
- GeometryCollection geometries = feature->getGeometries();
+ const GeometryCollection& geometries = feature->getGeometries();
bucket->addFeature(*feature, geometries, patternPositions, patterns);
featureIndex->insert(geometries, i, sourceLayerID, bucketLeaderID);
diff --git a/src/mbgl/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp
index 72f613d4b6..72e88fb55e 100644
--- a/src/mbgl/layout/symbol_feature.hpp
+++ b/src/mbgl/layout/symbol_feature.hpp
@@ -13,14 +13,14 @@ class SymbolFeature : public GeometryTileFeature {
public:
SymbolFeature(std::unique_ptr<GeometryTileFeature> feature_) :
feature(std::move(feature_)),
- geometry(feature->getGeometries()) // we need a mutable copy of the geometry for mergeLines()
+ geometry(feature->getGeometries().clone()) // we need a mutable copy of the geometry for mergeLines()
{}
FeatureType getType() const override { return feature->getType(); }
optional<Value> getValue(const std::string& key) const override { return feature->getValue(key); };
std::unordered_map<std::string,Value> getProperties() const override { return feature->getProperties(); };
FeatureIdentifier getID() const override { return feature->getID(); };
- GeometryCollection getGeometries() const override { return geometry; };
+ const GeometryCollection& getGeometries() const override { return geometry; };
friend bool operator < (const SymbolFeature& lhs, const SymbolFeature& rhs) {
return lhs.sortKey < rhs.sortKey;
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp
index 809aa2f451..133cdec698 100644
--- a/src/mbgl/layout/symbol_instance.cpp
+++ b/src/mbgl/layout/symbol_instance.cpp
@@ -18,20 +18,63 @@ const Shaping& getAnyShaping(const ShapedTextOrientations& shapedTextOrientation
} // namespace
+SymbolInstanceSharedData::SymbolInstanceSharedData(GeometryCoordinates line_,
+ const ShapedTextOrientations& shapedTextOrientations,
+ const optional<PositionedIcon>& shapedIcon,
+ const style::SymbolLayoutProperties::Evaluated& layout,
+ const float layoutTextSize,
+ const style::SymbolPlacementType textPlacement,
+ const std::array<float, 2>& textOffset,
+ const GlyphPositions& positions) : line(std::move(line_)) {
+ // Create the quads used for rendering the icon and glyphs.
+ if (shapedIcon) {
+ iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.horizontal);
+ }
+
+ bool singleLineInitialized = false;
+ const auto initHorizontalGlyphQuads = [&] (SymbolQuads& quads, const Shaping& shaping) {
+ if (!shapedTextOrientations.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) {
+ initHorizontalGlyphQuads(centerJustifiedGlyphQuads, shapedTextOrientations.center);
+ }
+
+ if (shapedTextOrientations.left) {
+ initHorizontalGlyphQuads(leftJustifiedGlyphQuads, shapedTextOrientations.left);
+ }
+
+ if (shapedTextOrientations.vertical) {
+ verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.vertical, textOffset, layout, textPlacement, positions);
+ }
+}
+
+bool SymbolInstanceSharedData::empty() const {
+ return rightJustifiedGlyphQuads.empty() && centerJustifiedGlyphQuads.empty() && leftJustifiedGlyphQuads.empty() && verticalGlyphQuads.empty();
+}
+
SymbolInstance::SymbolInstance(Anchor& anchor_,
- GeometryCoordinates line_,
+ std::shared_ptr<SymbolInstanceSharedData> sharedData_,
const ShapedTextOrientations& shapedTextOrientations,
- optional<PositionedIcon> shapedIcon,
- const SymbolLayoutProperties::Evaluated& layout,
- const float layoutTextSize,
+ const optional<PositionedIcon>& shapedIcon,
const float textBoxScale_,
const float textPadding,
const SymbolPlacementType textPlacement,
- const std::array<float, 2> textOffset_,
+ const std::array<float, 2>& textOffset_,
const float iconBoxScale,
const float iconPadding,
- const std::array<float, 2> iconOffset_,
- const GlyphPositions& positions,
+ const std::array<float, 2>& iconOffset_,
const IndexedSubfeature& indexedFeature,
const std::size_t layoutFeatureIndex_,
const std::size_t dataFeatureIndex_,
@@ -39,15 +82,15 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
const float overscaling,
const float rotate,
float radialTextOffset_) :
+ sharedData(std::move(sharedData_)),
anchor(anchor_),
- line(line_),
- hasText(false),
+ // 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap
+ hasText(!sharedData->empty()),
hasIcon(shapedIcon),
-
// Create the collision features that will be used to check whether this symbol instance can be placed
// As a collision approximation, we can use either the vertical or any of the horizontal versions of the feature
- textCollisionFeature(line_, anchor, getAnyShaping(shapedTextOrientations), textBoxScale_, textPadding, textPlacement, indexedFeature, overscaling, rotate),
- iconCollisionFeature(line_, anchor, shapedIcon, iconBoxScale, iconPadding, indexedFeature, rotate),
+ textCollisionFeature(sharedData->line, anchor, getAnyShaping(shapedTextOrientations), textBoxScale_, textPadding, textPlacement, indexedFeature, overscaling, rotate),
+ iconCollisionFeature(sharedData->line, anchor, shapedIcon, iconBoxScale, iconPadding, indexedFeature, rotate),
writingModes(WritingModeType::None),
layoutFeatureIndex(layoutFeatureIndex_),
dataFeatureIndex(dataFeatureIndex_),
@@ -58,43 +101,52 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
radialTextOffset(radialTextOffset_),
singleLine(shapedTextOrientations.singleLine) {
- // Create the quads used for rendering the icon and glyphs.
- if (shapedIcon) {
- iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.horizontal);
- }
-
- bool singleLineInitialized = false;
- const auto initHorizontalGlyphQuads = [&] (SymbolQuads& quads, const Shaping& shaping) {
+ rightJustifiedGlyphQuadsSize = sharedData->rightJustifiedGlyphQuads.size();
+ centerJustifiedGlyphQuadsSize = sharedData->centerJustifiedGlyphQuads.size();
+ leftJustifiedGlyphQuadsSize = sharedData->leftJustifiedGlyphQuads.size();
+ verticalGlyphQuadsSize = sharedData->verticalGlyphQuads.size();
+
+ if (rightJustifiedGlyphQuadsSize || centerJustifiedGlyphQuadsSize || leftJustifiedGlyphQuadsSize) {
writingModes |= WritingModeType::Horizontal;
- 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) {
- initHorizontalGlyphQuads(centerJustifiedGlyphQuads, shapedTextOrientations.center);
+ if (verticalGlyphQuadsSize) {
+ writingModes |= WritingModeType::Vertical;
}
+}
- if (shapedTextOrientations.left) {
- initHorizontalGlyphQuads(leftJustifiedGlyphQuads, shapedTextOrientations.left);
- }
+const GeometryCoordinates& SymbolInstance::line() const {
+ assert(sharedData);
+ return sharedData->line;
+}
- if (shapedTextOrientations.vertical) {
- writingModes |= WritingModeType::Vertical;
- verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.vertical, textOffset, layout, textPlacement, positions);
- }
+const SymbolQuads& SymbolInstance::rightJustifiedGlyphQuads() const {
+ assert(sharedData);
+ return sharedData->rightJustifiedGlyphQuads;
+}
- // 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap
- hasText = !rightJustifiedGlyphQuads.empty() || !centerJustifiedGlyphQuads.empty() || !leftJustifiedGlyphQuads.empty() || !verticalGlyphQuads.empty();
+const SymbolQuads& SymbolInstance::leftJustifiedGlyphQuads() const {
+ assert(sharedData);
+ return sharedData->leftJustifiedGlyphQuads;
+}
+
+const SymbolQuads& SymbolInstance::centerJustifiedGlyphQuads() const {
+ assert(sharedData);
+ return sharedData->centerJustifiedGlyphQuads;
+}
+
+const SymbolQuads& SymbolInstance::verticalGlyphQuads() const {
+ assert(sharedData);
+ return sharedData->verticalGlyphQuads;
+}
+
+const optional<SymbolQuad>& SymbolInstance::iconQuad() const {
+ assert(sharedData);
+ return sharedData->iconQuad;
+}
+
+void SymbolInstance::releaseSharedData() {
+ sharedData.reset();
}
optional<size_t> SymbolInstance::getDefaultHorizontalPlacedTextIndex() const {
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index 95159deeb1..48bb2f0cbc 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -21,23 +21,39 @@ struct ShapedTextOrientations {
bool singleLine = false;
};
+struct SymbolInstanceSharedData {
+ SymbolInstanceSharedData(GeometryCoordinates line,
+ const ShapedTextOrientations& shapedTextOrientations,
+ const optional<PositionedIcon>& shapedIcon,
+ const style::SymbolLayoutProperties::Evaluated& layout,
+ const float layoutTextSize,
+ const style::SymbolPlacementType textPlacement,
+ const std::array<float, 2>& textOffset,
+ const GlyphPositions& positions);
+ bool empty() const;
+ GeometryCoordinates line;
+ // Note: When singleLine == true, only `rightJustifiedGlyphQuads` is populated.
+ SymbolQuads rightJustifiedGlyphQuads;
+ SymbolQuads centerJustifiedGlyphQuads;
+ SymbolQuads leftJustifiedGlyphQuads;
+ SymbolQuads verticalGlyphQuads;
+ optional<SymbolQuad> iconQuad;
+};
+
class SymbolInstance {
public:
- SymbolInstance(Anchor& anchor,
- GeometryCoordinates line,
+ SymbolInstance(Anchor& anchor_,
+ std::shared_ptr<SymbolInstanceSharedData> sharedData,
const ShapedTextOrientations& shapedTextOrientations,
- optional<PositionedIcon> shapedIcon,
- const style::SymbolLayoutProperties::Evaluated&,
- const float layoutTextSize,
+ const optional<PositionedIcon>& shapedIcon,
const float textBoxScale,
const float textPadding,
- style::SymbolPlacementType textPlacement,
- const std::array<float, 2> textOffset,
+ const style::SymbolPlacementType textPlacement,
+ const std::array<float, 2>& textOffset,
const float iconBoxScale,
const float iconPadding,
- const std::array<float, 2> iconOffset,
- const GlyphPositions&,
- const IndexedSubfeature&,
+ const std::array<float, 2>& iconOffset,
+ const IndexedSubfeature& indexedFeature,
const std::size_t layoutFeatureIndex,
const std::size_t dataFeatureIndex,
std::u16string key,
@@ -46,18 +62,27 @@ public:
float radialTextOffset);
optional<size_t> getDefaultHorizontalPlacedTextIndex() const;
+ const GeometryCoordinates& line() const;
+ const SymbolQuads& rightJustifiedGlyphQuads() const;
+ const SymbolQuads& leftJustifiedGlyphQuads() const;
+ const SymbolQuads& centerJustifiedGlyphQuads() const;
+ const SymbolQuads& verticalGlyphQuads() const;
+ const optional<SymbolQuad>& iconQuad() const;
+ void releaseSharedData();
+
+private:
+ std::shared_ptr<SymbolInstanceSharedData> sharedData;
+
+public:
Anchor anchor;
- GeometryCoordinates line;
bool hasText;
bool hasIcon;
- // Note: When singleLine == true, only `rightJustifiedGlyphQuads` is populated.
- SymbolQuads rightJustifiedGlyphQuads;
- SymbolQuads centerJustifiedGlyphQuads;
- SymbolQuads leftJustifiedGlyphQuads;
- SymbolQuads verticalGlyphQuads;
+ std::size_t rightJustifiedGlyphQuadsSize;
+ std::size_t centerJustifiedGlyphQuadsSize;
+ std::size_t leftJustifiedGlyphQuadsSize;
+ std::size_t verticalGlyphQuadsSize;
- optional<SymbolQuad> iconQuad;
CollisionFeature textCollisionFeature;
CollisionFeature iconCollisionFeature;
WritingModeType writingModes;
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 21642b01e3..d269ca4144 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -397,7 +397,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
const SymbolFeature& feature,
const ShapedTextOrientations& shapedTextOrientations,
- optional<PositionedIcon> shapedIcon,
+ const optional<PositionedIcon>& shapedIcon,
const GlyphPositions& glyphPositions,
Point<float> offset) {
const float minScale = 0.5f;
@@ -433,7 +433,8 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
const auto evaluatedLayoutProperties = layout->evaluate(zoom, feature);
IndexedSubfeature indexedFeature(feature.index, sourceLayer->getName(), bucketLeaderID, symbolInstances.size());
- auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) {
+ auto addSymbolInstance = [&] (Anchor& anchor, std::shared_ptr<SymbolInstanceSharedData> sharedData) {
+ assert(sharedData);
const bool anchorInsideTile = anchor.point.x >= 0 && anchor.point.x < util::EXTENT && anchor.point.y >= 0 && anchor.point.y < util::EXTENT;
if (mode == MapMode::Tile || anchorInsideTile) {
@@ -442,20 +443,26 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
// In tiled rendering mode, add all symbols in the buffers so that we can:
// (1) render symbols that overlap into this tile
// (2) approximate collision detection effects from neighboring symbols
- symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon,
- evaluatedLayoutProperties, layoutTextSize,
+ symbolInstances.emplace_back(anchor, std::move(sharedData), shapedTextOrientations, shapedIcon,
textBoxScale, textPadding, textPlacement, textOffset,
- iconBoxScale, iconPadding, iconOffset,
- glyphPositions, indexedFeature, layoutFeatureIndex, feature.index,
- feature.formattedText ? feature.formattedText->rawText() : std::u16string(), overscaling, rotation, radialTextOffset);
+ iconBoxScale, iconPadding, iconOffset, indexedFeature,
+ layoutFeatureIndex, feature.index,
+ feature.formattedText ? feature.formattedText->rawText() : std::u16string(),
+ overscaling, rotation, radialTextOffset);
}
};
+ const auto createSymbolInstanceSharedData = [&] (GeometryCoordinates line) {
+ return std::make_shared<SymbolInstanceSharedData>(std::move(line),
+ shapedTextOrientations, shapedIcon, evaluatedLayoutProperties, layoutTextSize,
+ textPlacement, textOffset, glyphPositions);
+ };
+
const auto& type = feature.getType();
if (layout->get<SymbolPlacement>() == SymbolPlacementType::Line) {
auto clippedLines = util::clipLines(feature.geometry, 0, 0, util::EXTENT, util::EXTENT);
- for (const auto& line : clippedLines) {
+ for (auto& line : clippedLines) {
Anchors anchors = getAnchors(line,
symbolSpacing,
textMaxAngle,
@@ -466,10 +473,10 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
glyphSize,
textMaxBoxScale,
overscaling);
-
+ auto sharedData = createSymbolInstanceSharedData(std::move(line));
for (auto& anchor : anchors) {
if (!feature.formattedText || !anchorIsTooClose(feature.formattedText->rawText(), textRepeatDistance, anchor)) {
- addSymbolInstance(line, anchor);
+ addSymbolInstance(anchor, sharedData);
}
}
}
@@ -487,7 +494,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
glyphSize,
textMaxBoxScale);
if (anchor) {
- addSymbolInstance(line, *anchor);
+ addSymbolInstance(*anchor, createSymbolInstanceSharedData(line));
}
}
}
@@ -505,18 +512,18 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
// 1 pixel worth of precision, in tile coordinates
auto poi = mapbox::polylabel(poly, double(util::EXTENT / util::tileSize));
Anchor anchor(poi.x, poi.y, 0, minScale);
- addSymbolInstance(polygon[0], anchor);
+ addSymbolInstance(anchor, createSymbolInstanceSharedData(polygon[0]));
}
} else if (type == FeatureType::LineString) {
for (const auto& line : feature.geometry) {
Anchor anchor(line[0].x, line[0].y, 0, minScale);
- addSymbolInstance(line, anchor);
+ addSymbolInstance(anchor, createSymbolInstanceSharedData(line));
}
} else if (type == FeatureType::Point) {
for (const auto& points : feature.geometry) {
for (const auto& point : points) {
Anchor anchor(point.x, point.y, 0, minScale);
- addSymbolInstance({point}, anchor);
+ addSymbolInstance(anchor, createSymbolInstanceSharedData({point}));
}
}
}
@@ -576,36 +583,36 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn
optional<std::size_t> lastAddedSection;
if (singleLine) {
optional<std::size_t> placedTextIndex;
- lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, placedTextIndex, symbolInstance.rightJustifiedGlyphQuads, lastAddedSection);
+ 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.rightJustifiedGlyphQuadsSize) {
+ 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.centerJustifiedGlyphQuadsSize) {
+ 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.leftJustifiedGlyphQuadsSize) {
+ 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);
+ if (symbolInstance.writingModes & WritingModeType::Vertical && symbolInstance.verticalGlyphQuadsSize) {
+ lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, WritingModeType::Vertical, symbolInstance.placedVerticalTextIndex, symbolInstance.verticalGlyphQuads(), lastAddedSection);
}
assert(lastAddedSection); // True, as hasText == true;
updatePaintPropertiesForSection(*bucket, feature, *lastAddedSection);
}
if (hasIcon) {
- if (symbolInstance.iconQuad) {
+ if (symbolInstance.hasIcon) {
const Range<float> sizeData = bucket->iconSizeBinder->getVertexSizeData(feature);
bucket->icon.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
- symbolInstance.iconOffset, WritingModeType::None, symbolInstance.line, std::vector<float>());
+ symbolInstance.iconOffset, WritingModeType::None, symbolInstance.line(), std::vector<float>());
symbolInstance.placedIconIndex = bucket->icon.placedSymbols.size() - 1;
PlacedSymbol& iconSymbol = bucket->icon.placedSymbols.back();
- iconSymbol.vertexStartIndex = addSymbol(bucket->icon, sizeData, *symbolInstance.iconQuad,
+ iconSymbol.vertexStartIndex = addSymbol(bucket->icon, sizeData, *symbolInstance.iconQuad(),
symbolInstance.anchor, iconSymbol, feature.sortKey);
for (auto& pair : bucket->paintProperties) {
@@ -613,6 +620,7 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn
}
}
}
+ symbolInstance.releaseSharedData();
}
if (showCollisionBoxes) {
@@ -649,7 +657,7 @@ std::size_t SymbolLayout::addSymbolGlyphQuads(SymbolBucket& bucket,
const bool hasFormatSectionOverrides = bucket.hasFormatSectionOverrides();
bucket.text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
- symbolInstance.textOffset, writingMode, symbolInstance.line, CalculateTileDistances(symbolInstance.line, symbolInstance.anchor));
+ symbolInstance.textOffset, writingMode, symbolInstance.line(), CalculateTileDistances(symbolInstance.line(), symbolInstance.anchor));
placedIndex = bucket.text.placedSymbols.size() - 1;
PlacedSymbol& placedSymbol = bucket.text.placedSymbols.back();
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index 23f883f56c..581c3ccb04 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -51,7 +51,7 @@ private:
void addFeature(const size_t,
const SymbolFeature&,
const ShapedTextOrientations& shapedTextOrientations,
- optional<PositionedIcon> shapedIcon,
+ const optional<PositionedIcon>& shapedIcon,
const GlyphPositions&,
Point<float> textOffset);
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index 7876937b1e..c22a168a0c 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -114,7 +114,6 @@ public:
std::unique_ptr<SymbolSizeBinder> iconSizeBinder;
struct IconBuffer : public Buffer {
- PremultipliedImage atlasImage;
} icon;
struct CollisionBuffer {
diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp
index cf59319307..4f1620364f 100644
--- a/src/mbgl/renderer/layers/render_circle_layer.cpp
+++ b/src/mbgl/renderer/layers/render_circle_layer.cpp
@@ -167,7 +167,7 @@ bool RenderCircleLayer::queryIntersectsFeature(
projectQueryGeometry(translatedQueryGeometry, posMatrix, transformState.getSize());
auto transformedSize = alignWithMap ? size * pixelsToTileUnits : size;
- auto geometry = feature.getGeometries();
+ const auto& geometry = feature.getGeometries();
for (auto& ring : geometry) {
for (auto& point : ring) {
const GeometryCoordinate& transformedPoint = alignWithMap ? point : projectPoint(point, posMatrix, transformState.getSize());
diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp
index 5c56826bd7..fcd52b21df 100644
--- a/src/mbgl/renderer/layers/render_line_layer.cpp
+++ b/src/mbgl/renderer/layers/render_line_layer.cpp
@@ -214,16 +214,22 @@ void RenderLineLayer::render(PaintParameters& parameters) {
}
}
-optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const double offset) {
- if (offset == 0) return {};
+namespace {
+
+GeometryCollection offsetLine(const GeometryCollection& rings, double offset) {
+ assert(offset != 0.0f);
+ assert(!rings.empty());
GeometryCollection newRings;
- Point<double> zero(0, 0);
+ newRings.reserve(rings.size());
+
+ const Point<double> zero(0, 0);
for (const auto& ring : rings) {
newRings.emplace_back();
auto& newRing = newRings.back();
+ newRing.reserve(ring.size());
- for (auto i = ring.begin(); i != ring.end(); i++) {
+ for (auto i = ring.begin(); i != ring.end(); ++i) {
auto& p = *i;
Point<double> aToB = i == ring.begin() ?
@@ -237,13 +243,15 @@ optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const d
const double cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y;
extrude *= (1.0 / cosHalfAngle);
- newRing.push_back(convertPoint<int16_t>(extrude * offset) + p);
+ newRing.emplace_back(convertPoint<int16_t>(extrude * offset) + p);
}
}
return newRings;
}
+} // namespace
+
bool RenderLineLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature,
@@ -263,16 +271,21 @@ bool RenderLineLayer::queryIntersectsFeature(
// Evaluate function
auto offset = evaluated.get<style::LineOffset>()
.evaluate(feature, zoom, style::LineOffset::defaultValue()) * pixelsToTileUnits;
+ // Test intersection
+ const float halfWidth = getLineWidth(feature, zoom) / 2.0 * pixelsToTileUnits;
// Apply offset to geometry
- auto offsetGeometry = offsetLine(feature.getGeometries(), offset);
+ if (offset != 0.0f && !feature.getGeometries().empty()) {
+ return util::polygonIntersectsBufferedMultiLine(
+ translatedQueryGeometry.value_or(queryGeometry),
+ offsetLine(feature.getGeometries(), offset),
+ halfWidth);
+ }
- // Test intersection
- const float halfWidth = getLineWidth(feature, zoom) / 2.0 * pixelsToTileUnits;
return util::polygonIntersectsBufferedMultiLine(
- translatedQueryGeometry.value_or(queryGeometry),
- offsetGeometry.value_or(feature.getGeometries()),
- halfWidth);
+ translatedQueryGeometry.value_or(queryGeometry),
+ feature.getGeometries(),
+ halfWidth);
}
void RenderLineLayer::updateColorRamp() {
diff --git a/src/mbgl/style/expression/expression.cpp b/src/mbgl/style/expression/expression.cpp
index 1e5b1581d2..4c810431d0 100644
--- a/src/mbgl/style/expression/expression.cpp
+++ b/src/mbgl/style/expression/expression.cpp
@@ -17,7 +17,6 @@ public:
}
PropertyMap getProperties() const override { return feature.properties; }
FeatureIdentifier getID() const override { return feature.id; }
- GeometryCollection getGeometries() const override { return {}; }
optional<mbgl::Value> getValue(const std::string& key) const override {
auto it = feature.properties.find(key);
if (it != feature.properties.end()) {
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index 1795b0dcb7..79bb984aa2 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -545,48 +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.rightJustifiedGlyphQuads.size() * 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.centerJustifiedGlyphQuads.size() * 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.leftJustifiedGlyphQuads.size() * 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.verticalGlyphQuads.size() * 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);
- if (symbolInstance.iconQuad) {
- 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();
}
@@ -596,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) {
@@ -631,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) {
@@ -642,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);
}
};
@@ -667,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) {
diff --git a/src/mbgl/tile/geojson_tile_data.hpp b/src/mbgl/tile/geojson_tile_data.hpp
index 3605af9690..21a65144d9 100644
--- a/src/mbgl/tile/geojson_tile_data.hpp
+++ b/src/mbgl/tile/geojson_tile_data.hpp
@@ -25,15 +25,17 @@ public:
return feature.id;
}
- GeometryCollection getGeometries() const override {
- GeometryCollection geometry = apply_visitor(ToGeometryCollection(), feature.geometry);
-
- // https://github.com/mapbox/geojson-vt-cpp/issues/44
- if (getType() == FeatureType::Polygon) {
- geometry = fixupPolygons(geometry);
+ const GeometryCollection& getGeometries() const override {
+ if (!geometry) {
+ geometry = apply_visitor(ToGeometryCollection(), feature.geometry);
+
+ // https://github.com/mapbox/geojson-vt-cpp/issues/44
+ if (getType() == FeatureType::Polygon) {
+ geometry = fixupPolygons(*geometry);
+ }
}
- return geometry;
+ return *geometry;
}
optional<Value> getValue(const std::string& key) const override {
@@ -43,6 +45,8 @@ public:
}
return optional<Value>();
}
+
+ mutable optional<GeometryCollection> geometry;
};
class GeoJSONTileLayer : public GeometryTileLayer {
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 7f1bed49f4..a431ae423e 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -360,7 +360,7 @@ void GeometryTile::querySourceFeatures(
continue;
}
- result.push_back(convertFeature(*feature, id.canonical));
+ result.emplace_back(convertFeature(*feature, id.canonical));
}
}
}
diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp
index 680f8d1497..db9f37ad4b 100644
--- a/src/mbgl/tile/geometry_tile_data.cpp
+++ b/src/mbgl/tile/geometry_tile_data.cpp
@@ -57,32 +57,31 @@ std::vector<GeometryCollection> classifyRings(const GeometryCollection& rings) {
std::size_t len = rings.size();
if (len <= 1) {
- polygons.push_back(rings);
+ polygons.emplace_back(rings.clone());
return polygons;
}
GeometryCollection polygon;
int8_t ccw = 0;
- for (std::size_t i = 0; i < len; i++) {
- double area = signedArea(rings[i]);
-
- if (area == 0)
- continue;
+ for (const auto& ring : rings) {
+ double area = signedArea(ring);
+ if (area == 0) continue;
- if (ccw == 0)
+ if (ccw == 0) {
ccw = (area < 0 ? -1 : 1);
+ }
if (ccw == (area < 0 ? -1 : 1) && !polygon.empty()) {
- polygons.push_back(polygon);
- polygon.clear();
+ polygons.emplace_back(std::move(polygon));
}
- polygon.push_back(rings[i]);
+ polygon.emplace_back(ring);
}
- if (!polygon.empty())
- polygons.push_back(polygon);
+ if (!polygon.empty()) {
+ polygons.emplace_back(std::move(polygon));
+ }
return polygons;
}
@@ -112,7 +111,7 @@ static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometr
);
};
- GeometryCollection geometries = geometryTileFeature.getGeometries();
+ const GeometryCollection& geometries = geometryTileFeature.getGeometries();
switch (geometryTileFeature.getType()) {
case FeatureType::Unknown: {
@@ -180,4 +179,9 @@ Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const Can
return feature;
}
+const GeometryCollection& GeometryTileFeature::getGeometries() const {
+ static const GeometryCollection dummy;
+ return dummy;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp
index 6ce67a532e..203afcace7 100644
--- a/src/mbgl/tile/geometry_tile_data.hpp
+++ b/src/mbgl/tile/geometry_tile_data.hpp
@@ -35,6 +35,13 @@ public:
GeometryCollection(Args&&... args) : std::vector<GeometryCoordinates>(std::forward<Args>(args)...) {}
GeometryCollection(std::initializer_list<GeometryCoordinates> args)
: std::vector<GeometryCoordinates>(std::move(args)) {}
+ GeometryCollection(GeometryCollection&&) = default;
+ GeometryCollection& operator=(GeometryCollection&&) = default;
+
+ GeometryCollection clone() const { return GeometryCollection(*this); }
+
+private:
+ GeometryCollection(const GeometryCollection&) = default;
};
class GeometryTileFeature {
@@ -44,7 +51,7 @@ public:
virtual optional<Value> getValue(const std::string& key) const = 0;
virtual PropertyMap getProperties() const { return PropertyMap(); }
virtual FeatureIdentifier getID() const { return NullValue {}; }
- virtual GeometryCollection getGeometries() const = 0;
+ virtual const GeometryCollection& getGeometries() const;
};
class GeometryTileLayer {
diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp
index a69825d346..f4d57e5bfc 100644
--- a/src/mbgl/tile/geometry_tile_worker.cpp
+++ b/src/mbgl/tile/geometry_tile_worker.cpp
@@ -382,7 +382,7 @@ void GeometryTileWorker::parse() {
if (!filter(expression::EvaluationContext { static_cast<float>(this->id.overscaledZ), feature.get() }))
continue;
- GeometryCollection geometries = feature->getGeometries();
+ const GeometryCollection& geometries = feature->getGeometries();
bucket->addFeature(*feature, geometries, {}, PatternLayerMap ());
featureIndex->insert(geometries, i, sourceLayerID, leaderImpl.id);
}
diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp
index 2d47515e0f..926e596080 100644
--- a/src/mbgl/tile/vector_tile_data.cpp
+++ b/src/mbgl/tile/vector_tile_data.cpp
@@ -34,14 +34,15 @@ FeatureIdentifier VectorTileFeature::getID() const {
return feature.getID();
}
-GeometryCollection VectorTileFeature::getGeometries() const {
- const float scale = float(util::EXTENT) / feature.getExtent();
- auto lines = feature.getGeometries<GeometryCollection>(scale);
- if (feature.getVersion() >= 2 || feature.getType() != mapbox::vector_tile::GeomType::POLYGON) {
- return lines;
- } else {
- return fixupPolygons(lines);
+const GeometryCollection& VectorTileFeature::getGeometries() const {
+ if (!lines) {
+ const float scale = float(util::EXTENT) / feature.getExtent();
+ lines = feature.getGeometries<GeometryCollection>(scale);
+ if (feature.getVersion() < 2 && feature.getType() == mapbox::vector_tile::GeomType::POLYGON) {
+ lines = fixupPolygons(*lines);
+ }
}
+ return *lines;
}
VectorTileLayer::VectorTileLayer(std::shared_ptr<const std::string> data_,
diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp
index 7c95121a37..525c7935e4 100644
--- a/src/mbgl/tile/vector_tile_data.hpp
+++ b/src/mbgl/tile/vector_tile_data.hpp
@@ -17,10 +17,11 @@ public:
optional<Value> getValue(const std::string& key) const override;
std::unordered_map<std::string, Value> getProperties() const override;
FeatureIdentifier getID() const override;
- GeometryCollection getGeometries() const override;
+ const GeometryCollection& getGeometries() const override;
private:
mapbox::vector_tile::feature feature;
+ mutable optional<GeometryCollection> lines;
};
class VectorTileLayer : public GeometryTileLayer {
diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp
index 9c9847cf4d..f97fd53919 100644
--- a/test/gl/bucket.test.cpp
+++ b/test/gl/bucket.test.cpp
@@ -131,7 +131,7 @@ TEST(Buckets, SymbolBucket) {
// SymbolBucket::addFeature() is a no-op.
GeometryCollection point { { { 0, 0 } } };
- bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point, {}, PatternLayerMap());
+ bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, std::move(point), properties }, point, {}, PatternLayerMap());
ASSERT_FALSE(bucket.hasData());
ASSERT_FALSE(bucket.needsUpload());
diff --git a/test/src/mbgl/test/stub_geometry_tile_feature.hpp b/test/src/mbgl/test/stub_geometry_tile_feature.hpp
index ef21f8e937..e74988df2e 100644
--- a/test/src/mbgl/test/stub_geometry_tile_feature.hpp
+++ b/test/src/mbgl/test/stub_geometry_tile_feature.hpp
@@ -33,7 +33,7 @@ public:
return properties.count(key) ? properties.at(key) : optional<Value>();
}
- GeometryCollection getGeometries() const override {
+ const GeometryCollection& getGeometries() const override {
return geometry;
}
};
diff --git a/test/text/cross_tile_symbol_index.test.cpp b/test/text/cross_tile_symbol_index.test.cpp
index 841f73c699..7cef287b00 100644
--- a/test/text/cross_tile_symbol_index.test.cpp
+++ b/test/text/cross_tile_symbol_index.test.cpp
@@ -11,7 +11,14 @@ SymbolInstance makeSymbolInstance(float x, float y, std::u16string key) {
style::SymbolLayoutProperties::Evaluated layout_;
IndexedSubfeature subfeature(0, "", "", 0);
Anchor anchor(x, y, 0, 0);
- return SymbolInstance(anchor, line, shaping, {}, layout_, 0, 0, 0, style::SymbolPlacementType::Point, {{0, 0}}, 0, 0, {{0, 0}}, positions, subfeature, 0, 0, key, 0, 0, 0.0f);
+ std::array<float, 2> textOffset{{0.0f, 0.0f}};
+ std::array<float, 2> iconOffset{{0.0f, 0.0f}};
+ style::SymbolPlacementType placementType = style::SymbolPlacementType::Point;
+
+ auto sharedData = std::make_shared<SymbolInstanceSharedData>(std::move(line),
+ shaping, nullopt, layout_, 0.0f, placementType,
+ textOffset, positions);
+ return SymbolInstance(anchor, std::move(sharedData), shaping, nullopt, 0, 0, placementType, textOffset, 0, 0, iconOffset, subfeature, 0, 0, key, 0, 0, 0.0f);
}
diff --git a/test/util/merge_lines.test.cpp b/test/util/merge_lines.test.cpp
index 1c8c7aae8f..5dc846ad6e 100644
--- a/test/util/merge_lines.test.cpp
+++ b/test/util/merge_lines.test.cpp
@@ -42,14 +42,14 @@ TEST(MergeLines, SameText) {
input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{6, 0}, {7, 0}, {8, 0}}}, properties, aaa, {}, 0));
input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{5, 0}, {6, 0}}}, properties, aaa, {}, 0));
- const std::vector<StubGeometryTileFeature> expected1 = {
- { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, properties },
- { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties },
- { {}, FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, properties },
- { {}, FeatureType::LineString, { emptyLine }, properties },
- { {}, FeatureType::LineString, { emptyLine }, properties },
- { {}, FeatureType::LineString, { emptyLine }, properties }
- };
+ std::vector<StubGeometryTileFeature> expected1;
+ expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, properties));
+ expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties));
+ expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, properties));
+ expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties));
+ expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties));
+ expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties));
+
mbgl::util::mergeLines(input1);
@@ -65,11 +65,11 @@ TEST(MergeLines, BothEnds) {
input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties, aaa, {}, 0 });
input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, properties, aaa, {}, 0 });
- const std::vector<StubGeometryTileFeature> expected2 = {
- { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, properties },
- { {}, FeatureType::LineString, { emptyLine }, properties },
- { {}, FeatureType::LineString, { emptyLine }, properties }
- };
+ std::vector<StubGeometryTileFeature> expected2;
+ expected2.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, properties));
+ expected2.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties));
+ expected2.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties));
+
mbgl::util::mergeLines(input2);
@@ -85,11 +85,11 @@ TEST(MergeLines, CircularLines) {
input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, properties, aaa, {}, 0 });
input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {0, 0}}}, properties, aaa, {}, 0 });
- const std::vector<StubGeometryTileFeature> expected3 = {
- { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, properties },
- { {}, FeatureType::LineString, { emptyLine }, properties },
- { {}, FeatureType::LineString, { emptyLine }, properties }
- };
+ std::vector<StubGeometryTileFeature> expected3;
+ expected3.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, properties));
+ expected3.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties));
+ expected3.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties));
+
mbgl::util::mergeLines(input3);
@@ -102,20 +102,20 @@ TEST(MergeLines, EmptyOuterGeometry) {
std::vector<mbgl::SymbolFeature> input;
input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, properties, aaa, {}, 0 });
- const std::vector<StubGeometryTileFeature> expected = { { {}, FeatureType::LineString, {}, properties } };
+ const StubGeometryTileFeature expected{ {}, FeatureType::LineString, {}, properties };
mbgl::util::mergeLines(input);
- EXPECT_EQ(input[0].geometry, expected[0].getGeometries());
+ EXPECT_EQ(input[0].geometry, expected.getGeometries());
}
TEST(MergeLines, EmptyInnerGeometry) {
std::vector<mbgl::SymbolFeature> input;
input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, properties, aaa, {}, 0 });
- const std::vector<StubGeometryTileFeature> expected = { { {}, FeatureType::LineString, {}, properties } };
+ const StubGeometryTileFeature expected{ {}, FeatureType::LineString, {}, properties };
mbgl::util::mergeLines(input);
- EXPECT_EQ(input[0].geometry, expected[0].getGeometries());
+ EXPECT_EQ(input[0].geometry, expected.getGeometries());
}