From ac74fc6d005e334ff7126e49b4c737ecb10666b3 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Sun, 21 Jul 2019 12:16:02 +0300 Subject: [core] Release quad data after vertex buffers are created --- src/mbgl/layout/symbol_instance.cpp | 136 +++++++++++++++++++++++++----------- src/mbgl/layout/symbol_instance.hpp | 59 +++++++++++----- src/mbgl/layout/symbol_layout.cpp | 62 +++++++++------- src/mbgl/layout/symbol_layout.hpp | 2 +- src/mbgl/text/placement.cpp | 18 +++-- 5 files changed, 180 insertions(+), 97 deletions(-) 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& shapedIcon, + const style::SymbolLayoutProperties::Evaluated& layout, + const float layoutTextSize, + const style::SymbolPlacementType textPlacement, + const std::array& 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 sharedData_, const ShapedTextOrientations& shapedTextOrientations, - optional shapedIcon, - const SymbolLayoutProperties::Evaluated& layout, - const float layoutTextSize, + const optional& shapedIcon, const float textBoxScale_, const float textPadding, const SymbolPlacementType textPlacement, - const std::array textOffset_, + const std::array& textOffset_, const float iconBoxScale, const float iconPadding, - const std::array iconOffset_, - const GlyphPositions& positions, + const std::array& 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& SymbolInstance::iconQuad() const { + assert(sharedData); + return sharedData->iconQuad; +} + +void SymbolInstance::releaseSharedData() { + sharedData.reset(); } optional 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& shapedIcon, + const style::SymbolLayoutProperties::Evaluated& layout, + const float layoutTextSize, + const style::SymbolPlacementType textPlacement, + const std::array& 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 iconQuad; +}; + class SymbolInstance { public: - SymbolInstance(Anchor& anchor, - GeometryCoordinates line, + SymbolInstance(Anchor& anchor_, + std::shared_ptr sharedData, const ShapedTextOrientations& shapedTextOrientations, - optional shapedIcon, - const style::SymbolLayoutProperties::Evaluated&, - const float layoutTextSize, + const optional& shapedIcon, const float textBoxScale, const float textPadding, - style::SymbolPlacementType textPlacement, - const std::array textOffset, + const style::SymbolPlacementType textPlacement, + const std::array& textOffset, const float iconBoxScale, const float iconPadding, - const std::array iconOffset, - const GlyphPositions&, - const IndexedSubfeature&, + const std::array& 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 getDefaultHorizontalPlacedTextIndex() const; + const GeometryCoordinates& line() const; + const SymbolQuads& rightJustifiedGlyphQuads() const; + const SymbolQuads& leftJustifiedGlyphQuads() const; + const SymbolQuads& centerJustifiedGlyphQuads() const; + const SymbolQuads& verticalGlyphQuads() const; + const optional& iconQuad() const; + void releaseSharedData(); + +private: + std::shared_ptr 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 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 shapedIcon, + const optional& shapedIcon, const GlyphPositions& glyphPositions, Point 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 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(std::move(line), + shapedTextOrientations, shapedIcon, evaluatedLayoutProperties, layoutTextSize, + textPlacement, textOffset, glyphPositions); + }; + const auto& type = feature.getType(); if (layout->get() == 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 lastAddedSection; if (singleLine) { optional 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 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()); + symbolInstance.iconOffset, WritingModeType::None, symbolInstance.line(), std::vector()); 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 shapedIcon, + const optional& shapedIcon, const GlyphPositions&, Point textOffset); diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 1795b0dcb7..b7d2189afd 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -547,28 +547,28 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState if (symbolInstance.hasText) { auto opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity); if (symbolInstance.placedRightTextIndex) { - for (size_t i = 0; i < symbolInstance.rightJustifiedGlyphQuads.size() * 4; i++) { + for (size_t i = 0; i < symbolInstance.rightJustifiedGlyphQuadsSize * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } 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++) { + for (size_t i = 0; i < symbolInstance.centerJustifiedGlyphQuadsSize * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } 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++) { + for (size_t i = 0; i < symbolInstance.leftJustifiedGlyphQuadsSize * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } 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++) { + for (size_t i = 0; i < symbolInstance.verticalGlyphQuadsSize * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } bucket.text.placedSymbols[*symbolInstance.placedVerticalTextIndex].hidden = opacityState.isHidden(); @@ -581,12 +581,10 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState } 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); - } + bucket.icon.opacityVertices.emplace_back(opacityVertex); + bucket.icon.opacityVertices.emplace_back(opacityVertex); + bucket.icon.opacityVertices.emplace_back(opacityVertex); + bucket.icon.opacityVertices.emplace_back(opacityVertex); if (symbolInstance.placedIconIndex) { bucket.icon.placedSymbols[*symbolInstance.placedIconIndex].hidden = opacityState.isHidden(); } -- cgit v1.2.1 From b4056ad88fc6626d8ee604b52be2020d83f6255a Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Sun, 21 Jul 2019 13:16:21 +0300 Subject: [core] Update CrossTileSymbolLayerIndex unit test --- test/text/cross_tile_symbol_index.test.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 textOffset{{0.0f, 0.0f}}; + std::array iconOffset{{0.0f, 0.0f}}; + style::SymbolPlacementType placementType = style::SymbolPlacementType::Point; + + auto sharedData = std::make_shared(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); } -- cgit v1.2.1 From d7dd35220932726e23bb3d353b32b65bf50bc198 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Mon, 22 Jul 2019 11:32:35 +0300 Subject: [core] Remove unused field from icon buffer --- src/mbgl/renderer/buckets/symbol_bucket.hpp | 1 - 1 file changed, 1 deletion(-) 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 iconSizeBinder; struct IconBuffer : public Buffer { - PremultipliedImage atlasImage; } icon; struct CollisionBuffer { -- cgit v1.2.1 From cafecd3f6fedc16e7bf5dff699960978c3b5cb3d Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Tue, 23 Jul 2019 14:10:43 +0300 Subject: [core] Introduce VertexVector::extend() and use it in placement code. --- src/mbgl/gfx/vertex_vector.hpp | 10 +++--- src/mbgl/text/placement.cpp | 80 ++++++++++++++++++++---------------------- 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 VertexVector { public: using Vertex = V; + template + void emplace_back(Arg&& vertex) { + v.emplace_back(std::forward(vertex)); + } - template - void emplace_back(Args&&... args) { - static_assert(sizeof...(args) == 1, "wrong buffer element count"); - util::ignore({ (v.emplace_back(std::forward(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 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> 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 autoIndex = justificationToIndex[justify]; - - for (auto& pair : justificationToIndex) { - const optional index = pair.second; + style::TextJustifyType anchorJustify = getAnchorJustification(placedAnchor); + assert(anchorJustify != style::TextJustifyType::Auto); + const optional& autoIndex = justificationToIndex(anchorJustify, symbolInstance); + + for (auto& justify : justifyTypes) { + const optional index = justificationToIndex(justify, symbolInstance); if (index) { assert(bucket.text.placedSymbols.size() > *index); if (autoIndex && *index != *autoIndex) { -- cgit v1.2.1 From 6798d21eda03ecc2fb2c46c448a45713fc493f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 24 Jul 2019 17:10:34 +0200 Subject: [android] changelog for 8.2.0 --- platform/android/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) 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): -- cgit v1.2.1 From 852fef66ef4cbbe753527b42cf23c59de59399b3 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 23 Jul 2019 08:54:16 +0300 Subject: [core] Force getGeometries() return const ref --- .../src/mbgl/benchmark/stub_geometry_tile_feature.hpp | 2 +- src/mbgl/annotation/annotation_tile.cpp | 2 +- src/mbgl/annotation/annotation_tile.hpp | 2 +- src/mbgl/geometry/feature_index.cpp | 2 +- src/mbgl/layout/symbol_feature.hpp | 2 +- src/mbgl/renderer/layers/render_circle_layer.cpp | 2 +- src/mbgl/style/expression/expression.cpp | 4 +++- src/mbgl/tile/geojson_tile_data.hpp | 18 +++++++++++------- src/mbgl/tile/geometry_tile.cpp | 2 +- src/mbgl/tile/geometry_tile_data.cpp | 2 +- src/mbgl/tile/geometry_tile_data.hpp | 2 +- src/mbgl/tile/vector_tile_data.cpp | 15 ++++++++------- src/mbgl/tile/vector_tile_data.hpp | 3 ++- test/src/mbgl/test/stub_geometry_tile_feature.hpp | 2 +- 14 files changed, 34 insertions(+), 26 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(); } - GeometryCollection getGeometries() const override { + const GeometryCollection& getGeometries() const override { return geometry; } }; 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 getValue(const std::string&) const override; FeatureIdentifier getID() const override; - GeometryCollection getGeometries() const override; + const GeometryCollection& getGeometries() const override; private: std::shared_ptr 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/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp index 72f613d4b6..2c952fc12a 100644 --- a/src/mbgl/layout/symbol_feature.hpp +++ b/src/mbgl/layout/symbol_feature.hpp @@ -20,7 +20,7 @@ public: optional getValue(const std::string& key) const override { return feature->getValue(key); }; std::unordered_map 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/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/style/expression/expression.cpp b/src/mbgl/style/expression/expression.cpp index 1e5b1581d2..4800f6aa7f 100644 --- a/src/mbgl/style/expression/expression.cpp +++ b/src/mbgl/style/expression/expression.cpp @@ -17,7 +17,7 @@ public: } PropertyMap getProperties() const override { return feature.properties; } FeatureIdentifier getID() const override { return feature.id; } - GeometryCollection getGeometries() const override { return {}; } + const GeometryCollection& getGeometries() const override { return geometry; } optional getValue(const std::string& key) const override { auto it = feature.properties.find(key); if (it != feature.properties.end()) { @@ -25,6 +25,8 @@ public: } return optional(); } + + GeometryCollection geometry; }; 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 getValue(const std::string& key) const override { @@ -43,6 +45,8 @@ public: } return optional(); } + + mutable optional 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..2dda9ecae4 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -112,7 +112,7 @@ static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometr ); }; - GeometryCollection geometries = geometryTileFeature.getGeometries(); + const GeometryCollection& geometries = geometryTileFeature.getGeometries(); switch (geometryTileFeature.getType()) { case FeatureType::Unknown: { diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp index 6ce67a532e..db3378a019 100644 --- a/src/mbgl/tile/geometry_tile_data.hpp +++ b/src/mbgl/tile/geometry_tile_data.hpp @@ -44,7 +44,7 @@ public: virtual optional 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 = 0; }; class GeometryTileLayer { 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(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(scale); + if (feature.getVersion() < 2 && feature.getType() == mapbox::vector_tile::GeomType::POLYGON) { + lines = fixupPolygons(*lines); + } } + return *lines; } VectorTileLayer::VectorTileLayer(std::shared_ptr 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 getValue(const std::string& key) const override; std::unordered_map getProperties() const override; FeatureIdentifier getID() const override; - GeometryCollection getGeometries() const override; + const GeometryCollection& getGeometries() const override; private: mapbox::vector_tile::feature feature; + mutable optional lines; }; class VectorTileLayer : public GeometryTileLayer { 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(); } - GeometryCollection getGeometries() const override { + const GeometryCollection& getGeometries() const override { return geometry; } }; -- cgit v1.2.1 From ec6650d3c0db8bff7e425518176261a8e6ed4e79 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Wed, 24 Jul 2019 13:18:40 +0300 Subject: [core] Default GeometryTileFeature::getGeometries() implementation --- src/mbgl/style/expression/expression.cpp | 3 --- src/mbgl/tile/geometry_tile_data.cpp | 5 +++++ src/mbgl/tile/geometry_tile_data.hpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mbgl/style/expression/expression.cpp b/src/mbgl/style/expression/expression.cpp index 4800f6aa7f..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; } - const GeometryCollection& getGeometries() const override { return geometry; } optional getValue(const std::string& key) const override { auto it = feature.properties.find(key); if (it != feature.properties.end()) { @@ -25,8 +24,6 @@ public: } return optional(); } - - GeometryCollection geometry; }; diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp index 2dda9ecae4..c7aea35944 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -180,4 +180,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 db3378a019..a0d41608a3 100644 --- a/src/mbgl/tile/geometry_tile_data.hpp +++ b/src/mbgl/tile/geometry_tile_data.hpp @@ -44,7 +44,7 @@ public: virtual optional getValue(const std::string& key) const = 0; virtual PropertyMap getProperties() const { return PropertyMap(); } virtual FeatureIdentifier getID() const { return NullValue {}; } - virtual const GeometryCollection& getGeometries() const = 0; + virtual const GeometryCollection& getGeometries() const; }; class GeometryTileLayer { -- cgit v1.2.1 From a242bd107041bc740788ee8298fd7848c923442f Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Wed, 24 Jul 2019 14:12:04 +0300 Subject: [core] Optimize RenderLineLayer::queryIntersectsFeature --- src/mbgl/renderer/layers/render_line_layer.cpp | 35 ++++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) 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 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 zero(0, 0); + newRings.reserve(rings.size()); + + const Point 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 aToB = i == ring.begin() ? @@ -237,13 +243,15 @@ optional 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(extrude * offset) + p); + newRing.emplace_back(convertPoint(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() .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() { -- cgit v1.2.1 From 2c2e8589c341e2940202b781f7eb539b82b3599d Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Wed, 24 Jul 2019 14:52:40 +0300 Subject: [core] GeometryCollection must not be implicitly copied --- src/mbgl/layout/pattern_layout.hpp | 2 +- src/mbgl/layout/symbol_feature.hpp | 2 +- src/mbgl/tile/geometry_tile_data.cpp | 23 +++++++++--------- src/mbgl/tile/geometry_tile_data.hpp | 7 ++++++ src/mbgl/tile/geometry_tile_worker.cpp | 2 +- test/gl/bucket.test.cpp | 2 +- test/util/merge_lines.test.cpp | 44 +++++++++++++++++----------------- 7 files changed, 44 insertions(+), 38 deletions(-) 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 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 2c952fc12a..72e88fb55e 100644 --- a/src/mbgl/layout/symbol_feature.hpp +++ b/src/mbgl/layout/symbol_feature.hpp @@ -13,7 +13,7 @@ class SymbolFeature : public GeometryTileFeature { public: SymbolFeature(std::unique_ptr 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(); } diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp index c7aea35944..db9f37ad4b 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -57,32 +57,31 @@ std::vector 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; } diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp index a0d41608a3..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(std::forward(args)...) {} GeometryCollection(std::initializer_list args) : std::vector(std::move(args)) {} + GeometryCollection(GeometryCollection&&) = default; + GeometryCollection& operator=(GeometryCollection&&) = default; + + GeometryCollection clone() const { return GeometryCollection(*this); } + +private: + GeometryCollection(const GeometryCollection&) = default; }; class GeometryTileFeature { 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(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/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/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 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 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 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 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 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 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 input; input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, properties, aaa, {}, 0 }); - const std::vector 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 input; input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, properties, aaa, {}, 0 }); - const std::vector 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()); } -- cgit v1.2.1 From 05afd88aac1106be9543311f7d0ba28ddb79caaf Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Wed, 24 Jul 2019 13:22:42 -0700 Subject: [ios] Prepare ios-v5.2.0 release --- platform/ios/CHANGELOG.md | 23 ++++++++++++++++++---- .../ios/Mapbox-iOS-SDK-snapshot-dynamic.podspec | 2 +- platform/ios/Mapbox-iOS-SDK-stripped.podspec | 2 +- platform/ios/Mapbox-iOS-SDK.podspec | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index e529607a48..9fe972c18c 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -6,10 +6,9 @@ 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)) - -## 5.2.0 +## 5.2.0 - July 24, 2019 ### Networking @@ -57,10 +56,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 -- cgit v1.2.1 From a8db681454e5173c03154e79c5f125ce26d653c1 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Wed, 24 Jul 2019 15:10:31 -0700 Subject: [ios, build] Trigger external deploy jobs before long-running build tasks --- circle.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index a60e83fa72..ba624dc251 100644 --- a/circle.yml +++ b/circle.yml @@ -1109,13 +1109,19 @@ jobs: - install-macos-dependencies - 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 -- cgit v1.2.1