diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 332fb3f46a1..4acd0a1ccdc 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -90,10 +90,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, } for (const auto& layer : layers) { - layerPaintProperties.emplace(layer->getID(), std::make_pair( - toRenderSymbolLayer(layer)->iconPaintProperties(), - toRenderSymbolLayer(layer)->textPaintProperties() - )); + layerPaintProperties.emplace(layer->getID(), toRenderSymbolLayer(layer)->evaluated); } // Determine glyph dependencies diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 7045eebc222..ab6dc049a2a 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -44,8 +44,7 @@ class SymbolLayout : public Layout { bool hasSymbolInstances() const override; bool hasDependencies() const override; - std::map> layerPaintProperties; + std::map layerPaintProperties; const std::string bucketLeaderID; std::vector symbolInstances; diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index 93870b287b6..4947b6b5217 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -9,9 +9,7 @@ namespace mbgl { using namespace style; SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layout_, - const std::map>& layerPaintProperties, + std::map paintProperties_, const style::PropertyValue& textSize, const style::PropertyValue& iconSize, float zoom, @@ -26,17 +24,18 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo sortFeaturesByY(sortFeaturesByY_), bucketLeaderID(std::move(bucketName_)), symbolInstances(std::move(symbolInstances_)), + paintProperties(std::move(paintProperties_)), textSizeBinder(SymbolSizeBinder::create(zoom, textSize, TextSize::defaultValue())), iconSizeBinder(SymbolSizeBinder::create(zoom, iconSize, IconSize::defaultValue())) { - for (const auto& pair : layerPaintProperties) { + for (const auto& pair : paintProperties) { paintPropertyBinders.emplace( std::piecewise_construct, std::forward_as_tuple(pair.first), std::forward_as_tuple( std::piecewise_construct, - std::forward_as_tuple(pair.second.first, zoom), - std::forward_as_tuple(pair.second.second, zoom))); + std::forward_as_tuple(RenderSymbolLayer::iconPaintProperties(pair.second), zoom), + std::forward_as_tuple(RenderSymbolLayer::textPaintProperties(pair.second), zoom))); } } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index ccb2cce5138..76fab2fa0f9 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -40,7 +40,7 @@ class PlacedSymbol { class SymbolBucket final : public Bucket { public: SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated, - const std::map>&, + std::map, const style::PropertyValue& textSize, const style::PropertyValue& iconSize, float zoom, @@ -78,6 +78,8 @@ class SymbolBucket final : public Bucket { std::vector symbolInstances; + std::map paintProperties; + std::map> paintPropertyBinders; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 11ffd74b10e..67051fc6e01 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -101,6 +101,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { continue; } SymbolBucket& bucket = *bucket_; + const auto& evaluated_ = (tile.tile.isComplete()) ? evaluated : bucket.paintProperties.at(getID()); const auto& layout = bucket.layout; @@ -152,8 +153,8 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { GeometryTile& geometryTile = static_cast(tile.tile); if (bucket.hasIconData()) { - auto values = iconPropertyValues(layout); - auto paintPropertyValues = iconPaintProperties(); + auto values = iconPropertyValues(evaluated_, layout); + const auto& paintPropertyValues = iconPaintProperties(evaluated_); const bool alongLine = layout.get() != SymbolPlacementType::Point && layout.get() == AlignmentType::Map; @@ -213,8 +214,8 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (bucket.hasTextData()) { parameters.context.bindTexture(*geometryTile.glyphAtlasTexture, 0, gl::TextureFilter::Linear); - auto values = textPropertyValues(layout); - auto paintPropertyValues = textPaintProperties(); + auto values = textPropertyValues(evaluated_, layout); + const auto& paintPropertyValues = textPaintProperties(bucket.paintProperties.at(getID())); const bool alongLine = layout.get() != SymbolPlacementType::Point && layout.get() == AlignmentType::Map; @@ -328,54 +329,59 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { } } -style::IconPaintProperties::PossiblyEvaluated RenderSymbolLayer::iconPaintProperties() const { +// static +style::IconPaintProperties::PossiblyEvaluated RenderSymbolLayer::iconPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated& evaluated_) { return style::IconPaintProperties::PossiblyEvaluated { - evaluated.get(), - evaluated.get(), - evaluated.get(), - evaluated.get(), - evaluated.get(), - evaluated.get(), - evaluated.get() + evaluated_.get(), + evaluated_.get(), + evaluated_.get(), + evaluated_.get(), + evaluated_.get(), + evaluated_.get(), + evaluated_.get() }; } -style::TextPaintProperties::PossiblyEvaluated RenderSymbolLayer::textPaintProperties() const { +// static +style::TextPaintProperties::PossiblyEvaluated RenderSymbolLayer::textPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated& evaluated_) { return style::TextPaintProperties::PossiblyEvaluated { - evaluated.get(), - evaluated.get(), - evaluated.get(), - evaluated.get(), - evaluated.get(), - evaluated.get(), - evaluated.get() + evaluated_.get(), + evaluated_.get(), + evaluated_.get(), + evaluated_.get(), + evaluated_.get(), + evaluated_.get(), + evaluated_.get() }; } - -style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) const { +// static +style::SymbolPropertyValues RenderSymbolLayer::iconPropertyValues(const style::SymbolPaintProperties::PossiblyEvaluated& evaluated_, + const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) { return style::SymbolPropertyValues { layout_.get(), layout_.get(), layout_.get(), - evaluated.get(), - evaluated.get(), - evaluated.get().constantOr(Color::black()).a > 0 && - evaluated.get().constantOr(1), - evaluated.get().constantOr(Color::black()).a > 0 + evaluated_.get(), + evaluated_.get(), + evaluated_.get().constantOr(Color::black()).a > 0 && + evaluated_.get().constantOr(1), + evaluated_.get().constantOr(Color::black()).a > 0 }; } -style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) const { +// static +style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::SymbolPaintProperties::PossiblyEvaluated& evaluated_, + const style::SymbolLayoutProperties::PossiblyEvaluated& layout_) { return style::SymbolPropertyValues { layout_.get(), layout_.get(), layout_.get(), - evaluated.get(), - evaluated.get(), - evaluated.get().constantOr(Color::black()).a > 0 && - evaluated.get().constantOr(1), - evaluated.get().constantOr(Color::black()).a > 0 + evaluated_.get(), + evaluated_.get(), + evaluated_.get().constantOr(Color::black()).a > 0 && + evaluated_.get().constantOr(1), + evaluated_.get().constantOr(Color::black()).a > 0 }; } @@ -398,4 +404,8 @@ void RenderSymbolLayer::sortRenderTiles(const TransformState& state) { }); } +void RenderSymbolLayer::updateBucketPaintProperties(Bucket* bucket) const { + static_cast(bucket)->paintProperties[getID()] = evaluated; +} + } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index 832fb940012..6b43f91a22f 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -68,11 +68,8 @@ class RenderSymbolLayer: public RenderLayer, public RenderLayerSymbolInterface { bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; - style::IconPaintProperties::PossiblyEvaluated iconPaintProperties() const; - style::TextPaintProperties::PossiblyEvaluated textPaintProperties() const; - - style::SymbolPropertyValues iconPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated&) const; - style::SymbolPropertyValues textPropertyValues(const style::SymbolLayoutProperties::PossiblyEvaluated&) const; + static style::IconPaintProperties::PossiblyEvaluated iconPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&); + static style::TextPaintProperties::PossiblyEvaluated textPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&); std::unique_ptr createBucket(const BucketParameters&, const std::vector&) const override; std::unique_ptr createLayout(const BucketParameters&, @@ -97,8 +94,13 @@ class RenderSymbolLayer: public RenderLayer, public RenderLayerSymbolInterface { const style::SymbolLayer::Impl& impl() const; protected: + static style::SymbolPropertyValues iconPropertyValues(const style::SymbolPaintProperties::PossiblyEvaluated&, + const style::SymbolLayoutProperties::PossiblyEvaluated&); + static style::SymbolPropertyValues textPropertyValues(const style::SymbolPaintProperties::PossiblyEvaluated&, + const style::SymbolLayoutProperties::PossiblyEvaluated&); RenderTiles filterRenderTiles(RenderTiles) const final; void sortRenderTiles(const TransformState&) final; + void updateBucketPaintProperties(Bucket*) const final; }; inline const RenderSymbolLayer* toRenderSymbolLayer(const RenderLayer* layer) { diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index 033df02282e..c2c57deb22b 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -71,10 +71,13 @@ RenderLayer::RenderTiles RenderLayer::filterRenderTiles(RenderTiles tiles, Filte continue; } - if (tile.tile.getBucket(*baseImpl)) { + if (Bucket* bucket = tile.tile.getBucket(*baseImpl)) { tile.used = true; tile.needsClipping |= needsClipping_; filtered.emplace_back(tile); + if (tile.tile.isComplete()) { + updateBucketPaintProperties(bucket); + } } } return filtered; @@ -84,6 +87,10 @@ void RenderLayer::markContextDestroyed() { // no-op } +void RenderLayer::updateBucketPaintProperties(Bucket*) const { + // no-op +} + void RenderLayer::checkRenderability(const PaintParameters& parameters, const uint32_t activeBindingCount) { // Only warn once for every layer. diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 485e5551c6f..76b9f6c38de 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -96,6 +96,9 @@ class RenderLayer { // Code specific to RenderTiles sorting / filtering virtual RenderTiles filterRenderTiles(RenderTiles) const; virtual void sortRenderTiles(const TransformState&); + // For some layers, we want Bucket to keep up-to-date paint properties data, so that this bucket can + // be reused while the new bucket is on the way. + virtual void updateBucketPaintProperties(Bucket*) const; using FilterFunctionPtr = bool (*)(RenderTile&); RenderTiles filterRenderTiles(RenderTiles, FilterFunctionPtr) const;