summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer')
-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
4 files changed, 63 insertions, 37 deletions
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 {