diff options
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.cpp | 45 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.hpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.cpp | 43 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.hpp | 6 |
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 { |