From e23aca5e9b75e84f52f2578bb6ca5b0dbdf0f39a Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Mon, 9 Oct 2023 14:17:20 -0700 Subject: [PATCH] Refactor `readDataDrivenPaintProperties` into smaller methods (#1742) --- include/mbgl/gfx/vertex_attribute.hpp | 130 +++++++++++++++----------- 1 file changed, 77 insertions(+), 53 deletions(-) diff --git a/include/mbgl/gfx/vertex_attribute.hpp b/include/mbgl/gfx/vertex_attribute.hpp index db3b1401f..5c676844a 100644 --- a/include/mbgl/gfx/vertex_attribute.hpp +++ b/include/mbgl/gfx/vertex_attribute.hpp @@ -365,59 +365,6 @@ public: return newAttrs; } - /// 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, - std::unordered_set& propertiesAsUniforms) { - propertiesAsUniforms.reserve(sizeof...(DataDrivenPaintProperty)); - ( - [&](const auto& attributeNames) { - for (std::size_t attrIndex = 0; attrIndex < attributeNames.size(); ++attrIndex) { - const auto& attributeName = attributeNames[attrIndex]; - if (auto& binder = binders.template get()) { - using Attribute = typename DataDrivenPaintProperty::Attribute; - using Type = typename Attribute::Type; // ::mbgl::gfx::AttributeType - using InterpType = ZoomInterpolatedAttributeType; - - auto& attributeNameID = DataDrivenPaintProperty::AttributeNameIDs[attrIndex]; - if (!attributeNameID) { - attributeNameID = stringIndexer().get(attributePrefix + attributeName.data()); - } - - const auto vertexCount = binder->getVertexCount(); - const auto isConstant = evaluated.template get().isConstant(); - if (vertexCount > 0 && !isConstant) { - if (auto& attr = getOrAdd(*attributeNameID)) { - if (const auto& sharedVector = binder->getSharedVertexVector()) { - const auto rawSize = static_cast(sharedVector->getRawSize()); - const bool isInterpolated = binder->isInterpolated(); - const auto dataType = isInterpolated ? InterpType::DataType : Type::DataType; - assert(rawSize == static_cast(isInterpolated - ? sizeof(typename InterpType::Value) - : sizeof(typename Type::Value))); - assert(sharedVector->getRawCount() == vertexCount); - attr->setSharedRawData(std::move(sharedVector), 0, 0, rawSize, dataType); - } else { - for (std::size_t i = 0; i < vertexCount; ++i) { - attr->set(i, binder->getVertexValue(i), attrIndex); - } - } - } - } else { - propertiesAsUniforms.emplace(*attributeNameID); - } - } - } - }(DataDrivenPaintProperty::AttributeNames), - ...); - } - /// Copy another collection into this one virtual void copy(const VertexAttributeArray& other) { for (const auto& kv : other.attrs) { @@ -427,7 +374,84 @@ public: } } + /// 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, + std::unordered_set& propertiesAsUniforms) { + // Read each property in the type pack + propertiesAsUniforms.reserve(sizeof...(DataDrivenPaintProperty)); + (readDataDrivenPaintProperty(binders.template get(), + isConstant(evaluated), + propertiesAsUniforms), + ...); + } + protected: + template + static bool isConstant(const Evaluated& evaluated) { + return evaluated.template get().isConstant(); + } + + /// Place one property from a type pack into an attribute in this collection, replacing if it already exists. + template + void readDataDrivenPaintProperty(const Binder& binder, + const bool isConstant, + std::unordered_set& propertiesAsUniforms) { + if (!binder) { + return; + } + + // Consider each attribute name in the attribute (e.g., pattern_from, pattern_to) + for (std::size_t attrIndex = 0; attrIndex < DataDrivenPaintProperty::AttributeNames.size(); ++attrIndex) { + auto& attributeNameID = DataDrivenPaintProperty::AttributeNameIDs[attrIndex]; + if (!attributeNameID) { + const auto& attributeName = DataDrivenPaintProperty::AttributeNames[attrIndex]; + attributeNameID = stringIndexer().get(attributePrefix + attributeName.data()); + } + + // Apply the property, or add it to the uniforms collection if it's constant. + if (!isConstant && binder->getVertexCount() > 0) { + using Attribute = typename DataDrivenPaintProperty::Attribute; + applyPaintProperty(attrIndex, getOrAdd(*attributeNameID), binder); + } else { + propertiesAsUniforms.emplace(*attributeNameID); + } + } + } + + /// Copy or share the attribute data from a paint property + template + static void applyPaintProperty(const std::size_t attrIndex, const UniqueVertexAttribute& attrib, TBinder& binder) { + using Type = typename TAttribute::Type; // ::mbgl::gfx::AttributeType + using InterpType = ZoomInterpolatedAttributeType; + + if (!attrib) { + assert(!"Failed to add attribute"); + return; + } + + if (const auto& sharedVector = binder->getSharedVertexVector()) { + const auto rawSize = static_cast(sharedVector->getRawSize()); + const bool isInterpolated = binder->isInterpolated(); + const auto dataType = isInterpolated ? InterpType::DataType : Type::DataType; + assert(rawSize == static_cast(isInterpolated ? sizeof(typename InterpType::Value) + : sizeof(typename Type::Value))); + assert(sharedVector->getRawCount() == binder->getVertexCount()); + attrib->setSharedRawData(std::move(sharedVector), 0, 0, rawSize, dataType); + } else { + const auto vertexCount = binder->getVertexCount(); + for (std::size_t i = 0; i < vertexCount; ++i) { + attrib->set(i, binder->getVertexValue(i), attrIndex); + } + } + } + const UniqueVertexAttribute& add(const StringIdentity id, std::unique_ptr&&); virtual UniqueVertexAttribute create(int index, AttributeDataType dataType, std::size_t count) const {