From 8be135231d9efe41a3b12037518d02b36104e8cf Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Mon, 11 Mar 2019 10:26:19 +0200 Subject: [core] Add possibility of overriding paint properties inside format expression #14062 * [core] Add format override expression and formatted section to evaluation context * [core] Add textColor to TaggedString's formatted section * [core] Add FormatSectionOverrides and introduce overridable properties * [core] Populate symbol layer paint properties for text sections * [core] Add benchmark for style that uses text-color override * [core] Add unit test for FormatOverrideExpression * [core] Add unit test for FormatSectionOverrides --- src/mbgl/renderer/buckets/symbol_bucket.cpp | 29 +++++++++++++++++-- src/mbgl/renderer/buckets/symbol_bucket.hpp | 20 +++++-------- src/mbgl/renderer/layers/render_symbol_layer.cpp | 2 +- src/mbgl/renderer/paint_property_binder.hpp | 36 +++++++++++++++--------- 4 files changed, 56 insertions(+), 31 deletions(-) (limited to 'src/mbgl/renderer') diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index 3a3688a60b..9220235f1d 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -28,13 +28,17 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo iconSizeBinder(SymbolSizeBinder::create(zoom, iconSize, IconSize::defaultValue())) { for (const auto& pair : paintProperties_) { + auto layerPaintProperties = pair.second; + if (hasFormatSectionOverrides()) { + setPaintPropertyOverrides(layerPaintProperties); + } paintProperties.emplace( std::piecewise_construct, std::forward_as_tuple(pair.first), std::forward_as_tuple(PaintProperties { - pair.second, - { RenderSymbolLayer::iconPaintProperties(pair.second), zoom }, - { RenderSymbolLayer::textPaintProperties(pair.second), zoom } + layerPaintProperties, + { RenderSymbolLayer::iconPaintProperties(layerPaintProperties), zoom }, + { RenderSymbolLayer::textPaintProperties(layerPaintProperties), zoom } })); } } @@ -226,4 +230,23 @@ void SymbolBucket::sortFeatures(const float angle) { } } +void SymbolBucket::updatePaintProperties(const std::string& layerID, + style::SymbolPaintProperties::PossiblyEvaluated updated) { + if (hasFormatSectionOverrides()) { + SymbolLayerPaintPropertyOverrides::updateOverrides(paintProperties.at(layerID).evaluated, updated); + } + paintProperties.at(layerID).evaluated = updated; +} + +void SymbolBucket::setPaintPropertyOverrides(style::SymbolPaintProperties::PossiblyEvaluated& paint) { + SymbolLayerPaintPropertyOverrides::setOverrides(layout, paint); +} + +bool SymbolBucket::hasFormatSectionOverrides() { + if (!hasFormatSectionOverrides_) { + hasFormatSectionOverrides_= SymbolLayerPaintPropertyOverrides::hasOverrides(layout.get()); + } + return *hasFormatSectionOverrides_; +} + } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index 709e48dd2e..9764d870da 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -58,6 +58,10 @@ public: bool hasIconData() const; bool hasCollisionBoxData() const; bool hasCollisionCircleData() const; + bool hasFormatSectionOverrides(); + void updatePaintProperties(const std::string& layerID, + style::SymbolPaintProperties::PossiblyEvaluated); + void setPaintPropertyOverrides(style::SymbolPaintProperties::PossiblyEvaluated&); void updateOpacity(); void sortFeatures(const float angle); @@ -87,7 +91,7 @@ public: std::unique_ptr textSizeBinder; - struct TextBuffer { + struct Buffer { gfx::VertexVector vertices; gfx::VertexVector> dynamicVertices; gfx::VertexVector> opacityVertices; @@ -103,19 +107,8 @@ public: std::unique_ptr iconSizeBinder; - struct IconBuffer { - gfx::VertexVector vertices; - gfx::VertexVector> dynamicVertices; - gfx::VertexVector> opacityVertices; - gfx::IndexVector triangles; - SegmentVector segments; - std::vector placedSymbols; + struct IconBuffer : public Buffer { PremultipliedImage atlasImage; - - optional> vertexBuffer; - optional>> dynamicVertexBuffer; - optional>> opacityVertexBuffer; - optional indexBuffer; } icon; struct CollisionBuffer { @@ -139,6 +132,7 @@ public: uint32_t bucketInstanceId = 0; bool justReloaded = false; + optional hasFormatSectionOverrides_; std::shared_ptr> featureSortOrder; }; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index e523a869b2..43e3068ff0 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -411,7 +411,7 @@ void RenderSymbolLayer::sortRenderTiles(const TransformState& state) { void RenderSymbolLayer::updateBucketPaintProperties(Bucket* bucket) const { assert(bucket->supportsLayer(*baseImpl)); - static_cast(bucket)->paintProperties.at(getID()).evaluated = evaluated; + static_cast(bucket)->updatePaintProperties(getID(), evaluated); } } // namespace mbgl diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index 34600508af..dc5ab6ae22 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -95,7 +95,10 @@ public: virtual ~PaintPropertyBinder() = default; - virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional&) = 0; + virtual void populateVertexVector(const GeometryTileFeature& feature, + std::size_t length, const ImagePositions&, + const optional&, + const style::expression::Value&) = 0; virtual void upload(gfx::Context& context) = 0; virtual void setPatternParameters(const optional&, const optional&, CrossfadeParameters&) = 0; virtual std::tuple>...> attributeBinding(const PossiblyEvaluatedType& currentValue) const = 0; @@ -114,7 +117,7 @@ public: : constant(std::move(constant_)) { } - void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional&) override {} + void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional&, const style::expression::Value&) override {} void upload(gfx::Context&) override {} void setPatternParameters(const optional&, const optional&, CrossfadeParameters&) override {}; @@ -135,13 +138,13 @@ private: }; template -class ConstantCrossFadedPaintPropertyBinder : public PaintPropertyBinder,PossiblyEvaluatedPropertyValue>, As...> { +class ConstantCrossFadedPaintPropertyBinder final : public PaintPropertyBinder,PossiblyEvaluatedPropertyValue>, As...> { public: ConstantCrossFadedPaintPropertyBinder(Faded constant_) : constant(std::move(constant_)), constantPatternPositions({}) { } - void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional&) override {} + void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional&, const style::expression::Value&) override {} void upload(gfx::Context&) override {} void setPatternParameters(const optional& posA, const optional& posB, CrossfadeParameters&) override { @@ -171,7 +174,7 @@ private: }; template -class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder, A> { +class SourceFunctionPaintPropertyBinder final : public PaintPropertyBinder, A> { public: using BaseAttributeType = A; using BaseVertex = gfx::Vertex; @@ -183,8 +186,9 @@ public: defaultValue(std::move(defaultValue_)) { } void setPatternParameters(const optional&, const optional&, CrossfadeParameters&) override {}; - void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional&) override { - auto evaluated = expression.evaluate(feature, defaultValue); + void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional&, const style::expression::Value& formattedSection) override { + using style::expression::EvaluationContext; + auto evaluated = expression.evaluate(EvaluationContext(&feature).withFormattedSection(&formattedSection), defaultValue); this->statistics.add(evaluated); auto value = attributeValue(evaluated); for (std::size_t i = vertexVector.elements(); i < length; ++i) { @@ -227,7 +231,7 @@ private: }; template -class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder, A> { +class CompositeFunctionPaintPropertyBinder final : public PaintPropertyBinder, A> { public: using AttributeType = ZoomInterpolatedAttributeType; @@ -240,8 +244,12 @@ public: zoomRange({zoom, zoom + 1}) { } void setPatternParameters(const optional&, const optional&, CrossfadeParameters&) override {}; - void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional&) override { - Range range = expression.evaluate(zoomRange, feature, defaultValue); + void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional&, const style::expression::Value& formattedSection) override { + using style::expression::EvaluationContext; + Range range = { + expression.evaluate(EvaluationContext(zoomRange.min, &feature).withFormattedSection(&formattedSection), defaultValue), + expression.evaluate(EvaluationContext(zoomRange.max, &feature).withFormattedSection(&formattedSection), defaultValue), + }; this->statistics.add(range.min); this->statistics.add(range.max); AttributeValue value = zoomInterpolatedAttributeValue( @@ -292,7 +300,7 @@ private: }; template -class CompositeCrossFadedPaintPropertyBinder : public PaintPropertyBinder, PossiblyEvaluatedPropertyValue>, A1, A2> { +class CompositeCrossFadedPaintPropertyBinder final : public PaintPropertyBinder, PossiblyEvaluatedPropertyValue>, A1, A2> { public: using AttributeType = ZoomInterpolatedAttributeType; using AttributeType2 = ZoomInterpolatedAttributeType; @@ -313,7 +321,7 @@ public: crossfade = crossfade_; }; - void populateVertexVector(const GeometryTileFeature&, std::size_t length, const ImagePositions& patternPositions, const optional& patternDependencies) override { + void populateVertexVector(const GeometryTileFeature&, std::size_t length, const ImagePositions& patternPositions, const optional& patternDependencies, const style::expression::Value&) override { if (patternDependencies->mid.empty()) { // Unlike other propperties with expressions that evaluate to null, the default value for `*-pattern` properties is an empty @@ -474,9 +482,9 @@ public: PaintPropertyBinders(PaintPropertyBinders&&) = default; PaintPropertyBinders(const PaintPropertyBinders&) = delete; - void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length, const ImagePositions& patternPositions, const optional& patternDependencies) { + void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length, const ImagePositions& patternPositions, const optional& patternDependencies, const style::expression::Value& formattedSection = {}) { util::ignore({ - (binders.template get()->populateVertexVector(feature, length, patternPositions, patternDependencies), 0)... + (binders.template get()->populateVertexVector(feature, length, patternPositions, patternDependencies, formattedSection), 0)... }); } -- cgit v1.2.1