diff --git a/include/mbgl/gfx/vertex_attribute.hpp b/include/mbgl/gfx/vertex_attribute.hpp index 741e1ee48..dae588c77 100644 --- a/include/mbgl/gfx/vertex_attribute.hpp +++ b/include/mbgl/gfx/vertex_attribute.hpp @@ -359,9 +359,25 @@ public: VertexAttributeArray& operator=(VertexAttributeArray&&); VertexAttributeArray& operator=(const VertexAttributeArray&) = delete; - /// Clone the collection - - /// Copy another collection into this one + /// Specialized DataDrivenPaintProperty reader + /// @param binders Property binders for the target shader + /// @param evaluated Evaluated properties + /// @param propertiesAsUniforms [out] A set of string identities for the properties which will be constant, not + /// attributes. + /// @details The property name IDs refer to the "a\_" prefixed values to match the shader definitions. + template + void readDataDrivenPaintProperties(const Binders& binders, + const Evaluated& evaluated, + mbgl::unordered_set* propertiesAsUniforms) { + // Read each property in the type pack + if (propertiesAsUniforms) { + propertiesAsUniforms->reserve(sizeof...(DataDrivenPaintProperty)); + } + (readDataDrivenPaintProperty(binders.template get(), + isConstant(evaluated), + propertiesAsUniforms), + ...); + } /// Specialized DataDrivenPaintProperty reader /// @param binders Property binders for the target shader @@ -377,7 +393,7 @@ public: propertiesAsUniforms.reserve(sizeof...(DataDrivenPaintProperty)); (readDataDrivenPaintProperty(binders.template get(), isConstant(evaluated), - propertiesAsUniforms), + &propertiesAsUniforms), ...); } @@ -391,7 +407,7 @@ protected: template void readDataDrivenPaintProperty(const Binder& binder, const bool isConstant, - mbgl::unordered_set& propertiesAsUniforms) { + mbgl::unordered_set* propertiesAsUniforms) { if (!binder) { return; } @@ -410,8 +426,8 @@ protected: const auto& attr = getOrAdd( *attributeNameID, /*index=*/-1, /*type=*/gfx::AttributeDataType::Invalid, /*count=*/0); applyPaintProperty(attrIndex, attr, binder); - } else { - propertiesAsUniforms.emplace(*attributeNameID); + } else if (propertiesAsUniforms) { + propertiesAsUniforms->emplace(*attributeNameID); } } } diff --git a/src/mbgl/gfx/symbol_drawable_data.hpp b/src/mbgl/gfx/symbol_drawable_data.hpp index 6febd039c..223106432 100644 --- a/src/mbgl/gfx/symbol_drawable_data.hpp +++ b/src/mbgl/gfx/symbol_drawable_data.hpp @@ -22,16 +22,14 @@ struct SymbolDrawableData : public DrawableData { const style::AlignmentType pitchAlignment_, const style::AlignmentType rotationAlignment_, const style::SymbolPlacementType placement_, - const style::IconTextFitType textFit_, - PropertyMapType&& propertiesAsUniforms_) + const style::IconTextFitType textFit_) : isHalo(isHalo_), bucketVariablePlacement(bucketVariablePlacement_), symbolType(symbolType_), pitchAlignment(pitchAlignment_), rotationAlignment(rotationAlignment_), placement(placement_), - textFit(textFit_), - propertiesAsUniforms(std::move(propertiesAsUniforms_)) {} + textFit(textFit_) {} ~SymbolDrawableData() override = default; const bool isHalo; @@ -41,7 +39,6 @@ struct SymbolDrawableData : public DrawableData { const style::AlignmentType rotationAlignment; const style::SymbolPlacementType placement; const style::IconTextFitType textFit; - const PropertyMapType propertiesAsUniforms; }; using UniqueSymbolDrawableData = std::unique_ptr; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 038121610..063bcdfd2 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -748,13 +748,6 @@ SymbolDrawableTilePropsUBO buildTileUBO(const SymbolBucket& bucket, }; } -// Convert a properties-as-uniforms set to the type expected by `SymbolDrawableData` -gfx::SymbolDrawableData::PropertyMapType toMap(const mbgl::unordered_set& set) { - // can we do this without allocating? - auto values = std::vector(set.size()); - return gfx::SymbolDrawableData::PropertyMapType(set.begin(), set.end(), values.begin(), values.end()); -} - const auto idDataAttibName = stringIndexer().get("a_data"); const auto posOffsetAttribName = "a_pos_offset"; const auto idPosOffsetAttribName = stringIndexer().get(posOffsetAttribName); @@ -769,7 +762,7 @@ void updateTileAttributes(const SymbolBucket::Buffer& buffer, const SymbolBucket::PaintProperties& paintProps, const SymbolPaintProperties::PossiblyEvaluated& evaluated, gfx::VertexAttributeArray& attribs, - mbgl::unordered_set& propertiesAsUniforms) { + mbgl::unordered_set* propertiesAsUniforms) { if (const auto& attr = attribs.getOrAdd(idPosOffsetAttribName)) { attr->setSharedRawData(buffer.sharedVertices, offsetof(SymbolLayoutVertex, a1), @@ -825,8 +818,7 @@ void updateTileDrawable(gfx::Drawable& drawable, const SymbolPaintProperties::PossiblyEvaluated& evaluated, const TransformState& state, gfx::UniformBufferPtr& textInterpUBO, - gfx::UniformBufferPtr& iconInterpUBO, - mbgl::unordered_set& propertiesAsUniforms) { + gfx::UniformBufferPtr& iconInterpUBO) { if (!drawable.getData()) { return; } @@ -868,7 +860,7 @@ void updateTileDrawable(gfx::Drawable& drawable, // See `Placement::updateBucketDynamicVertices` if (auto& attribs = drawable.getVertexAttributes()) { - updateTileAttributes(buffer, isText, paintProps, evaluated, *attribs, propertiesAsUniforms); + updateTileAttributes(buffer, isText, paintProps, evaluated, *attribs, nullptr); } } @@ -1159,20 +1151,8 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, propertiesAsUniforms.clear(); const auto& evaluated = getEvaluated(renderData.layerProperties); - updateTileDrawable(drawable, - context, - bucket, - bucketPaintProperties, - evaluated, - state, - textInterpUBO, - iconInterpUBO, - propertiesAsUniforms); - - // We assume that the properties-as-uniforms doesn't change without the style changing. - // That would require updating the shader as well. - [[maybe_unused]] const auto& drawData = static_cast(*drawable.getData()); - assert(drawData.propertiesAsUniforms == toMap(propertiesAsUniforms)); + updateTileDrawable( + drawable, context, bucket, bucketPaintProperties, evaluated, state, textInterpUBO, iconInterpUBO); return true; }; if (updateTile(passes, tileID, std::move(updateExisting))) { @@ -1259,7 +1239,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, propertiesAsUniforms.clear(); auto attribs = context.createVertexAttributeArray(); - updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, *attribs, propertiesAsUniforms); + updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, *attribs, &propertiesAsUniforms); const auto textHalo = evaluated.get().constantOr(Color::black()).a > 0.0f && evaluated.get().constantOr(1); @@ -1355,8 +1335,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, /*.pitchAlignment=*/values.pitchAlignment, /*.rotationAlignment=*/values.rotationAlignment, /*.placement=*/layout.get(), - /*.textFit=*/layout.get(), - /*propertiesAsUniforms=*/toMap(propertiesAsUniforms)); + /*.textFit=*/layout.get()); const auto tileUBO = buildTileUBO(bucket, *drawData, currentZoom); drawable->setData(std::move(drawData));