summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmiao <miao.zhao@mapbox.com>2019-08-27 16:46:47 +0300
committerGitHub <noreply@github.com>2019-08-27 16:46:47 +0300
commit1a8ba94774cc9e580b7b5edf2a26e102251197c6 (patch)
tree0655af4497c79af704ff6069f098c9884b6b9400
parent6d78890a92a623ce11fbffa4fbd6a8939bbc1ed5 (diff)
downloadqtlocation-mapboxgl-1a8ba94774cc9e580b7b5edf2a26e102251197c6.tar.gz
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
-rw-r--r--platform/android/CHANGELOG.md3
-rw-r--r--platform/ios/CHANGELOG.md4
-rw-r--r--platform/macos/CHANGELOG.md7
-rw-r--r--platform/node/CHANGELOG.md9
-rw-r--r--src/mbgl/layout/symbol_instance.cpp22
-rw-r--r--src/mbgl/layout/symbol_instance.hpp31
-rw-r--r--src/mbgl/layout/symbol_layout.cpp54
-rw-r--r--src/mbgl/layout/symbol_layout.hpp4
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp45
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp6
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp43
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.hpp6
-rw-r--r--src/mbgl/text/placement.cpp80
-rw-r--r--test/gl/bucket.test.cpp4
-rw-r--r--test/text/cross_tile_symbol_index.test.cpp24
15 files changed, 214 insertions, 128 deletions
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md
index 54729fbcc5..579d97765f 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 9b0c6ae2fb..c5525c8bf2 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 c0cb940b53..076bc64a6e 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 fa798d2676..9338409b3e 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 8be025afe1..ad36e6c38c 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<SymbolQuad>& SymbolInstance::iconQuad() const {
assert(sharedData);
return sharedData->iconQuad;
}
+
+bool SymbolInstance::hasText() const {
+ return static_cast<bool>(symbolContent & SymbolContent::Text);
+}
+
+bool SymbolInstance::hasIcon() const {
+ return static_cast<bool>(symbolContent & SymbolContent::IconRGBA) || hasSdfIcon();
+}
+
+bool SymbolInstance::hasSdfIcon() const {
+ return static_cast<bool>(symbolContent & SymbolContent::IconSDF);
+}
const optional<SymbolQuad>& SymbolInstance::verticalIconQuad() const {
assert(sharedData);
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index 60883c12db..7d002d2285 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -4,7 +4,8 @@
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/text/collision_feature.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
-
+#include <mbgl/util/traits.hpp>
+#include <mbgl/util/util.hpp>
namespace mbgl {
@@ -42,6 +43,25 @@ struct SymbolInstanceSharedData {
optional<SymbolQuad> 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 @@ public:
const float iconRotation,
const float textRotation,
float radialTextOffset,
- bool allowVerticalPlacement);
+ bool allowVerticalPlacement,
+ const SymbolContent iconType = SymbolContent::None);
optional<size_t> getDefaultHorizontalPlacedTextIndex() const;
const GeometryCoordinates& line() const;
@@ -72,6 +93,9 @@ public:
const SymbolQuads& leftJustifiedGlyphQuads() const;
const SymbolQuads& centerJustifiedGlyphQuads() const;
const SymbolQuads& verticalGlyphQuads() const;
+ bool hasText() const;
+ bool hasIcon() const;
+ bool hasSdfIcon() const;
const optional<SymbolQuad>& iconQuad() const;
const optional<SymbolQuad>& verticalIconQuad() const;
void releaseSharedData();
@@ -81,8 +105,7 @@ private:
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 6a13bb22ae..fe169785ce 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<IconOffset>(zoom, feature),
layout->evaluate<IconAnchor>(zoom, feature),
layout->evaluate<IconRotate>(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<PositionedIcon> shapedIcon,
const GlyphPositions& glyphPositions,
- Point<float> offset) {
+ Point<float> 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<float> CalculateTileDistances(const GeometryCoordinates& line, const
}
void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIndex>&, std::unordered_map<std::string, LayerRenderData>& renderData, const bool firstLoad, const bool showCollisionBoxes) {
- auto bucket = std::make_shared<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear,
+ auto bucket = std::make_shared<SymbolBucket>(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<FeatureIn
// Process icon first, so that text symbols would have reference to iconIndex which
// is used when dynamic vertices for icon-text-fit image have to be updated.
if (hasIcon) {
- if (symbolInstance.hasIcon) {
- const Range<float> 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<float>());
- 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<float> 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<float>());
+ 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 6cc21c6d91..8d4c51148a 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -53,7 +53,8 @@ private:
const ShapedTextOrientations& shapedTextOrientations,
optional<PositionedIcon> shapedIcon,
const GlyphPositions&,
- Point<float> textOffset);
+ Point<float> textOffset,
+ const SymbolContent iconType);
bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&);
std::map<std::u16string, std::vector<Anchor>> compareText;
@@ -93,7 +94,6 @@ private:
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 681a492e73..a46c25a13b 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.cpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp
@@ -18,7 +18,6 @@ SymbolBucket::SymbolBucket(Immutable<style::SymbolLayoutProperties::PossiblyEval
const style::PropertyValue<float>& textSize,
const style::PropertyValue<float>& iconSize,
float zoom,
- bool sdfIcons_,
bool iconsNeedLinear_,
bool sortFeaturesByY_,
const std::string bucketName_,
@@ -28,7 +27,6 @@ SymbolBucket::SymbolBucket(Immutable<style::SymbolLayoutProperties::PossiblyEval
std::vector<style::TextWritingModeType> 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<std::vector<size_t>>();
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 20c0c5b790..d813707c2f 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -55,7 +55,6 @@ public:
const style::PropertyValue<float>& textSize,
const style::PropertyValue<float>& iconSize,
float zoom,
- bool sdfIcons,
bool iconsNeedLinear,
bool sortFeaturesByY,
const std::string bucketLeaderID,
@@ -72,6 +71,7 @@ public:
void updateVertices(Placement&, bool updateOpacities, const TransformState&, const RenderTile&, std::set<uint32_t>&) override;
bool hasTextData() const;
bool hasIconData() const;
+ bool hasSdfIconData() const;
bool hasCollisionBoxData() const;
bool hasCollisionCircleData() const;
bool hasFormatSectionOverrides() const;
@@ -86,7 +86,6 @@ public:
float sortedAngle = std::numeric_limits<float>::max();
// Flags
- const bool sdfIcons : 1;
const bool iconsNeedLinear : 1;
const bool sortFeaturesByY : 1;
bool staticUploaded : 1;
@@ -124,7 +123,8 @@ public:
std::unique_ptr<SymbolSizeBinder> iconSizeBinder;
Buffer icon;
-
+ Buffer sdfIcon;
+
struct CollisionBuffer {
gfx::VertexVector<gfx::Vertex<CollisionBoxLayoutAttributes>> vertices;
gfx::VertexVector<gfx::Vertex<CollisionBoxDynamicAttributes>> dynamicVertices;
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp
index ffb32b9746..d0c038222a 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<SymbolBucket&>(*renderData.bucket);
const auto& evaluated = getEvaluated<SymbolLayerProperties>(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<IconTextFit>() != 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 d9ce8c688d..5fcb9e2c8c 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.hpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp
@@ -50,6 +50,12 @@ public:
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 9f9d948b94..9bc87911de 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<style::IconOptional>());
+ const bool alwaysShowText = textAllowOverlap && (iconAllowOverlap || !(bucket.hasIconData() || bucket.hasSdfIconData()) || layout.get<style::IconOptional>());
const bool alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || layout.get<style::TextOptional>());
std::vector<style::TextVariableAnchorType> variableTextAnchors = layout.get<style::TextVariableAnchor>();
const bool rotateWithMap = layout.get<style::TextRotationAlignment>() == 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<style::TextOptional>();
- const bool textWithoutIcon = !symbolInstance.hasIcon || layout.get<style::IconOptional>();
+ const bool iconWithoutText = !symbolInstance.hasText() || layout.get<style::TextOptional>();
+ const bool textWithoutIcon = !symbolInstance.hasIcon() || layout.get<style::IconOptional>();
// 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<SymbolPlacement>() != SymbolPlacementType::Point;
const bool hasVariableAnchors = !layout.get<TextVariableAnchor>().empty() && bucket.hasTextData();
- const bool updateTextFitIcon = layout.get<IconTextFit>() != IconTextFitType::None && (bucket.allowVerticalPlacement || hasVariableAnchors) && bucket.hasIconData();
+ const bool updateTextFitIcon = layout.get<IconTextFit>() != IconTextFitType::None && (bucket.allowVerticalPlacement || hasVariableAnchors) && (bucket.hasIconData() || bucket.hasSdfIconData());
bool result = false;
if (alongLine) {
- if (bucket.hasIconData() && layout.get<IconRotationAlignment>() == AlignmentType::Map) {
+ if (layout.get<IconRotationAlignment>() == AlignmentType::Map) {
const bool pitchWithMap = layout.get<style::IconPitchAlignment>() == style::AlignmentType::Map;
const bool keepUpright = layout.get<style::IconKeepUpright>();
- 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<TextRotationAlignment>() == 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<uint32_t>& 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<style::IconOptional>()),
+ textAllowOverlap && (iconAllowOverlap || !(bucket.hasIconData() || bucket.hasSdfIconData()) || bucket.layout->get<style::IconOptional>()),
iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || bucket.layout->get<style::TextOptional>()),
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 cd21a027a2..f30606ee42 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<style::SymbolLayoutProperties::PossiblyEvaluated>();
- bool sdfIcons = false;
bool iconsNeedLinear = false;
bool sortFeaturesByY = false;
std::string bucketLeaderID = "test";
std::vector<SymbolInstance> 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 a1385dfa8a..11d6fc7de3 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<style::SymbolLayoutProperties::PossiblyEvaluated> layout =
makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>();
- bool sdfIcons = false;
bool iconsNeedLinear = false;
bool sortFeaturesByY = false;
std::string bucketLeaderID = "test";
@@ -39,7 +38,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) {
std::vector<SymbolInstance> 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<SymbolInstance> 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<SymbolInstance> 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<style::SymbolLayoutProperties::PossiblyEvaluated> layout =
makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>();
- 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<SymbolInstance> 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<SymbolInstance> 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<style::SymbolLayoutProperties::PossiblyEvaluated> layout =
makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>();
- bool sdfIcons = false;
bool iconsNeedLinear = false;
bool sortFeaturesByY = false;
std::string bucketLeaderID = "test";
@@ -155,7 +152,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) {
std::vector<SymbolInstance> 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<style::SymbolLayoutProperties::PossiblyEvaluated> layout =
makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>();
- bool sdfIcons = false;
bool iconsNeedLinear = false;
bool sortFeaturesByY = false;
std::string bucketLeaderID = "test";
@@ -194,14 +190,14 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) {
std::vector<SymbolInstance> 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<SymbolInstance> 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