From 1a8ba94774cc9e580b7b5edf2a26e102251197c6 Mon Sep 17 00:00:00 2001 From: zmiao Date: Tue, 27 Aug 2019 16:46:47 +0300 Subject: [PATCH] Cherry-pick #15456 [core] fix mixed sdf + non-sdf icon rendering in one layer (#15494) * [core] fix mixed sdf + non-sdf icon rendering in one layer (#15456) * [core] fix icon symbol rendring when sdf and non-sdf icon in the same symbol layer * fix build error * fix typo * revert renderableSegment change * simplify codes * fix build error * refine sdf icon flag * [core] fix mixed sdf + non-sdf icon rendering in one layer * remove iconstatus getter in stymbol bucket * fix review findings * provide bitwise operator for SymbolContent enum * use MBGL_MBGL_CONSTEXPR * add one missing update for sdfIcon * make renderer symbol type as enum * Add changelog for fix of mixed SDF+non-SDF icon rendering in one layer (#15492) * Add changelog for fix of mixed SDF+non-SDF icon rendering in one layer * Add bracket for ios changelog number * Add more brackets --- platform/android/CHANGELOG.md | 3 + platform/ios/CHANGELOG.md | 4 + platform/macos/CHANGELOG.md | 7 +- platform/node/CHANGELOG.md | 9 ++- src/mbgl/layout/symbol_instance.cpp | 22 +++-- src/mbgl/layout/symbol_instance.hpp | 31 ++++++- src/mbgl/layout/symbol_layout.cpp | 54 +++++++------ src/mbgl/layout/symbol_layout.hpp | 4 +- src/mbgl/renderer/buckets/symbol_bucket.cpp | 45 +++++++---- src/mbgl/renderer/buckets/symbol_bucket.hpp | 6 +- .../renderer/layers/render_symbol_layer.cpp | 43 ++++++---- .../renderer/layers/render_symbol_layer.hpp | 6 ++ src/mbgl/text/placement.cpp | 80 ++++++++++++------- test/gl/bucket.test.cpp | 4 +- test/text/cross_tile_symbol_index.test.cpp | 24 +++--- 15 files changed, 214 insertions(+), 128 deletions(-) diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 54729fbcc54..579d97765f5 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -4,6 +4,9 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to ## master +### Bug fixes +- Fixed a rendering issue that non-SDF icon would be treated as SDF icon if they are in the same layer. [#15456](https://github.com/mapbox/mapbox-gl-native/pull/15456) + ## 8.3.0 This release changes how offline tile requests are billed — they are now billed on a pay-as-you-go basis and all developers are able raise the offline tile limit for their users. Offline requests were previously exempt from monthly active user (MAU) billing and increasing the offline per-user tile limit to more than 6,000 tiles required the purchase of an enterprise license. By upgrading to this release, you are opting into the changes outlined in [this blog post](https://blog.mapbox.com/offline-maps-for-all-bb0fc51827be) and [#15380](https://github.com/mapbox/mapbox-gl-native/pull/15380). diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 9b0c6ae2fb7..c5525c8bf2a 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -2,6 +2,10 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started. +## master + +* Fixed a rendering issue that non-SDF icon would be treated as SDF icon if they are in the same layer. ([#15456](https://github.com/mapbox/mapbox-gl-native/pull/15456)) + ## 5.3.0 This release changes how offline tile requests are billed — they are now billed on a pay-as-you-go basis and all developers are able raise the offline tile limit for their users. Offline requests were previously exempt from monthly active user (MAU) billing and increasing the offline per-user tile limit to more than 6,000 tiles required the purchase of an enterprise license. By upgrading to this release, you are opting into the changes outlined in [this blog post](https://blog.mapbox.com/offline-maps-for-all-bb0fc51827be) and [#15380](https://github.com/mapbox/mapbox-gl-native/pull/15380). diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index c0cb940b53b..076bc64a6e6 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -9,10 +9,11 @@ * The `MGLIdeographicFontFamilyName` Info.plist key now also accepts an array of font family names, to customize font fallback behavior. It can also be set to a Boolean value of `NO` to force the SDK to typeset CJK characters in a remote font specified by `MGLSymbolStyleLayer.textFontNames`. ([#14862](https://github.com/mapbox/mapbox-gl-native/pull/14862)) * Performance improvements for queryRenderedFeatures API and optimization that allocates containers based on a number of rendered layers. ([#14930](https://github.com/mapbox/mapbox-gl-native/pull/14930)) * Fixed rendering layers after fill-extrusion regression caused by optimization of fill-extrusion rendering. ([#15065](https://github.com/mapbox/mapbox-gl-native/pull/15065)) -* `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) -* Fixed an issue where animated camera transitions zoomed in or out too dramatically. [#15281](https://github.com/mapbox/mapbox-gl-native/pull/15281) +* `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)) +* Fixed an issue where animated camera transitions zoomed in or out too dramatically. ([#15281](https://github.com/mapbox/mapbox-gl-native/pull/15281)) * Fixed rendering and collision detection issues with using `text-variable-anchor` and `icon-text-fit` properties on the same layer. ([#15367](https://github.com/mapbox/mapbox-gl-native/pull/15367)) -- Fixed symbol overlap when zooming out quickly. ([15416](https://github.com/mapbox/mapbox-gl-native/pull/15416)) +* Fixed symbol overlap when zooming out quickly. ([15416](https://github.com/mapbox/mapbox-gl-native/pull/15416)) +* Fixed a rendering issue that non-SDF icon would be treated as SDF icon if they are in the same layer. ([#15456](https://github.com/mapbox/mapbox-gl-native/pull/15456)) ### Styles and rendering diff --git a/platform/node/CHANGELOG.md b/platform/node/CHANGELOG.md index fa798d26768..9338409b3e4 100644 --- a/platform/node/CHANGELOG.md +++ b/platform/node/CHANGELOG.md @@ -1,15 +1,16 @@ # master * Introduce `text-writing-mode` layout property for symbol layer ([#14932](https://github.com/mapbox/mapbox-gl-native/pull/14932)). The `text-writing-mode` layout property allows control over symbol's preferred writing mode. The new property value is an array, whose values are enumeration values from a ( `horizontal` | `vertical` ) set. * Fixed rendering and collision detection issues with using `text-variable-anchor` and `icon-text-fit` properties on the same layer ([#15367](https://github.com/mapbox/mapbox-gl-native/pull/15367)). +* Fixed a rendering issue that non-SDF icon would be treated as SDF icon if they are in the same layer. ([#15456](https://github.com/mapbox/mapbox-gl-native/pull/15456)) # 4.2.0 - Add an option to set whether or not an image should be treated as a SDF ([#15054](https://github.com/mapbox/mapbox-gl-native/issues/15054)) -- Fix problems associated with node 10 and NAN [#14847](https://github.com/mapbox/mapbox-gl-native/pull/14847) +- Fix problems associated with node 10 and NAN ([#14847](https://github.com/mapbox/mapbox-gl-native/pull/14847)) # 4.1.0 -- Add `symbol-z-order` symbol layout property to style spec [#12783](https://github.com/mapbox/mapbox-gl-native/pull/12783) -- Add `crossSourceCollisions` map option, with default of `true`. When set to `false`, cross-source collision detection is disabled. ([#12820] (https://github.com/mapbox/mapbox-gl-native/issues/12820)) -- Fixed bugs in coercion expression operators ("to-array" applied to empty arrays, "to-color" applied to colors, and "to-number" applied to null) [#12864](https://github.com/mapbox/mapbox-gl-native/pull/12864) +- Add `symbol-z-order` symbol layout property to style spec ([#12783](https://github.com/mapbox/mapbox-gl-native/pull/12783)) +- Add `crossSourceCollisions` map option, with default of `true`. When set to `false`, cross-source collision detection is disabled. ([#12820](https://github.com/mapbox/mapbox-gl-native/issues/12820)) +- Fixed bugs in coercion expression operators ("to-array" applied to empty arrays, "to-color" applied to colors, and "to-number" applied to null) ([#12864](https://github.com/mapbox/mapbox-gl-native/pull/12864)) - Fixed an issue where fill and line layers would occasionally flicker on zoom ([#12982](https://github.com/mapbox/mapbox-gl-native/pull/12982)) # 4.0.0 diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index 8be025afe18..ad36e6c38c5 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -88,12 +88,11 @@ SymbolInstance::SymbolInstance(Anchor& anchor_, const float iconRotation, const float textRotation, float radialTextOffset_, - bool allowVerticalPlacement) : + bool allowVerticalPlacement, + const SymbolContent iconType) : sharedData(std::move(sharedData_)), anchor(anchor_), - // 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap - hasText(!sharedData->empty()), - hasIcon(shapedIcon), + symbolContent(iconType), // 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(sharedData->line, anchor, getAnyShaping(shapedTextOrientations), textBoxScale_, textPadding, textPlacement, indexedFeature, overscaling, textRotation), @@ -107,7 +106,8 @@ SymbolInstance::SymbolInstance(Anchor& anchor_, textBoxScale(textBoxScale_), radialTextOffset(radialTextOffset_), singleLine(shapedTextOrientations.singleLine) { - + // 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap + if(!sharedData->empty()) symbolContent |= SymbolContent::Text; if (allowVerticalPlacement && shapedTextOrientations.vertical) { const float verticalPointLabelAngle = 90.0f; verticalTextCollisionFeature = CollisionFeature(line(), anchor, shapedTextOrientations.vertical, textBoxScale_, textPadding, textPlacement, indexedFeature, overscaling, textRotation + verticalPointLabelAngle); @@ -164,6 +164,18 @@ const optional& SymbolInstance::iconQuad() const { assert(sharedData); return sharedData->iconQuad; } + +bool SymbolInstance::hasText() const { + return static_cast(symbolContent & SymbolContent::Text); +} + +bool SymbolInstance::hasIcon() const { + return static_cast(symbolContent & SymbolContent::IconRGBA) || hasSdfIcon(); +} + +bool SymbolInstance::hasSdfIcon() const { + return static_cast(symbolContent & SymbolContent::IconSDF); +} const optional& SymbolInstance::verticalIconQuad() const { assert(sharedData); diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 60883c12dbf..7d002d22859 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -4,7 +4,8 @@ #include #include #include - +#include +#include namespace mbgl { @@ -42,6 +43,25 @@ struct SymbolInstanceSharedData { optional verticalIconQuad; }; +enum class SymbolContent : uint8_t { + None = 0, + Text = 1 << 0, + IconRGBA = 1 << 1, + IconSDF = 1 << 2 +}; + +MBGL_CONSTEXPR SymbolContent operator|(SymbolContent a, SymbolContent b) { + return SymbolContent(mbgl::underlying_type(a) | mbgl::underlying_type(b)); +} + +MBGL_CONSTEXPR SymbolContent& operator|=(SymbolContent& a, SymbolContent b) { + return (a = a | b); +} + +MBGL_CONSTEXPR SymbolContent operator&(SymbolContent a, SymbolContent b) { + return SymbolContent(mbgl::underlying_type(a) & mbgl::underlying_type(b)); +} + class SymbolInstance { public: SymbolInstance(Anchor& anchor_, @@ -64,7 +84,8 @@ class SymbolInstance { const float iconRotation, const float textRotation, float radialTextOffset, - bool allowVerticalPlacement); + bool allowVerticalPlacement, + const SymbolContent iconType = SymbolContent::None); optional getDefaultHorizontalPlacedTextIndex() const; const GeometryCoordinates& line() const; @@ -72,6 +93,9 @@ class SymbolInstance { const SymbolQuads& leftJustifiedGlyphQuads() const; const SymbolQuads& centerJustifiedGlyphQuads() const; const SymbolQuads& verticalGlyphQuads() const; + bool hasText() const; + bool hasIcon() const; + bool hasSdfIcon() const; const optional& iconQuad() const; const optional& verticalIconQuad() const; void releaseSharedData(); @@ -81,8 +105,7 @@ class SymbolInstance { public: Anchor anchor; - bool hasText; - bool hasIcon; + SymbolContent symbolContent; std::size_t rightJustifiedGlyphQuadsSize; std::size_t centerJustifiedGlyphQuadsSize; diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 6a13bb22ae8..fe169785ceb 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -398,16 +398,18 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions } // if feature has icon, get sprite atlas position + SymbolContent iconType{SymbolContent::None}; if (feature.icon) { auto image = imageMap.find(*feature.icon); if (image != imageMap.end()) { + iconType = SymbolContent::IconRGBA; shapedIcon = PositionedIcon::shapeIcon( imagePositions.at(*feature.icon), layout->evaluate(zoom, feature), layout->evaluate(zoom, feature), layout->evaluate(zoom, feature) * util::DEG2RAD); if (image->second->sdf) { - sdfIcons = true; + iconType = SymbolContent::IconSDF; } if (image->second->pixelRatio != pixelRatio) { iconsNeedLinear = true; @@ -419,7 +421,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions // if either shapedText or icon position is present, add the feature if (getDefaultHorizontalShaping(shapedTextOrientations) || shapedIcon) { - addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, std::move(shapedIcon), glyphPositions, textOffset); + addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, std::move(shapedIcon), glyphPositions, textOffset, iconType); } feature.geometry.clear(); @@ -433,7 +435,8 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const ShapedTextOrientations& shapedTextOrientations, optional shapedIcon, const GlyphPositions& glyphPositions, - Point offset) { + Point offset, + const SymbolContent iconType) { const float minScale = 0.5f; const float glyphSize = 24.0f; @@ -500,7 +503,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, iconBoxScale, iconPadding, iconOffset, indexedFeature, layoutFeatureIndex, feature.index, feature.formattedText ? feature.formattedText->rawText() : std::u16string(), - overscaling, iconRotation, textRotation, radialTextOffset, allowVerticalPlacement); + overscaling, iconRotation, textRotation, radialTextOffset, allowVerticalPlacement, iconType); } }; @@ -620,14 +623,14 @@ std::vector CalculateTileDistances(const GeometryCoordinates& line, const } void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr&, std::unordered_map& renderData, const bool firstLoad, const bool showCollisionBoxes) { - auto bucket = std::make_shared(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, + auto bucket = std::make_shared(layout, layerPaintProperties, textSize, iconSize, zoom, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), tilePixelRatio, allowVerticalPlacement, std::move(placementModes)); for (SymbolInstance &symbolInstance : bucket->symbolInstances) { - const bool hasText = symbolInstance.hasText; - const bool hasIcon = symbolInstance.hasIcon; + const bool hasText = symbolInstance.hasText(); + const bool hasIcon = symbolInstance.hasIcon(); const bool singleLine = symbolInstance.singleLine; const auto& feature = features.at(symbolInstance.layoutFeatureIndex); @@ -637,26 +640,25 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr sizeData = bucket->iconSizeBinder->getVertexSizeData(feature); - const auto placeIcon = [&] (const SymbolQuad& iconQuad, auto& index, const WritingModeType writingMode) { - bucket->icon.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max, - symbolInstance.iconOffset, writingMode, symbolInstance.line(), std::vector()); - index = bucket->icon.placedSymbols.size() - 1; - PlacedSymbol& iconSymbol = bucket->icon.placedSymbols.back(); - iconSymbol.angle = (allowVerticalPlacement && writingMode == WritingModeType::Vertical) ? M_PI_2 : 0; - iconSymbol.vertexStartIndex = addSymbol(bucket->icon, sizeData, iconQuad, - symbolInstance.anchor, iconSymbol, feature.sortKey); - }; - - placeIcon(*symbolInstance.iconQuad(), symbolInstance.placedIconIndex, WritingModeType::None); - if (symbolInstance.verticalIconQuad()) { - placeIcon(*symbolInstance.verticalIconQuad(), symbolInstance.placedVerticalIconIndex, WritingModeType::Vertical); - } + const Range sizeData = bucket->iconSizeBinder->getVertexSizeData(feature); + auto& iconBuffer = symbolInstance.hasSdfIcon() ? bucket->sdfIcon : bucket->icon; + const auto placeIcon = [&] (const SymbolQuad& iconQuad, auto& index, const WritingModeType writingMode) { + iconBuffer.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max, + symbolInstance.iconOffset, writingMode, symbolInstance.line(), std::vector()); + index = iconBuffer.placedSymbols.size() - 1; + PlacedSymbol& iconSymbol = iconBuffer.placedSymbols.back(); + iconSymbol.angle = (allowVerticalPlacement && writingMode == WritingModeType::Vertical) ? M_PI_2 : 0; + iconSymbol.vertexStartIndex = addSymbol(iconBuffer, sizeData, iconQuad, + symbolInstance.anchor, iconSymbol, feature.sortKey); + }; - for (auto& pair : bucket->paintProperties) { - pair.second.iconBinders.populateVertexVectors(feature, bucket->icon.vertices.elements(), {}, {}); - } + placeIcon(*symbolInstance.iconQuad(), symbolInstance.placedIconIndex, WritingModeType::None); + if (symbolInstance.verticalIconQuad()) { + placeIcon(*symbolInstance.verticalIconQuad(), symbolInstance.placedVerticalIconIndex, WritingModeType::Vertical); + } + + for (auto& pair : bucket->paintProperties) { + pair.second.iconBinders.populateVertexVectors(feature, iconBuffer.vertices.elements(), {}, {}); } } diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 6cc21c6d91a..8d4c51148a3 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -53,7 +53,8 @@ class SymbolLayout final : public Layout { const ShapedTextOrientations& shapedTextOrientations, optional shapedIcon, const GlyphPositions&, - Point textOffset); + Point textOffset, + const SymbolContent iconType); bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&); std::map> compareText; @@ -93,7 +94,6 @@ class SymbolLayout final : public Layout { const uint32_t tileSize; const float tilePixelRatio; - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; bool allowVerticalPlacement = false; diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index 681a492e734..a46c25a13be 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -18,7 +18,6 @@ SymbolBucket::SymbolBucket(Immutable& textSize, const style::PropertyValue& iconSize, float zoom, - bool sdfIcons_, bool iconsNeedLinear_, bool sortFeaturesByY_, const std::string bucketName_, @@ -28,7 +27,6 @@ SymbolBucket::SymbolBucket(Immutable placementModes_) : layout(std::move(layout_)), bucketLeaderID(std::move(bucketName_)), - sdfIcons(sdfIcons_), iconsNeedLinear(iconsNeedLinear_ || iconSize.isDataDriven() || !iconSize.isZoomConstant()), sortFeaturesByY(sortFeaturesByY_), staticUploaded(false), @@ -87,30 +85,37 @@ void SymbolBucket::upload(gfx::UploadPass& uploadPass) { } } - if (hasIconData()) { + auto updateIconBuffer = [&](Buffer& iconBuffer) { if (!staticUploaded) { - icon.indexBuffer = uploadPass.createIndexBuffer(std::move(icon.triangles), sortFeaturesByY ? gfx::BufferUsageType::StreamDraw : gfx::BufferUsageType::StaticDraw); - icon.vertexBuffer = uploadPass.createVertexBuffer(std::move(icon.vertices)); + iconBuffer.indexBuffer = uploadPass.createIndexBuffer(std::move(iconBuffer.triangles), sortFeaturesByY ? gfx::BufferUsageType::StreamDraw : gfx::BufferUsageType::StaticDraw); + iconBuffer.vertexBuffer = uploadPass.createVertexBuffer(std::move(iconBuffer.vertices)); for (auto& pair : paintProperties) { pair.second.iconBinders.upload(uploadPass); } } else if (!sortUploaded) { - uploadPass.updateIndexBuffer(*icon.indexBuffer, std::move(icon.triangles)); + uploadPass.updateIndexBuffer(*iconBuffer.indexBuffer, std::move(iconBuffer.triangles)); } if (!dynamicUploaded) { - if (!icon.dynamicVertexBuffer) { - icon.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(icon.dynamicVertices), gfx::BufferUsageType::StreamDraw); + if (!iconBuffer.dynamicVertexBuffer) { + iconBuffer.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(iconBuffer.dynamicVertices), gfx::BufferUsageType::StreamDraw); } else { - uploadPass.updateVertexBuffer(*icon.dynamicVertexBuffer, std::move(icon.dynamicVertices)); + uploadPass.updateVertexBuffer(*iconBuffer.dynamicVertexBuffer, std::move(iconBuffer.dynamicVertices)); } } if (!placementChangesUploaded) { - if (!icon.opacityVertexBuffer) { - icon.opacityVertexBuffer = uploadPass.createVertexBuffer(std::move(icon.opacityVertices), gfx::BufferUsageType::StreamDraw); + if (!iconBuffer.opacityVertexBuffer) { + iconBuffer.opacityVertexBuffer = uploadPass.createVertexBuffer(std::move(iconBuffer.opacityVertices), gfx::BufferUsageType::StreamDraw); } else { - uploadPass.updateVertexBuffer(*icon.opacityVertexBuffer, std::move(icon.opacityVertices)); + uploadPass.updateVertexBuffer(*iconBuffer.opacityVertexBuffer, std::move(iconBuffer.opacityVertices)); } } + }; + if (hasIconData()) { + updateIconBuffer(icon); + } + + if (hasSdfIconData()) { + updateIconBuffer(sdfIcon); } if (hasCollisionBoxData()) { @@ -149,7 +154,7 @@ void SymbolBucket::upload(gfx::UploadPass& uploadPass) { } bool SymbolBucket::hasData() const { - return hasTextData() || hasIconData() || hasCollisionBoxData(); + return hasTextData() || hasIconData() || hasSdfIconData() || hasCollisionBoxData(); } bool SymbolBucket::hasTextData() const { @@ -160,6 +165,10 @@ bool SymbolBucket::hasIconData() const { return !icon.segments.empty(); } +bool SymbolBucket::hasSdfIconData() const { + return !sdfIcon.segments.empty(); +} + bool SymbolBucket::hasCollisionBoxData() const { return collisionBox && !collisionBox->segments.empty(); } @@ -188,9 +197,9 @@ void SymbolBucket::sortFeatures(const float angle) { sortedAngle = angle; - // The current approach to sorting doesn't sort across segments so don't try. + // The current approach to sorting doesn't sort across text and icon segments so don't try. // Sorting within segments separately seemed not to be worth the complexity. - if (text.segments.size() > 1 || icon.segments.size() > 1) { + if (text.segments.size() > 1 || (icon.segments.size() > 1 || sdfIcon.segments.size() > 1)) { return; } @@ -199,6 +208,7 @@ void SymbolBucket::sortFeatures(const float angle) { text.triangles.clear(); icon.triangles.clear(); + sdfIcon.triangles.clear(); featureSortOrder = std::make_unique>(); featureSortOrder->reserve(symbolInstances.size()); @@ -225,12 +235,13 @@ void SymbolBucket::sortFeatures(const float angle) { addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedVerticalTextIndex]); } + auto& iconBuffer = symbolInstance.hasSdfIcon() ? sdfIcon : icon; if (symbolInstance.placedIconIndex) { - addPlacedSymbol(icon.triangles, icon.placedSymbols[*symbolInstance.placedIconIndex]); + addPlacedSymbol(iconBuffer.triangles, iconBuffer.placedSymbols[*symbolInstance.placedIconIndex]); } if (symbolInstance.placedVerticalIconIndex) { - addPlacedSymbol(icon.triangles, icon.placedSymbols[*symbolInstance.placedVerticalIconIndex]); + addPlacedSymbol(iconBuffer.triangles, iconBuffer.placedSymbols[*symbolInstance.placedVerticalIconIndex]); } } } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index 20c0c5b7905..d813707c2fb 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -55,7 +55,6 @@ class SymbolBucket final : public Bucket { const style::PropertyValue& textSize, const style::PropertyValue& iconSize, float zoom, - bool sdfIcons, bool iconsNeedLinear, bool sortFeaturesByY, const std::string bucketLeaderID, @@ -72,6 +71,7 @@ class SymbolBucket final : public Bucket { void updateVertices(Placement&, bool updateOpacities, const TransformState&, const RenderTile&, std::set&) override; bool hasTextData() const; bool hasIconData() const; + bool hasSdfIconData() const; bool hasCollisionBoxData() const; bool hasCollisionCircleData() const; bool hasFormatSectionOverrides() const; @@ -86,7 +86,6 @@ class SymbolBucket final : public Bucket { float sortedAngle = std::numeric_limits::max(); // Flags - const bool sdfIcons : 1; const bool iconsNeedLinear : 1; const bool sortFeaturesByY : 1; bool staticUploaded : 1; @@ -124,7 +123,8 @@ class SymbolBucket final : public Bucket { std::unique_ptr iconSizeBinder; Buffer icon; - + Buffer sdfIcon; + struct CollisionBuffer { gfx::VertexVector> vertices; gfx::VertexVector> dynamicVertices; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index ffb32b9746e..d0c038222a3 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -67,20 +67,20 @@ struct RenderableSegment { const LayerRenderData& renderData_, const SymbolBucket::PaintProperties& bucketPaintProperties_, float sortKey_, - bool isText_) : + const SymbolType type_) : segment(std::move(segment_)), tile(tile_), renderData(renderData_), bucketPaintProperties(bucketPaintProperties_), sortKey(sortKey_), - isText(isText_) {} + type(type_) {} SegmentWrapper segment; const RenderTile& tile; const LayerRenderData& renderData; const SymbolBucket::PaintProperties& bucketPaintProperties; float sortKey; - bool isText; + SymbolType type; friend bool operator < (const RenderableSegment& lhs, const RenderableSegment& rhs) { // Sort renderable segments by a sort key. @@ -91,11 +91,11 @@ struct RenderableSegment { // In cases when sort key is the same, sort by the type of a segment (text over icons), // and for segments of the same type with the same sort key, sort by a tile id. if (lhs.sortKey == rhs.sortKey) { - if (!lhs.isText && rhs.isText) { + if (lhs.type != SymbolType::Text && rhs.type == SymbolType::Text) { return true; } - if (lhs.isText == rhs.isText) { + if (lhs.type == rhs.type) { return lhs.tile.id < rhs.tile.id; } } @@ -110,7 +110,8 @@ void drawIcon(const DrawFn& draw, const LayerRenderData& renderData, SegmentsWrapper iconSegments, const SymbolBucket::PaintProperties& bucketPaintProperties, - const PaintParameters& parameters) { + const PaintParameters& parameters, + const bool sdfIcons) { auto& bucket = static_cast(*renderData.bucket); const auto& evaluated = getEvaluated(renderData.layerProperties); const auto& layout = *bucket.layout; @@ -124,7 +125,7 @@ void drawIcon(const DrawFn& draw, const bool iconTransformed = values.rotationAlignment == AlignmentType::Map || parameters.state.getPitch() != 0; const gfx::TextureBinding textureBinding{ tile.getIconAtlasTexture().getResource(), - bucket.sdfIcons || + sdfIcons || parameters.state.isChanging() || iconScaled || iconTransformed ? gfx::TextureFilterType::Linear @@ -133,11 +134,11 @@ void drawIcon(const DrawFn& draw, const Size& iconSize = tile.getIconAtlasTexture().size; const bool variablePlacedIcon = bucket.hasVariablePlacement && layout.get() != IconTextFitType::None; - if (bucket.sdfIcons) { + if (sdfIcons) { if (values.hasHalo) { draw(parameters.programs.getSymbolLayerPrograms().symbolIconSDF, SymbolSDFIconProgram::layoutUniformValues(false, variablePlacedIcon, values, iconSize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo), - bucket.icon, + bucket.sdfIcon, iconSegments, bucket.iconSizeBinder, bucketPaintProperties.iconBinders, @@ -151,7 +152,7 @@ void drawIcon(const DrawFn& draw, if (values.hasFill) { draw(parameters.programs.getSymbolLayerPrograms().symbolIconSDF, SymbolSDFIconProgram::layoutUniformValues(false, variablePlacedIcon, values, iconSize, parameters.pixelsToGLUnits, parameters.pixelRatio, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill), - bucket.icon, + bucket.sdfIcon, iconSegments, bucket.iconSizeBinder, bucketPaintProperties.iconBinders, @@ -361,23 +362,31 @@ void RenderSymbolLayer::render(PaintParameters& parameters) { assert(bucket.paintProperties.find(getID()) != bucket.paintProperties.end()); const auto& bucketPaintProperties = bucket.paintProperties.at(getID()); - auto addRenderables = [&renderableSegments, &tile, renderData, &bucketPaintProperties, it = renderableSegments.begin()] (auto& segments, bool isText) mutable { + auto addRenderables = [&renderableSegments, &tile, renderData, &bucketPaintProperties, it = renderableSegments.begin()] (auto& segments, const SymbolType type) mutable { for (auto& segment : segments) { - it = renderableSegments.emplace_hint(it, SegmentWrapper{std::ref(segment)}, tile, *renderData, bucketPaintProperties, segment.sortKey, isText); + it = renderableSegments.emplace_hint(it, SegmentWrapper{std::ref(segment)}, tile, *renderData, bucketPaintProperties, segment.sortKey, type); } }; if (bucket.hasIconData()) { if (sortFeaturesByKey) { - addRenderables(bucket.icon.segments, false /*isText*/); + addRenderables(bucket.icon.segments, SymbolType::IconRGBA); + } else { + drawIcon(draw, tile, *renderData, std::ref(bucket.icon.segments), bucketPaintProperties, parameters, false /*sdfIcon*/); + } + } + + if (bucket.hasSdfIconData()) { + if (sortFeaturesByKey) { + addRenderables(bucket.sdfIcon.segments, SymbolType::IconSDF); } else { - drawIcon(draw, tile, *renderData, std::ref(bucket.icon.segments), bucketPaintProperties, parameters); + drawIcon(draw, tile, *renderData, std::ref(bucket.sdfIcon.segments), bucketPaintProperties, parameters, true /*sdfIcon*/); } } if (bucket.hasTextData()) { if (sortFeaturesByKey) { - addRenderables(bucket.text.segments, true /*isText*/); + addRenderables(bucket.text.segments, SymbolType::Text); } else { drawText(draw, tile, *renderData, std::ref(bucket.text.segments), bucketPaintProperties, parameters); } @@ -460,10 +469,10 @@ void RenderSymbolLayer::render(PaintParameters& parameters) { if (sortFeaturesByKey) { for (auto& renderable : renderableSegments) { - if (renderable.isText) { + if (renderable.type == SymbolType::Text) { drawText(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters); } else { - drawIcon(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters); + drawIcon(draw, renderable.tile, renderable.renderData, renderable.segment, renderable.bucketPaintProperties, parameters, renderable.type == SymbolType::IconSDF); } } } diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index d9ce8c688d3..5fcb9e2c8c1 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -50,6 +50,12 @@ class SymbolPropertyValues { bool hasFill; }; +enum class SymbolType : uint8_t { + Text, + IconRGBA, + IconSDF +}; + } // namespace style class RenderSymbolLayer final: public RenderLayer { diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 9f9d948b945..9bc87911ded 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -153,7 +153,7 @@ void Placement::placeBucket( // This is the reverse of our normal policy of "fade in on pan", but should look like any other // collision and hopefully not be too noticeable. // See https://github.com/mapbox/mapbox-gl-native/issues/12683 - const bool alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || layout.get()); + const bool alwaysShowText = textAllowOverlap && (iconAllowOverlap || !(bucket.hasIconData() || bucket.hasSdfIconData()) || layout.get()); const bool alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || layout.get()); std::vector variableTextAnchors = layout.get(); const bool rotateWithMap = layout.get() == style::AlignmentType::Map; @@ -367,7 +367,8 @@ void Placement::placeBucket( shift = {0.0f, 0.0f}; } - const PlacedSymbol& placedSymbol = bucket.icon.placedSymbols.at(*symbolInstance.placedIconIndex); + const auto& iconBuffer = symbolInstance.hasSdfIcon() ? bucket.sdfIcon : bucket.icon; + const PlacedSymbol& placedSymbol = iconBuffer.placedSymbols.at(*symbolInstance.placedIconIndex); const float fontSize = evaluateSizeForFeature(partiallyEvaluatedIconSize, placedSymbol); const auto& placeIconFeature = [&] (const CollisionFeature& collisionFeature) { return collisionIndex.placeFeature(collisionFeature, shift, @@ -389,8 +390,8 @@ void Placement::placeBucket( offscreen &= placedIcon.second; } - const bool iconWithoutText = !symbolInstance.hasText || layout.get(); - const bool textWithoutIcon = !symbolInstance.hasIcon || layout.get(); + const bool iconWithoutText = !symbolInstance.hasText() || layout.get(); + const bool textWithoutIcon = !symbolInstance.hasIcon() || layout.get(); // combine placements for icon and text if (!iconWithoutText && !textWithoutIcon) { @@ -538,17 +539,25 @@ bool Placement::updateBucketDynamicVertices(SymbolBucket& bucket, const Transfor const auto& layout = *bucket.layout; const bool alongLine = layout.get() != SymbolPlacementType::Point; const bool hasVariableAnchors = !layout.get().empty() && bucket.hasTextData(); - const bool updateTextFitIcon = layout.get() != IconTextFitType::None && (bucket.allowVerticalPlacement || hasVariableAnchors) && bucket.hasIconData(); + const bool updateTextFitIcon = layout.get() != IconTextFitType::None && (bucket.allowVerticalPlacement || hasVariableAnchors) && (bucket.hasIconData() || bucket.hasSdfIconData()); bool result = false; if (alongLine) { - if (bucket.hasIconData() && layout.get() == AlignmentType::Map) { + if (layout.get() == AlignmentType::Map) { const bool pitchWithMap = layout.get() == style::AlignmentType::Map; const bool keepUpright = layout.get(); - reprojectLineLabels(bucket.icon.dynamicVertices, bucket.icon.placedSymbols, - tile.matrix, pitchWithMap, true /*rotateWithMap*/, keepUpright, - tile, *bucket.iconSizeBinder, state); - result = true; + if (bucket.hasSdfIconData()) { + reprojectLineLabels(bucket.sdfIcon.dynamicVertices, bucket.sdfIcon.placedSymbols, + tile.matrix, pitchWithMap, true /*rotateWithMap*/, keepUpright, + tile, *bucket.iconSizeBinder, state); + result = true; + } + if (bucket.hasIconData()) { + reprojectLineLabels(bucket.icon.dynamicVertices, bucket.icon.placedSymbols, + tile.matrix, pitchWithMap, true /*rotateWithMap*/, keepUpright, + tile, *bucket.iconSizeBinder, state); + result = true; + } } if (bucket.hasTextData() && layout.get() == AlignmentType::Map) { @@ -633,22 +642,26 @@ bool Placement::updateBucketDynamicVertices(SymbolBucket& bucket, const Transfor } if (updateTextFitIcon && bucket.hasVariablePlacement) { - bucket.icon.dynamicVertices.clear(); - for (std::size_t i = 0; i < bucket.icon.placedSymbols.size(); ++i) { - const PlacedSymbol& placedIcon = bucket.icon.placedSymbols[i]; - if (placedIcon.hidden || (!placedIcon.placedOrientation && bucket.allowVerticalPlacement)) { - hideGlyphs(placedIcon.glyphOffsets.size(), bucket.icon.dynamicVertices); - } else { - const auto& pair = placedTextShifts.find(i); - if (pair == placedTextShifts.end()) { - hideGlyphs(placedIcon.glyphOffsets.size(), bucket.icon.dynamicVertices); + auto updateIcon = [&](SymbolBucket::Buffer& iconBuffer) { + iconBuffer.dynamicVertices.clear(); + for (std::size_t i = 0; i < iconBuffer.placedSymbols.size(); ++i) { + const PlacedSymbol& placedIcon = iconBuffer.placedSymbols[i]; + if (placedIcon.hidden || (!placedIcon.placedOrientation && bucket.allowVerticalPlacement)) { + hideGlyphs(placedIcon.glyphOffsets.size(), iconBuffer.dynamicVertices); } else { - for (std::size_t j = 0; j < placedIcon.glyphOffsets.size(); ++j) { - addDynamicAttributes(pair->second.second, placedIcon.angle, bucket.icon.dynamicVertices); + const auto& pair = placedTextShifts.find(i); + if (pair == placedTextShifts.end()) { + hideGlyphs(placedIcon.glyphOffsets.size(), iconBuffer.dynamicVertices); + } else { + for (std::size_t j = 0; j < placedIcon.glyphOffsets.size(); ++j) { + addDynamicAttributes(pair->second.second, placedIcon.angle, iconBuffer.dynamicVertices); + } } } } - } + }; + updateIcon(bucket.icon); + updateIcon(bucket.sdfIcon); } result = true; @@ -670,6 +683,7 @@ bool Placement::updateBucketDynamicVertices(SymbolBucket& bucket, const Transfor // When text box is rotated, icon-text-fit icon must be rotated as well. if (updateTextFitIcon) { updateDynamicVertices(bucket.icon); + updateDynamicVertices(bucket.sdfIcon); } result = true; @@ -681,6 +695,7 @@ bool Placement::updateBucketDynamicVertices(SymbolBucket& bucket, const Transfor void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState& state, std::set& seenCrossTileIDs) { if (bucket.hasTextData()) bucket.text.opacityVertices.clear(); if (bucket.hasIconData()) bucket.icon.opacityVertices.clear(); + if (bucket.hasSdfIconData()) bucket.sdfIcon.opacityVertices.clear(); if (bucket.hasCollisionBoxData()) bucket.collisionBox->dynamicVertices.clear(); if (bucket.hasCollisionCircleData()) bucket.collisionCircle->dynamicVertices.clear(); @@ -698,7 +713,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState // with allow-overlap: false. // See https://github.com/mapbox/mapbox-gl-native/issues/12483 JointOpacityState defaultOpacityState( - textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || bucket.layout->get()), + textAllowOverlap && (iconAllowOverlap || !(bucket.hasIconData() || bucket.hasSdfIconData()) || bucket.layout->get()), iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || bucket.layout->get()), true); @@ -719,7 +734,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState seenCrossTileIDs.insert(symbolInstance.crossTileID); - if (symbolInstance.hasText) { + if (symbolInstance.hasText()) { size_t textOpacityVerticesSize = 0u; const auto& opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity); if (symbolInstance.placedRightTextIndex) { @@ -758,16 +773,18 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState markUsedJustification(bucket, prevOffset->second.anchor, symbolInstance, previousOrientation); } } - if (symbolInstance.hasIcon) { + if (symbolInstance.hasIcon()) { const auto& opacityVertex = SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity); + auto& iconBuffer = symbolInstance.hasSdfIcon() ? bucket.sdfIcon : bucket.icon; + if (symbolInstance.placedIconIndex) { - bucket.icon.opacityVertices.extend(4, opacityVertex); - bucket.icon.placedSymbols[*symbolInstance.placedIconIndex].hidden = opacityState.isHidden(); + iconBuffer.opacityVertices.extend(4, opacityVertex); + iconBuffer.placedSymbols[*symbolInstance.placedIconIndex].hidden = opacityState.isHidden(); } if (symbolInstance.placedVerticalIconIndex) { - bucket.icon.opacityVertices.extend(4, opacityVertex); - bucket.icon.placedSymbols[*symbolInstance.placedVerticalIconIndex].hidden = opacityState.isHidden(); + iconBuffer.opacityVertices.extend(4, opacityVertex); + iconBuffer.placedSymbols[*symbolInstance.placedVerticalIconIndex].hidden = opacityState.isHidden(); } } @@ -919,12 +936,13 @@ void Placement::markUsedOrientation(SymbolBucket& bucket, style::TextWritingMode bucket.text.placedSymbols.at(*symbolInstance.placedVerticalTextIndex).placedOrientation = vertical; } + auto& iconBuffer = symbolInstance.hasSdfIcon() ? bucket.sdfIcon : bucket.icon; if (symbolInstance.placedIconIndex) { - bucket.icon.placedSymbols.at(*symbolInstance.placedIconIndex).placedOrientation = horizontal; + iconBuffer.placedSymbols.at(*symbolInstance.placedIconIndex).placedOrientation = horizontal; } if (symbolInstance.placedVerticalIconIndex) { - bucket.icon.placedSymbols.at(*symbolInstance.placedVerticalIconIndex).placedOrientation = vertical; + iconBuffer.placedSymbols.at(*symbolInstance.placedVerticalIconIndex).placedOrientation = vertical; } } diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index cd21a027a29..f30606ee425 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -115,15 +115,15 @@ TEST(Buckets, SymbolBucket) { gfx::BackendScope scope { backend }; auto layout = makeMutable(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; std::vector symbolInstances; gl::Context context{ backend }; - SymbolBucket bucket { std::move(layout), {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), 1.0f, false, {}}; + SymbolBucket bucket { std::move(layout), {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), 1.0f, false, {}}; ASSERT_FALSE(bucket.hasIconData()); + ASSERT_FALSE(bucket.hasSdfIconData()); ASSERT_FALSE(bucket.hasTextData()); ASSERT_FALSE(bucket.hasCollisionBoxData()); ASSERT_FALSE(bucket.hasData()); diff --git a/test/text/cross_tile_symbol_index.test.cpp b/test/text/cross_tile_symbol_index.test.cpp index a1385dfa8a7..11d6fc7de3a 100644 --- a/test/text/cross_tile_symbol_index.test.cpp +++ b/test/text/cross_tile_symbol_index.test.cpp @@ -30,7 +30,6 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { Immutable layout = makeMutable(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; @@ -39,7 +38,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { std::vector mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Detroit")); mainInstances.push_back(makeSymbolInstance(2000, 2000, u"Toronto")); - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(mainID, mainBucket, maxCrossTileID); @@ -54,7 +53,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { childInstances.push_back(makeSymbolInstance(2000, 2000, u"Windsor")); childInstances.push_back(makeSymbolInstance(3000, 3000, u"Toronto")); childInstances.push_back(makeSymbolInstance(4001, 4001, u"Toronto")); - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; childBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(childID, childBucket, maxCrossTileID); @@ -70,7 +69,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { OverscaledTileID parentID(5, 0, 5, 4, 4); std::vector parentInstances; parentInstances.push_back(makeSymbolInstance(500, 500, u"Detroit")); - SymbolBucket parentBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(parentInstances), 1.0f, false, {} }; + SymbolBucket parentBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(parentInstances), 1.0f, false, {} }; parentBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(parentID, parentBucket, maxCrossTileID); @@ -86,7 +85,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { std::vector grandchildInstances; grandchildInstances.push_back(makeSymbolInstance(4000, 4000, u"Detroit")); grandchildInstances.push_back(makeSymbolInstance(4000, 4000, u"Windsor")); - SymbolBucket grandchildBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(grandchildInstances), 1.0f, false, {} }; + SymbolBucket grandchildBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(grandchildInstances), 1.0f, false, {} }; grandchildBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(grandchildID, grandchildBucket, maxCrossTileID); @@ -105,7 +104,6 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { Immutable layout = makeMutable(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; @@ -113,13 +111,13 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { OverscaledTileID mainID(6, 0, 6, 8, 8); std::vector mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Detroit")); - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; OverscaledTileID childID(7, 0, 7, 16, 16); std::vector childInstances; childInstances.push_back(makeSymbolInstance(2000, 2000, u"Detroit")); - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; childBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns a new id @@ -146,7 +144,6 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { Immutable layout = makeMutable(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; @@ -155,7 +152,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { std::vector mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A mainInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; OverscaledTileID childID(7, 0, 7, 16, 16); @@ -163,7 +160,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // A' childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // B' childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // C' - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; childBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns new ids @@ -185,7 +182,6 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { Immutable layout = makeMutable(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; @@ -194,14 +190,14 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { std::vector firstInstances; firstInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A firstInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B - SymbolBucket firstBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(firstInstances), 1.0f, false, {} }; + SymbolBucket firstBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(firstInstances), 1.0f, false, {} }; firstBucket.bucketInstanceId = ++maxBucketInstanceId; std::vector secondInstances; secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A' secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B' secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // C' - SymbolBucket secondBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(secondInstances), 1.0f, false, {} }; + SymbolBucket secondBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(secondInstances), 1.0f, false, {} }; secondBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns new ids