From 4b21560cf59877125ea0bdae1a2546ab06f1efb2 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Mon, 1 Apr 2019 11:29:28 +0300 Subject: [PATCH] [core] Use `style::LayerProperties` in render layers, buckets and layouts. --- .../layermanager/circle_layer_factory.hpp | 2 +- .../fill_extrusion_layer_factory.hpp | 2 +- .../mbgl/layermanager/fill_layer_factory.hpp | 2 +- .../layermanager/heatmap_layer_factory.hpp | 2 +- include/mbgl/layermanager/layer_factory.hpp | 7 +- include/mbgl/layermanager/layer_manager.hpp | 8 ++- .../mbgl/layermanager/line_layer_factory.hpp | 2 +- .../layermanager/symbol_layer_factory.hpp | 2 +- .../layermanager/circle_layer_factory.cpp | 2 +- .../fill_extrusion_layer_factory.cpp | 6 +- src/mbgl/layermanager/fill_layer_factory.cpp | 6 +- .../layermanager/heatmap_layer_factory.cpp | 2 +- src/mbgl/layermanager/layer_factory.cpp | 6 +- src/mbgl/layermanager/layer_manager.cpp | 5 +- src/mbgl/layermanager/line_layer_factory.cpp | 6 +- .../layermanager/symbol_layer_factory.cpp | 2 +- src/mbgl/layout/pattern_layout.hpp | 68 ++++++++++--------- src/mbgl/layout/symbol_layout.cpp | 18 ++--- src/mbgl/layout/symbol_layout.hpp | 3 +- src/mbgl/renderer/bucket.hpp | 3 - src/mbgl/renderer/buckets/circle_bucket.cpp | 20 +++--- src/mbgl/renderer/buckets/circle_bucket.hpp | 2 +- src/mbgl/renderer/buckets/fill_bucket.cpp | 5 +- src/mbgl/renderer/buckets/fill_bucket.hpp | 2 - .../buckets/fill_extrusion_bucket.cpp | 4 +- .../buckets/fill_extrusion_bucket.hpp | 2 - src/mbgl/renderer/buckets/heatmap_bucket.cpp | 6 +- src/mbgl/renderer/buckets/heatmap_bucket.hpp | 2 +- src/mbgl/renderer/buckets/line_bucket.cpp | 31 ++++----- src/mbgl/renderer/buckets/line_bucket.hpp | 7 +- src/mbgl/renderer/group_by_layout.cpp | 34 +++------- src/mbgl/renderer/group_by_layout.hpp | 6 +- .../layers/render_background_layer.cpp | 33 +++++---- .../layers/render_background_layer.hpp | 14 ++-- .../renderer/layers/render_circle_layer.cpp | 22 +++--- .../renderer/layers/render_circle_layer.hpp | 12 +--- .../renderer/layers/render_custom_layer.cpp | 16 +++-- .../renderer/layers/render_custom_layer.hpp | 16 ++--- .../layers/render_fill_extrusion_layer.cpp | 30 ++++---- .../layers/render_fill_extrusion_layer.hpp | 24 ++----- .../renderer/layers/render_fill_layer.cpp | 29 +++++--- .../renderer/layers/render_fill_layer.hpp | 20 ++---- .../renderer/layers/render_heatmap_layer.cpp | 24 ++++--- .../renderer/layers/render_heatmap_layer.hpp | 16 ++--- .../layers/render_hillshade_layer.cpp | 28 +++++--- .../layers/render_hillshade_layer.hpp | 8 +-- .../renderer/layers/render_line_layer.cpp | 29 +++++--- .../renderer/layers/render_line_layer.hpp | 22 ++---- .../renderer/layers/render_raster_layer.cpp | 24 ++++--- .../renderer/layers/render_raster_layer.hpp | 10 ++- .../renderer/layers/render_symbol_layer.cpp | 25 ++++--- .../renderer/layers/render_symbol_layer.hpp | 30 +++----- src/mbgl/renderer/render_layer.cpp | 5 +- src/mbgl/renderer/render_layer.hpp | 8 ++- src/mbgl/style/layers/custom_layer_impl.hpp | 7 ++ src/mbgl/tile/geometry_tile_worker.cpp | 49 +++++++------ src/mbgl/tile/geometry_tile_worker.hpp | 3 - test/renderer/group_by_layout.test.cpp | 60 ---------------- test/test-files.json | 1 - 59 files changed, 383 insertions(+), 457 deletions(-) delete mode 100644 test/renderer/group_by_layout.test.cpp diff --git a/include/mbgl/layermanager/circle_layer_factory.hpp b/include/mbgl/layermanager/circle_layer_factory.hpp index e9eb0f59ccf..51135d33835 100644 --- a/include/mbgl/layermanager/circle_layer_factory.hpp +++ b/include/mbgl/layermanager/circle_layer_factory.hpp @@ -8,7 +8,7 @@ class CircleLayerFactory : public LayerFactory { protected: const style::LayerTypeInfo* getTypeInfo() const noexcept final; std::unique_ptr createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final; - std::unique_ptr createBucket(const BucketParameters&, const std::vector&) noexcept final; + std::unique_ptr createBucket(const BucketParameters&, const std::vector>&) noexcept final; std::unique_ptr createRenderLayer(Immutable) noexcept final; }; diff --git a/include/mbgl/layermanager/fill_extrusion_layer_factory.hpp b/include/mbgl/layermanager/fill_extrusion_layer_factory.hpp index 3430d3da1c5..fbaa5c12544 100644 --- a/include/mbgl/layermanager/fill_extrusion_layer_factory.hpp +++ b/include/mbgl/layermanager/fill_extrusion_layer_factory.hpp @@ -8,7 +8,7 @@ class FillExtrusionLayerFactory : public LayerFactory { protected: const style::LayerTypeInfo* getTypeInfo() const noexcept final; std::unique_ptr createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final; - std::unique_ptr createLayout(const LayoutParameters&, std::unique_ptr, const std::vector&) noexcept final; + std::unique_ptr createLayout(const LayoutParameters&, std::unique_ptr, const std::vector>&) noexcept final; std::unique_ptr createRenderLayer(Immutable) noexcept final; }; diff --git a/include/mbgl/layermanager/fill_layer_factory.hpp b/include/mbgl/layermanager/fill_layer_factory.hpp index 22762d1290b..09afb0dc3a1 100644 --- a/include/mbgl/layermanager/fill_layer_factory.hpp +++ b/include/mbgl/layermanager/fill_layer_factory.hpp @@ -8,7 +8,7 @@ class FillLayerFactory : public LayerFactory { protected: const style::LayerTypeInfo* getTypeInfo() const noexcept final; std::unique_ptr createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final; - std::unique_ptr createLayout(const LayoutParameters&, std::unique_ptr, const std::vector&) noexcept final; + std::unique_ptr createLayout(const LayoutParameters&, std::unique_ptr, const std::vector>&) noexcept final; std::unique_ptr createRenderLayer(Immutable) noexcept final; }; diff --git a/include/mbgl/layermanager/heatmap_layer_factory.hpp b/include/mbgl/layermanager/heatmap_layer_factory.hpp index 306af609381..2d0e1a5a027 100644 --- a/include/mbgl/layermanager/heatmap_layer_factory.hpp +++ b/include/mbgl/layermanager/heatmap_layer_factory.hpp @@ -8,7 +8,7 @@ class HeatmapLayerFactory : public LayerFactory { protected: const style::LayerTypeInfo* getTypeInfo() const noexcept final; std::unique_ptr createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final; - std::unique_ptr createBucket(const BucketParameters&, const std::vector&) noexcept final; + std::unique_ptr createBucket(const BucketParameters&, const std::vector>&) noexcept final; std::unique_ptr createRenderLayer(Immutable) noexcept final; }; diff --git a/include/mbgl/layermanager/layer_factory.hpp b/include/mbgl/layermanager/layer_factory.hpp index 037de1b6472..f3cfef6bb64 100644 --- a/include/mbgl/layermanager/layer_factory.hpp +++ b/include/mbgl/layermanager/layer_factory.hpp @@ -6,6 +6,9 @@ namespace mbgl { +namespace style { +class LayerProperties; +} // namespace style class Bucket; class BucketParameters; class GeometryTileLayer; @@ -28,9 +31,9 @@ class LayerFactory { /// Returns a new RenderLayer instance. virtual std::unique_ptr createRenderLayer(Immutable) noexcept = 0; /// Returns a new Bucket instance on success call; returns `nullptr` otherwise. - virtual std::unique_ptr createBucket(const BucketParameters&, const std::vector&) noexcept; + virtual std::unique_ptr createBucket(const BucketParameters&, const std::vector>&) noexcept; /// Returns a new Layout instance on success call; returns `nullptr` otherwise. - virtual std::unique_ptr createLayout(const LayoutParameters&, std::unique_ptr, const std::vector&) noexcept; + virtual std::unique_ptr createLayout(const LayoutParameters&, std::unique_ptr, const std::vector>&) noexcept; protected: optional getSource(const style::conversion::Convertible& value) const noexcept; diff --git a/include/mbgl/layermanager/layer_manager.hpp b/include/mbgl/layermanager/layer_manager.hpp index de10b0207c1..c6802dbb495 100644 --- a/include/mbgl/layermanager/layer_manager.hpp +++ b/include/mbgl/layermanager/layer_manager.hpp @@ -5,6 +5,9 @@ #include namespace mbgl { +namespace style { +class LayerProperties; +} // namespace style class GeometryTileLayer; class LayerFactory; class RenderLayer; @@ -37,9 +40,10 @@ class LayerManager { /// Returns a new RenderLayer instance on success call; returns `nullptr` otherwise. std::unique_ptr createRenderLayer(Immutable) noexcept; /// Returns a new Bucket instance on success call; returns `nullptr` otherwise. - std::unique_ptr createBucket(const BucketParameters&, const std::vector&) noexcept; + std::unique_ptr createBucket(const BucketParameters&, const std::vector>&) noexcept; /// Returns a new Layout instance on success call; returns `nullptr` otherwise. - std::unique_ptr createLayout(const LayoutParameters&, std::unique_ptr, const std::vector&) noexcept; + std::unique_ptr createLayout(const LayoutParameters&, std::unique_ptr, + const std::vector>&) noexcept; /** * @brief a build-time flag to enable/disable annotations in mapbox-gl-native core. diff --git a/include/mbgl/layermanager/line_layer_factory.hpp b/include/mbgl/layermanager/line_layer_factory.hpp index a7081228eea..803f550e57b 100644 --- a/include/mbgl/layermanager/line_layer_factory.hpp +++ b/include/mbgl/layermanager/line_layer_factory.hpp @@ -10,7 +10,7 @@ class LineLayerFactory : public LayerFactory { std::unique_ptr createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final; std::unique_ptr createLayout(const LayoutParameters& parameters, std::unique_ptr tileLayer, - const std::vector& group) noexcept final; + const std::vector>& group) noexcept final; std::unique_ptr createRenderLayer(Immutable) noexcept final; }; diff --git a/include/mbgl/layermanager/symbol_layer_factory.hpp b/include/mbgl/layermanager/symbol_layer_factory.hpp index dac515c9dcd..38f382e96c5 100644 --- a/include/mbgl/layermanager/symbol_layer_factory.hpp +++ b/include/mbgl/layermanager/symbol_layer_factory.hpp @@ -10,7 +10,7 @@ class SymbolLayerFactory : public LayerFactory { std::unique_ptr createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final; std::unique_ptr createLayout(const LayoutParameters& parameters, std::unique_ptr tileLayer, - const std::vector& group) noexcept final; + const std::vector>& group) noexcept final; std::unique_ptr createRenderLayer(Immutable) noexcept final; }; diff --git a/src/mbgl/layermanager/circle_layer_factory.cpp b/src/mbgl/layermanager/circle_layer_factory.cpp index 0ea56e57117..28c64fc4001 100644 --- a/src/mbgl/layermanager/circle_layer_factory.cpp +++ b/src/mbgl/layermanager/circle_layer_factory.cpp @@ -24,7 +24,7 @@ std::unique_ptr CircleLayerFactory::createLayer(const std::string& return layer; } -std::unique_ptr CircleLayerFactory::createBucket(const BucketParameters& parameters, const std::vector& layers) noexcept { +std::unique_ptr CircleLayerFactory::createBucket(const BucketParameters& parameters, const std::vector>& layers) noexcept { return std::make_unique(parameters, layers); } diff --git a/src/mbgl/layermanager/fill_extrusion_layer_factory.cpp b/src/mbgl/layermanager/fill_extrusion_layer_factory.cpp index b2558825ef3..bc1647afa40 100644 --- a/src/mbgl/layermanager/fill_extrusion_layer_factory.cpp +++ b/src/mbgl/layermanager/fill_extrusion_layer_factory.cpp @@ -26,8 +26,10 @@ std::unique_ptr FillExtrusionLayerFactory::createLayer(const std:: std::unique_ptr FillExtrusionLayerFactory::createLayout(const LayoutParameters& parameters, std::unique_ptr layer, - const std::vector& group) noexcept { - return std::make_unique>(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies); + const std::vector>& group) noexcept { + using namespace style; + using LayoutType = PatternLayout; + return std::make_unique(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies); } std::unique_ptr FillExtrusionLayerFactory::createRenderLayer(Immutable impl) noexcept { diff --git a/src/mbgl/layermanager/fill_layer_factory.cpp b/src/mbgl/layermanager/fill_layer_factory.cpp index 60a1818585a..f9b59359c50 100644 --- a/src/mbgl/layermanager/fill_layer_factory.cpp +++ b/src/mbgl/layermanager/fill_layer_factory.cpp @@ -27,8 +27,10 @@ std::unique_ptr FillLayerFactory::createLayer(const std::string& i std::unique_ptr FillLayerFactory::createLayout(const LayoutParameters& parameters, std::unique_ptr layer, - const std::vector& group) noexcept { - return std::make_unique>(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies); + const std::vector>& group) noexcept { + using namespace style; + using LayoutType = PatternLayout; + return std::make_unique(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies); } std::unique_ptr FillLayerFactory::createRenderLayer(Immutable impl) noexcept { diff --git a/src/mbgl/layermanager/heatmap_layer_factory.cpp b/src/mbgl/layermanager/heatmap_layer_factory.cpp index 5d6a595b46a..1cd5d18f796 100644 --- a/src/mbgl/layermanager/heatmap_layer_factory.cpp +++ b/src/mbgl/layermanager/heatmap_layer_factory.cpp @@ -24,7 +24,7 @@ std::unique_ptr HeatmapLayerFactory::createLayer(const std::string return layer; } -std::unique_ptr HeatmapLayerFactory::createBucket(const BucketParameters& parameters, const std::vector& layers) noexcept { +std::unique_ptr HeatmapLayerFactory::createBucket(const BucketParameters& parameters, const std::vector>& layers) noexcept { return std::make_unique(parameters, layers); } diff --git a/src/mbgl/layermanager/layer_factory.cpp b/src/mbgl/layermanager/layer_factory.cpp index ceeb304f442..f4967b0e5de 100644 --- a/src/mbgl/layermanager/layer_factory.cpp +++ b/src/mbgl/layermanager/layer_factory.cpp @@ -25,12 +25,14 @@ optional LayerFactory::getSource(const style::conversion::Convertib return source; } -std::unique_ptr LayerFactory::createBucket(const BucketParameters&, const std::vector&) noexcept { +std::unique_ptr LayerFactory::createBucket(const BucketParameters&, const std::vector>&) noexcept { assert(false); return nullptr; } -std::unique_ptr LayerFactory::createLayout(const LayoutParameters&, std::unique_ptr, const std::vector&) noexcept { +std::unique_ptr LayerFactory::createLayout(const LayoutParameters&, + std::unique_ptr, + const std::vector>&) noexcept { assert(false); return nullptr; } diff --git a/src/mbgl/layermanager/layer_manager.cpp b/src/mbgl/layermanager/layer_manager.cpp index e6195caeba7..1e2074cd70a 100644 --- a/src/mbgl/layermanager/layer_manager.cpp +++ b/src/mbgl/layermanager/layer_manager.cpp @@ -25,7 +25,8 @@ std::unique_ptr LayerManager::createLayer( return nullptr; } -std::unique_ptr LayerManager::createBucket(const BucketParameters& parameters, const std::vector& layers) noexcept { +std::unique_ptr LayerManager::createBucket(const BucketParameters& parameters, + const std::vector>& layers) noexcept { assert(!layers.empty()); assert(parameters.layerType->layout == style::LayerTypeInfo::Layout::NotRequired); LayerFactory* factory = getFactory(parameters.layerType); @@ -35,7 +36,7 @@ std::unique_ptr LayerManager::createBucket(const BucketParameters& param std::unique_ptr LayerManager::createLayout(const LayoutParameters& parameters, std::unique_ptr tileLayer, - const std::vector& layers) noexcept { + const std::vector>& layers) noexcept { assert(!layers.empty()); assert(parameters.bucketParameters.layerType->layout == style::LayerTypeInfo::Layout::Required); LayerFactory* factory = getFactory(parameters.bucketParameters.layerType); diff --git a/src/mbgl/layermanager/line_layer_factory.cpp b/src/mbgl/layermanager/line_layer_factory.cpp index 8bf756e1597..212fb456656 100644 --- a/src/mbgl/layermanager/line_layer_factory.cpp +++ b/src/mbgl/layermanager/line_layer_factory.cpp @@ -26,8 +26,10 @@ std::unique_ptr LineLayerFactory::createLayer(const std::string& i std::unique_ptr LineLayerFactory::createLayout(const LayoutParameters& parameters, std::unique_ptr layer, - const std::vector& group) noexcept { - return std::make_unique>(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies); + const std::vector>& group) noexcept { + using namespace style; + using LayoutType = PatternLayout; + return std::make_unique(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies); } std::unique_ptr LineLayerFactory::createRenderLayer(Immutable impl) noexcept { diff --git a/src/mbgl/layermanager/symbol_layer_factory.cpp b/src/mbgl/layermanager/symbol_layer_factory.cpp index d992741551d..f5a4640db79 100644 --- a/src/mbgl/layermanager/symbol_layer_factory.cpp +++ b/src/mbgl/layermanager/symbol_layer_factory.cpp @@ -26,7 +26,7 @@ std::unique_ptr SymbolLayerFactory::createLayer(const std::string& std::unique_ptr SymbolLayerFactory::createLayout(const LayoutParameters& parameters, std::unique_ptr tileLayer, - const std::vector& group) noexcept { + const std::vector>& group) noexcept { return std::make_unique(parameters.bucketParameters, group, std::move(tileLayer), diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp index 8dabfab9190..fe2e9c59504 100644 --- a/src/mbgl/layout/pattern_layout.hpp +++ b/src/mbgl/layout/pattern_layout.hpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace mbgl { @@ -22,31 +23,32 @@ class PatternFeature { PatternLayerMap patterns; }; -template +template ::PossiblyEvaluated> class PatternLayout : public Layout { public: PatternLayout(const BucketParameters& parameters, - const std::vector& layers, + const std::vector>& group, std::unique_ptr sourceLayer_, ImageDependencies& patternDependencies) - : Layout(), - bucketLeaderID(layers.at(0)->getID()), - sourceLayer(std::move(sourceLayer_)), + : sourceLayer(std::move(sourceLayer_)), zoom(parameters.tileID.overscaledZ), overscaling(parameters.tileID.overscaleFactor()), hasPattern(false) { - - using PatternLayer = typename B::RenderLayerType; - const auto renderLayer = static_cast(layers.at(0)); - const typename PatternLayer::StyleLayerImpl& leader = renderLayer->impl(); - layout = leader.layout.evaluate(PropertyEvaluationParameters(zoom)); - sourceLayerID = leader.sourceLayer; - groupID = renderLayer->getID(); - - for (const auto& layer : layers) { - const typename B::PossiblyEvaluatedPaintProperties evaluatedProps = static_cast(layer)->evaluated; - const auto patternProperty = evaluatedProps.template get(); - const auto constantPattern = patternProperty.constantOr({ "", "" }); + assert(!group.empty()); + auto leaderLayerProperties = staticImmutableCast(group.front()); + layout = leaderLayerProperties->layerImpl().layout.evaluate(PropertyEvaluationParameters(zoom)); + sourceLayerID = leaderLayerProperties->layerImpl().sourceLayer; + bucketLeaderID = leaderLayerProperties->layerImpl().id; + + for (const auto& layerProperties : group) { + const std::string& layerId = layerProperties->baseImpl->id; + const auto evaluatedProps = static_cast(*layerProperties).evaluated; + const auto patternProperty = evaluatedProps.template get(); + const auto constantPattern = patternProperty.constantOr(Faded >{ "", ""}); // determine if layer group has any layers that use *-pattern property and add // constant pattern dependencies. if (!patternProperty.isConstant()) { @@ -56,33 +58,34 @@ class PatternLayout : public Layout { patternDependencies.emplace(constantPattern.to, ImageType::Pattern); patternDependencies.emplace(constantPattern.from, ImageType::Pattern); } - layerPaintProperties.emplace(layer->getID(), std::move(evaluatedProps)); + layerPaintProperties.emplace(layerId, std::move(evaluatedProps)); } const size_t featureCount = sourceLayer->featureCount(); for (size_t i = 0; i < featureCount; ++i) { auto feature = sourceLayer->getFeature(i); - if (!leader.filter(style::expression::EvaluationContext { this->zoom, feature.get() })) + if (!leaderLayerProperties->layerImpl().filter(style::expression::EvaluationContext { this->zoom, feature.get() })) continue; PatternLayerMap patternDependencyMap; if (hasPattern) { - for (const auto& layer : layers) { - const auto it = layerPaintProperties.find(layer->getID()); + for (const auto& layerProperties : group) { + const std::string& layerId = layerProperties->baseImpl->id; + const auto it = layerPaintProperties.find(layerId); if (it != layerPaintProperties.end()) { const auto paint = it->second; - const auto patternProperty = paint.template get(); + const auto patternProperty = paint.template get(); if (!patternProperty.isConstant()) { // For layers with non-data-constant pattern properties, evaluate their expression and add // the patterns to the dependency vector - const auto min = patternProperty.evaluate(*feature, zoom - 1, PatternLayer::PatternProperty::defaultValue()); - const auto mid = patternProperty.evaluate(*feature, zoom, PatternLayer::PatternProperty::defaultValue()); - const auto max = patternProperty.evaluate(*feature, zoom + 1, PatternLayer::PatternProperty::defaultValue()); + const auto min = patternProperty.evaluate(*feature, zoom - 1, PatternPropertyType::defaultValue()); + const auto mid = patternProperty.evaluate(*feature, zoom, PatternPropertyType::defaultValue()); + const auto max = patternProperty.evaluate(*feature, zoom + 1, PatternPropertyType::defaultValue()); patternDependencies.emplace(min.to, ImageType::Pattern); patternDependencies.emplace(mid.to, ImageType::Pattern); patternDependencies.emplace(max.to, ImageType::Pattern); - patternDependencyMap.emplace(layer->getID(), PatternDependency {min.to, mid.to, max.to}); + patternDependencyMap.emplace(layerId, PatternDependency {min.to, mid.to, max.to}); } } @@ -99,15 +102,15 @@ class PatternLayout : public Layout { } void createBucket(const ImagePositions& patternPositions, std::unique_ptr& featureIndex, std::unordered_map>& buckets, const bool, const bool) override { - auto bucket = std::make_shared(layout, layerPaintProperties, zoom, overscaling); + auto bucket = std::make_shared(layout, layerPaintProperties, zoom, overscaling); for (auto & patternFeature : features) { const auto i = patternFeature.i; std::unique_ptr feature = std::move(patternFeature.feature); - PatternLayerMap patterns = patternFeature.patterns; + const PatternLayerMap& patterns = patternFeature.patterns; GeometryCollection geometries = feature->getGeometries(); bucket->addFeature(*feature, geometries, patternPositions, patterns); - featureIndex->insert(geometries, i, sourceLayerID, groupID); + featureIndex->insert(geometries, i, sourceLayerID, bucketLeaderID); } if (bucket->hasData()) { for (const auto& pair : layerPaintProperties) { @@ -116,19 +119,18 @@ class PatternLayout : public Layout { } }; - std::map layerPaintProperties; - const std::string bucketLeaderID; + std::map layerPaintProperties; + std::string bucketLeaderID; private: const std::unique_ptr sourceLayer; std::vector features; - typename B::PossiblyEvaluatedLayoutProperties layout; + PossiblyEvaluatedLayoutPropertiesType layout; const float zoom; const uint32_t overscaling; std::string sourceLayerID; - std::string groupID; bool hasPattern; }; diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 03cfe506ec2..0eb98f75694 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -40,16 +40,18 @@ expression::Value sectionOptionsToValue(const SectionOptions& options) { } return result; } -} // namespace +inline const SymbolLayerProperties& toSymbolLayerProperties(const Immutable& layer) { + return static_cast(*layer); +} +} // namespace SymbolLayout::SymbolLayout(const BucketParameters& parameters, - const std::vector& layers, + const std::vector>& layers, std::unique_ptr sourceLayer_, ImageDependencies& imageDependencies, GlyphDependencies& glyphDependencies) - : Layout(), - bucketLeaderID(layers.at(0)->getID()), + : bucketLeaderID(layers.front()->baseImpl->id), sourceLayer(std::move(sourceLayer_)), overscaling(parameters.tileID.overscaleFactor()), zoom(parameters.tileID.overscaledZ), @@ -57,11 +59,11 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, pixelRatio(parameters.pixelRatio), tileSize(util::tileSize * overscaling), tilePixelRatio(float(util::EXTENT) / tileSize), - textSize(toRenderSymbolLayer(layers.at(0))->impl().layout.get()), - iconSize(toRenderSymbolLayer(layers.at(0))->impl().layout.get()) + textSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get()), + iconSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get()) { - const SymbolLayer::Impl& leader = toRenderSymbolLayer(layers.at(0))->impl(); + const SymbolLayer::Impl& leader = toSymbolLayerProperties(layers.at(0)).layerImpl(); layout = leader.layout.evaluate(PropertyEvaluationParameters(zoom)); @@ -104,7 +106,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, layout.get() || layout.get()); for (const auto& layer : layers) { - layerPaintProperties.emplace(layer->getID(), toRenderSymbolLayer(layer)->evaluated); + layerPaintProperties.emplace(layer->baseImpl->id, toSymbolLayerProperties(layer).evaluated); } // Determine glyph dependencies diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 9b8b0adfcce..9fc48d904cc 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -16,7 +16,6 @@ namespace mbgl { class BucketParameters; class Anchor; -class RenderLayer; class PlacedSymbol; namespace style { @@ -26,7 +25,7 @@ class Filter; class SymbolLayout final : public Layout { public: SymbolLayout(const BucketParameters&, - const std::vector&, + const std::vector>&, std::unique_ptr, ImageDependencies&, GlyphDependencies&); diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index 1d775ede04c..e345f0b5ec1 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -31,9 +31,6 @@ class Bucket { const ImagePositions&, const PatternLayerMap&) {}; - virtual void populateFeatureBuffers(const ImagePositions&) {}; - virtual void addPatternDependencies(const std::vector&, ImageDependencies&) {}; - // As long as this bucket has a Prepare render pass, this function is getting called. Typically, // this only happens once when the bucket is being rendered for the first time. virtual void upload(gfx::Context&) = 0; diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp index 54ed374069f..376f4e682fc 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.cpp +++ b/src/mbgl/renderer/buckets/circle_bucket.cpp @@ -10,14 +10,14 @@ namespace mbgl { using namespace style; -CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector& layers) +CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector>& layers) : mode(parameters.mode) { for (const auto& layer : layers) { paintPropertyBinders.emplace( std::piecewise_construct, - std::forward_as_tuple(layer->getID()), + std::forward_as_tuple(layer->baseImpl->id), std::forward_as_tuple( - toRenderCircleLayer(layer)->evaluated, + getEvaluated(layer), parameters.tileID.overscaledZ)); } } @@ -99,20 +99,20 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature, } template -static float get(const RenderCircleLayer& layer, const std::map& paintPropertyBinders) { - auto it = paintPropertyBinders.find(layer.getID()); +static float get(const CirclePaintProperties::PossiblyEvaluated& evaluated, const std::string& id, const std::map& paintPropertyBinders) { + auto it = paintPropertyBinders.find(id); if (it == paintPropertyBinders.end() || !it->second.statistics().max()) { - return layer.evaluated.get().constantOr(Property::defaultValue()); + return evaluated.get().constantOr(Property::defaultValue()); } else { return *it->second.statistics().max(); } } float CircleBucket::getQueryRadius(const RenderLayer& layer) const { - const RenderCircleLayer* circleLayer = toRenderCircleLayer(&layer); - float radius = get(*circleLayer, paintPropertyBinders); - float stroke = get(*circleLayer, paintPropertyBinders); - auto translate = circleLayer->evaluated.get(); + const auto& evaluated = getEvaluated(layer.evaluatedProperties); + float radius = get(evaluated, layer.getID(), paintPropertyBinders); + float stroke = get(evaluated, layer.getID(), paintPropertyBinders); + auto translate = evaluated.get(); return radius + stroke + util::length(translate[0], translate[1]); } diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp index e9aceed2b1d..58f76327aba 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.hpp +++ b/src/mbgl/renderer/buckets/circle_bucket.hpp @@ -15,7 +15,7 @@ class BucketParameters; class CircleBucket final : public Bucket { public: - CircleBucket(const BucketParameters&, const std::vector&); + CircleBucket(const BucketParameters&, const std::vector>&); ~CircleBucket() override; void addFeature(const GeometryTileFeature&, diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp index 927cb4a307f..2dffc555e2c 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_bucket.cpp @@ -141,10 +141,9 @@ bool FillBucket::supportsLayer(const style::Layer::Impl& impl) const { return style::FillLayer::Impl::staticTypeInfo() == impl.getTypeInfo(); } - float FillBucket::getQueryRadius(const RenderLayer& layer) const { - const RenderFillLayer* fillLayer = toRenderFillLayer(&layer); - const std::array& translate = fillLayer->evaluated.get(); + const auto& evaluated = getEvaluated(layer.evaluatedProperties); + const std::array& translate = evaluated.get(); return util::length(translate[0], translate[1]); } diff --git a/src/mbgl/renderer/buckets/fill_bucket.hpp b/src/mbgl/renderer/buckets/fill_bucket.hpp index e1869e08d20..5844625d2a2 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_bucket.hpp @@ -18,8 +18,6 @@ class RenderFillLayer; class FillBucket final : public Bucket { public: ~FillBucket() override; - // These aliases are used by the PatternLayout template - using RenderLayerType = RenderFillLayer; using PossiblyEvaluatedPaintProperties = style::FillPaintProperties::PossiblyEvaluated; using PossiblyEvaluatedLayoutProperties = style::Properties<>::PossiblyEvaluated; diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp index e640cf504d3..61fc6a14446 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp @@ -185,8 +185,8 @@ bool FillExtrusionBucket::supportsLayer(const style::Layer::Impl& impl) const { } float FillExtrusionBucket::getQueryRadius(const RenderLayer& layer) const { - const RenderFillExtrusionLayer* fillExtrusionLayer = toRenderFillExtrusionLayer(&layer); - const std::array& translate = fillExtrusionLayer->evaluated.get(); + const auto& evaluated = getEvaluated(layer.evaluatedProperties); + const std::array& translate = evaluated.get(); return util::length(translate[0], translate[1]); } diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp index 81685e2c423..9dc2681bac1 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp @@ -16,8 +16,6 @@ class RenderFillExtrusionLayer; class FillExtrusionBucket final : public Bucket { public: ~FillExtrusionBucket() override; - // These aliases are used by the PatternLayout template - using RenderLayerType = RenderFillExtrusionLayer; using PossiblyEvaluatedPaintProperties = style::FillExtrusionPaintProperties::PossiblyEvaluated; using PossiblyEvaluatedLayoutProperties = style::Properties<>::PossiblyEvaluated; diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.cpp b/src/mbgl/renderer/buckets/heatmap_bucket.cpp index 04fd58ec553..111911a88c2 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.cpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.cpp @@ -10,14 +10,14 @@ namespace mbgl { using namespace style; -HeatmapBucket::HeatmapBucket(const BucketParameters& parameters, const std::vector& layers) +HeatmapBucket::HeatmapBucket(const BucketParameters& parameters, const std::vector>& layers) : mode(parameters.mode) { for (const auto& layer : layers) { paintPropertyBinders.emplace( std::piecewise_construct, - std::forward_as_tuple(layer->getID()), + std::forward_as_tuple(layer->baseImpl->id), std::forward_as_tuple( - toRenderHeatmapLayer(layer)->evaluated, + getEvaluated(layer), parameters.tileID.overscaledZ)); } } diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.hpp b/src/mbgl/renderer/buckets/heatmap_bucket.hpp index 62cb460e271..b11c1626cd9 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.hpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.hpp @@ -15,7 +15,7 @@ class BucketParameters; class HeatmapBucket final : public Bucket { public: - HeatmapBucket(const BucketParameters&, const std::vector&); + HeatmapBucket(const BucketParameters&, const std::vector>&); ~HeatmapBucket() override; void addFeature(const GeometryTileFeature&, diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index 13f575ba387..9a5ed9e6285 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -11,10 +11,10 @@ namespace mbgl { using namespace style; LineBucket::LineBucket(const style::LineLayoutProperties::PossiblyEvaluated layout_, - std::map layerPaintProperties, + const std::map& layerPaintProperties, const float zoom_, const uint32_t overscaling_) - : layout(layout_), + : layout(std::move(layout_)), zoom(zoom_), overscaling(overscaling_) { @@ -528,31 +528,26 @@ bool LineBucket::supportsLayer(const style::Layer::Impl& impl) const { } template -static float get(const RenderLineLayer& layer, const std::map& paintPropertyBinders) { - auto it = paintPropertyBinders.find(layer.getID()); +static float get(const LinePaintProperties::PossiblyEvaluated& evaluated, const std::string& id, const std::map& paintPropertyBinders) { + auto it = paintPropertyBinders.find(id); if (it == paintPropertyBinders.end() || !it->second.statistics().max()) { - return layer.evaluated.get().constantOr(Property::defaultValue()); + return evaluated.get().constantOr(Property::defaultValue()); } else { return *it->second.statistics().max(); } } -float LineBucket::getLineWidth(const RenderLineLayer& layer) const { - float lineWidth = get(layer, paintPropertyBinders); - float gapWidth = get(layer, paintPropertyBinders); - +float LineBucket::getQueryRadius(const RenderLayer& layer) const { + const auto& evaluated = getEvaluated(layer.evaluatedProperties); + const std::array& translate = evaluated.get(); + float offset = get(evaluated, layer.getID(), paintPropertyBinders); + float lineWidth = get(evaluated, layer.getID(), paintPropertyBinders); + float gapWidth = get(evaluated, layer.getID(), paintPropertyBinders); if (gapWidth) { - return gapWidth + 2 * lineWidth; - } else { - return lineWidth; + lineWidth = gapWidth + 2 * lineWidth; } -} -float LineBucket::getQueryRadius(const RenderLayer& layer) const { - const RenderLineLayer* lineLayer = toRenderLineLayer(&layer); - const std::array& translate = lineLayer->evaluated.get(); - float offset = get(*lineLayer, paintPropertyBinders); - return getLineWidth(*lineLayer) / 2.0 + std::abs(offset) + util::length(translate[0], translate[1]); + return lineWidth / 2.0f + std::abs(offset) + util::length(translate[0], translate[1]); } } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 7ee8677e505..6717ee74461 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -17,14 +17,11 @@ class RenderLineLayer; class LineBucket final : public Bucket { public: - - // These aliases are used by the PatternLayout template - using RenderLayerType = RenderLineLayer; using PossiblyEvaluatedPaintProperties = style::LinePaintProperties::PossiblyEvaluated; using PossiblyEvaluatedLayoutProperties = style::LineLayoutProperties::PossiblyEvaluated; LineBucket(const PossiblyEvaluatedLayoutProperties layout, - std::map layerPaintProperties, + const std::map& layerPaintProperties, const float zoom, const uint32_t overscaling); ~LineBucket() override; @@ -77,8 +74,6 @@ class LineBucket final : public Bucket { const float zoom; const uint32_t overscaling; - - float getLineWidth(const RenderLineLayer& layer) const; }; } // namespace mbgl diff --git a/src/mbgl/renderer/group_by_layout.cpp b/src/mbgl/renderer/group_by_layout.cpp index 41a895902c2..5f78dd0d2bf 100644 --- a/src/mbgl/renderer/group_by_layout.cpp +++ b/src/mbgl/renderer/group_by_layout.cpp @@ -1,6 +1,4 @@ #include -#include -#include #include #include @@ -11,38 +9,24 @@ namespace mbgl { -std::string layoutKey(const RenderLayer& layer) { +std::string layoutKey(const style::Layer::Impl& impl) { using namespace style::conversion; rapidjson::StringBuffer s; rapidjson::Writer writer(s); writer.StartArray(); - writer.Uint64(reinterpret_cast(layer.baseImpl->getTypeInfo())); - writer.String(layer.baseImpl->source); - writer.String(layer.baseImpl->sourceLayer); - writer.Double(layer.baseImpl->minZoom); - writer.Double(layer.baseImpl->maxZoom); - writer.Uint(static_cast(layer.baseImpl->visibility)); - stringify(writer, layer.baseImpl->filter); - layer.baseImpl->stringifyLayout(writer); + writer.Uint64(reinterpret_cast(impl.getTypeInfo())); + writer.String(impl.source); + writer.String(impl.sourceLayer); + writer.Double(impl.minZoom); + writer.Double(impl.maxZoom); + writer.Uint(static_cast(impl.visibility)); + stringify(writer, impl.filter); + impl.stringifyLayout(writer); writer.EndArray(); return s.GetString(); } -std::vector> groupByLayout(const std::vector>& layers) { - std::unordered_map> map; - for (auto& layer : layers) { - map[layoutKey(*layer)].push_back(layer.get()); - } - - std::vector> result; - for (auto& pair : map) { - result.push_back(pair.second); - } - - return result; -} - } // namespace mbgl diff --git a/src/mbgl/renderer/group_by_layout.hpp b/src/mbgl/renderer/group_by_layout.hpp index bc3ecfae63c..0a91465e921 100644 --- a/src/mbgl/renderer/group_by_layout.hpp +++ b/src/mbgl/renderer/group_by_layout.hpp @@ -1,12 +1,12 @@ #pragma once +#include + #include #include namespace mbgl { -class RenderLayer; - -std::vector> groupByLayout(const std::vector>&); +std::string layoutKey(const style::Layer::Impl& impl); } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index b633ad06717..d5ba8c879f4 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -14,25 +14,30 @@ namespace mbgl { using namespace style; -RenderBackgroundLayer::RenderBackgroundLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()) { +inline const BackgroundLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); } -const style::BackgroundLayer::Impl& RenderBackgroundLayer::impl() const { - return static_cast(*baseImpl); +RenderBackgroundLayer::RenderBackgroundLayer(Immutable _impl) + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()) { } +RenderBackgroundLayer::~RenderBackgroundLayer() = default; + void RenderBackgroundLayer::transition(const TransitionParameters ¶meters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters ¶meters) { - evaluated = unevaluated.evaluate(parameters); - crossfade = parameters.getCrossfadeParameters(); - - passes = evaluated.get() > 0 ? RenderPass::Translucent - : RenderPass::None; + auto properties = makeMutable( + staticImmutableCast(baseImpl), + parameters.getCrossfadeParameters(), + unevaluated.evaluate(parameters)); + + passes = properties->evaluated.get() > 0 ? RenderPass::Translucent + : RenderPass::None; + evaluatedProperties = std::move(properties); } bool RenderBackgroundLayer::hasTransition() const { @@ -40,7 +45,7 @@ bool RenderBackgroundLayer::hasTransition() const { } bool RenderBackgroundLayer::hasCrossfade() const { - return crossfade.t != 1; + return static_cast(*evaluatedProperties).crossfade.t != 1; } void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { @@ -81,7 +86,8 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { getID() ); }; - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; + const auto& crossfade = static_cast(*evaluatedProperties).crossfade; if (!evaluated.get().to.empty()) { optional imagePosA = parameters.imageManager.getPattern(evaluated.get().from); optional imagePosB = parameters.imageManager.getPattern(evaluated.get().to); @@ -123,6 +129,7 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { } optional RenderBackgroundLayer::getSolidBackground() const { + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; if (!evaluated.get().from.empty()) { return nullopt; } diff --git a/src/mbgl/renderer/layers/render_background_layer.hpp b/src/mbgl/renderer/layers/render_background_layer.hpp index 3cb30ac2a34..de553eef904 100644 --- a/src/mbgl/renderer/layers/render_background_layer.hpp +++ b/src/mbgl/renderer/layers/render_background_layer.hpp @@ -6,25 +6,21 @@ namespace mbgl { -class RenderBackgroundLayer: public RenderLayer { +class RenderBackgroundLayer final : public RenderLayer { public: - RenderBackgroundLayer(Immutable); - ~RenderBackgroundLayer() final = default; + explicit RenderBackgroundLayer(Immutable); + ~RenderBackgroundLayer() override; +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; bool hasCrossfade() const override; - optional getSolidBackground() const final; + optional getSolidBackground() const override; void render(PaintParameters&, RenderSource*) override; // Paint properties style::BackgroundPaintProperties::Unevaluated unevaluated; - style::BackgroundPaintProperties::PossiblyEvaluated evaluated; - - const style::BackgroundLayer::Impl& impl() const; -private: - CrossfadeParameters crossfade; }; } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index ad4e6a020fd..9df20cf8746 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -15,21 +15,24 @@ namespace mbgl { using namespace style; -RenderCircleLayer::RenderCircleLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()) { +inline const style::CircleLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); } -const style::CircleLayer::Impl& RenderCircleLayer::impl() const { - return static_cast(*baseImpl); +RenderCircleLayer::RenderCircleLayer(Immutable _impl) + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()) { } void RenderCircleLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters) { - evaluated = unevaluated.evaluate(parameters); + auto properties = makeMutable( + staticImmutableCast(baseImpl), + unevaluated.evaluate(parameters)); + const auto& evaluated = properties->evaluated; passes = ((evaluated.get().constantOr(1) > 0 || evaluated.get().constantOr(1) > 0) @@ -38,6 +41,7 @@ void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters) && (evaluated.get().constantOr(1) > 0 || evaluated.get().constantOr(1) > 0)) ? RenderPass::Translucent : RenderPass::None; + evaluatedProperties = std::move(properties); } bool RenderCircleLayer::hasTransition() const { @@ -52,7 +56,7 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; } - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; const bool scaleWithMap = evaluated.get() == CirclePitchScaleType::Map; const bool pitchWithMap = evaluated.get() == AlignmentType::Map; @@ -139,7 +143,7 @@ bool RenderCircleLayer::queryIntersectsFeature( const TransformState& transformState, const float pixelsToTileUnits, const mat4& posMatrix) const { - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; // Translate query geometry const GeometryCoordinates& translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, diff --git a/src/mbgl/renderer/layers/render_circle_layer.hpp b/src/mbgl/renderer/layers/render_circle_layer.hpp index 8b0678f6d8f..fbe67c91acf 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.hpp +++ b/src/mbgl/renderer/layers/render_circle_layer.hpp @@ -6,11 +6,12 @@ namespace mbgl { -class RenderCircleLayer: public RenderLayer { +class RenderCircleLayer final : public RenderLayer { public: - RenderCircleLayer(Immutable); + explicit RenderCircleLayer(Immutable); ~RenderCircleLayer() final = default; +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; @@ -27,13 +28,6 @@ class RenderCircleLayer: public RenderLayer { // Paint properties style::CirclePaintProperties::Unevaluated unevaluated; - style::CirclePaintProperties::PossiblyEvaluated evaluated; - - const style::CircleLayer::Impl& impl() const; }; -inline const RenderCircleLayer* toRenderCircleLayer(const RenderLayer* layer) { - return static_cast(layer); -} - } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index 9284ed82382..4148de1ddd3 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -14,8 +14,13 @@ namespace mbgl { using namespace style; +inline const CustomLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); +} + RenderCustomLayer::RenderCustomLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), host(impl().host) { + : RenderLayer(makeMutable(std::move(_impl))), + host(impl(baseImpl).host) { assert(gfx::BackendScope::exists()); MBGL_CHECK_ERROR(host->initialize()); } @@ -29,12 +34,9 @@ RenderCustomLayer::~RenderCustomLayer() { } } -const CustomLayer::Impl& RenderCustomLayer::impl() const { - return static_cast(*baseImpl); -} - void RenderCustomLayer::evaluate(const PropertyEvaluationParameters&) { passes = RenderPass::Translucent; + // It is fine to not update `evaluatedProperties`, as `baseImpl` should never be updated for this layer. } bool RenderCustomLayer::hasTransition() const { @@ -49,12 +51,12 @@ void RenderCustomLayer::markContextDestroyed() { } void RenderCustomLayer::render(PaintParameters& paintParameters, RenderSource*) { - if (host != impl().host) { + if (host != impl(baseImpl).host) { //If the context changed, deinitialize the previous one before initializing the new one. if (host && !contextDestroyed) { MBGL_CHECK_ERROR(host->deinitialize()); } - host = impl().host; + host = impl(baseImpl).host; MBGL_CHECK_ERROR(host->initialize()); } diff --git a/src/mbgl/renderer/layers/render_custom_layer.hpp b/src/mbgl/renderer/layers/render_custom_layer.hpp index 37b85921724..0c364cfc0c4 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.hpp +++ b/src/mbgl/renderer/layers/render_custom_layer.hpp @@ -5,22 +5,20 @@ namespace mbgl { -class RenderCustomLayer: public RenderLayer { +class RenderCustomLayer final : public RenderLayer { public: - RenderCustomLayer(Immutable); - ~RenderCustomLayer() final; + explicit RenderCustomLayer(Immutable); + ~RenderCustomLayer() override; - void transition(const TransitionParameters&) final {} +private: + void transition(const TransitionParameters&) override {} void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; bool hasCrossfade() const override; - void markContextDestroyed() final; - - void render(PaintParameters&, RenderSource*) final; + void markContextDestroyed() override; - const style::CustomLayer::Impl& impl() const; + void render(PaintParameters&, RenderSource*) override; -private: bool contextDestroyed = false; std::shared_ptr host; }; diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index 4041e420dff..a313f53f1cd 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -20,26 +20,31 @@ namespace mbgl { using namespace style; -RenderFillExtrusionLayer::RenderFillExtrusionLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()) { +inline const FillExtrusionLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); } -const style::FillExtrusionLayer::Impl& RenderFillExtrusionLayer::impl() const { - return static_cast(*baseImpl); +RenderFillExtrusionLayer::RenderFillExtrusionLayer(Immutable _impl) + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()) { } +RenderFillExtrusionLayer::~RenderFillExtrusionLayer() = default; + void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) { - evaluated = unevaluated.evaluate(parameters); - crossfade = parameters.getCrossfadeParameters(); + auto properties = makeMutable( + staticImmutableCast(baseImpl), + parameters.getCrossfadeParameters(), + unevaluated.evaluate(parameters)); - passes = (evaluated.get() > 0) + passes = (properties->evaluated.get() > 0) ? (RenderPass::Translucent | RenderPass::Pass3D) : RenderPass::None; + evaluatedProperties = std::move(properties); } bool RenderFillExtrusionLayer::hasTransition() const { @@ -47,14 +52,15 @@ bool RenderFillExtrusionLayer::hasTransition() const { } bool RenderFillExtrusionLayer::hasCrossfade() const { - return crossfade.t != 1; + return static_cast(*evaluatedProperties).crossfade.t != 1; } void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; } - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; + const auto& crossfade = static_cast(*evaluatedProperties).crossfade; if (parameters.pass == RenderPass::Pass3D) { const auto& size = parameters.staticData.backendSize; @@ -222,7 +228,7 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature( const TransformState& transformState, const float pixelsToTileUnits, const mat4&) const { - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, evaluated.get(), diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp index 6f14fcd7a86..fa50ac6f2c9 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp @@ -7,19 +7,12 @@ namespace mbgl { -template -class PatternLayout; - -class FillExtrusionBucket; - -class RenderFillExtrusionLayer: public RenderLayer { +class RenderFillExtrusionLayer final : public RenderLayer { public: - using StyleLayerImpl = style::FillExtrusionLayer::Impl; - using PatternProperty = style::FillExtrusionPattern; - - RenderFillExtrusionLayer(Immutable); - ~RenderFillExtrusionLayer() final = default; + explicit RenderFillExtrusionLayer(Immutable); + ~RenderFillExtrusionLayer() override; +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; @@ -36,17 +29,8 @@ class RenderFillExtrusionLayer: public RenderLayer { // Paint properties style::FillExtrusionPaintProperties::Unevaluated unevaluated; - style::FillExtrusionPaintProperties::PossiblyEvaluated evaluated; - - const style::FillExtrusionLayer::Impl& impl() const; std::unique_ptr renderTexture; -private: - CrossfadeParameters crossfade; }; -inline const RenderFillExtrusionLayer* toRenderFillExtrusionLayer(const RenderLayer* layer) { - return static_cast(layer); -} - } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index e6447c83a4a..5b0f0202908 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -20,22 +20,27 @@ namespace mbgl { using namespace style; -RenderFillLayer::RenderFillLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()) { +inline const FillLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); } -const style::FillLayer::Impl& RenderFillLayer::impl() const { - return static_cast(*baseImpl); +RenderFillLayer::RenderFillLayer(Immutable _impl) + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()) { } +RenderFillLayer::~RenderFillLayer() = default; + void RenderFillLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) { - evaluated = unevaluated.evaluate(parameters); - crossfade = parameters.getCrossfadeParameters(); + auto properties = makeMutable( + staticImmutableCast(baseImpl), + parameters.getCrossfadeParameters(), + unevaluated.evaluate(parameters)); + auto& evaluated = properties->evaluated; if (unevaluated.get().isUndefined()) { evaluated.get() = evaluated.get(); @@ -54,6 +59,8 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) { } else { passes |= RenderPass::Opaque; } + + evaluatedProperties = std::move(properties); } bool RenderFillLayer::hasTransition() const { @@ -61,10 +68,12 @@ bool RenderFillLayer::hasTransition() const { } bool RenderFillLayer::hasCrossfade() const { - return crossfade.t != 1; + return static_cast(*evaluatedProperties).crossfade.t != 1; } void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; + const auto& crossfade = static_cast(*evaluatedProperties).crossfade; if (unevaluated.get().isUndefined()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket(*baseImpl); @@ -240,7 +249,7 @@ bool RenderFillLayer::queryIntersectsFeature( const TransformState& transformState, const float pixelsToTileUnits, const mat4&) const { - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, evaluated.get(), diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp index 1c7ee6556e1..5d5206efe20 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_layer.hpp @@ -9,14 +9,12 @@ namespace mbgl { class FillBucket; -class RenderFillLayer: public RenderLayer { +class RenderFillLayer final : public RenderLayer { public: - using StyleLayerImpl = style::FillLayer::Impl; - using PatternProperty = style::FillPattern; - - RenderFillLayer(Immutable); - ~RenderFillLayer() final = default; + explicit RenderFillLayer(Immutable); + ~RenderFillLayer() override; +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; @@ -33,16 +31,6 @@ class RenderFillLayer: public RenderLayer { // Paint properties style::FillPaintProperties::Unevaluated unevaluated; - style::FillPaintProperties::PossiblyEvaluated evaluated; - - const style::FillLayer::Impl& impl() const; -private: - CrossfadeParameters crossfade; - }; -inline const RenderFillLayer* toRenderFillLayer(const RenderLayer* layer) { - return static_cast(layer); -} - } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index 333b8f98900..92b54c6cc86 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -19,25 +19,31 @@ namespace mbgl { using namespace style; -RenderHeatmapLayer::RenderHeatmapLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()), colorRamp({256, 1}) { +inline const HeatmapLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); } -const style::HeatmapLayer::Impl& RenderHeatmapLayer::impl() const { - return static_cast(*baseImpl); +RenderHeatmapLayer::RenderHeatmapLayer(Immutable _impl) + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()), colorRamp({256, 1}) { } +RenderHeatmapLayer::~RenderHeatmapLayer() = default; + void RenderHeatmapLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters) { - evaluated = unevaluated.evaluate(parameters); + auto properties = makeMutable( + staticImmutableCast(baseImpl), + unevaluated.evaluate(parameters)); - passes = (evaluated.get() > 0) + passes = (properties->evaluated.get() > 0) ? (RenderPass::Translucent | RenderPass::Pass3D) : RenderPass::None; + + evaluatedProperties = std::move(properties); } bool RenderHeatmapLayer::hasTransition() const { @@ -52,7 +58,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; } - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; if (parameters.pass == RenderPass::Pass3D) { const auto& viewportSize = parameters.staticData.backendSize; const auto size = Size{viewportSize.width / 4, viewportSize.height / 4}; diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.hpp b/src/mbgl/renderer/layers/render_heatmap_layer.hpp index 22fe48f3749..50a7d72e94c 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.hpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.hpp @@ -9,11 +9,12 @@ namespace mbgl { -class RenderHeatmapLayer: public RenderLayer { +class RenderHeatmapLayer final : public RenderLayer { public: - RenderHeatmapLayer(Immutable); - ~RenderHeatmapLayer() final = default; + explicit RenderHeatmapLayer(Immutable); + ~RenderHeatmapLayer() override; +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; @@ -31,20 +32,11 @@ class RenderHeatmapLayer: public RenderLayer { // Paint properties style::HeatmapPaintProperties::Unevaluated unevaluated; - style::HeatmapPaintProperties::PossiblyEvaluated evaluated; - - const style::HeatmapLayer::Impl& impl() const; - PremultipliedImage colorRamp; std::unique_ptr renderTexture; optional colorRampTexture; -private: void updateColorRamp(); }; -inline const RenderHeatmapLayer* toRenderHeatmapLayer(const RenderLayer* layer) { - return static_cast(layer); -} - } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index 08efa898f66..19af5b6202c 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -17,36 +17,44 @@ namespace mbgl { using namespace style; -RenderHillshadeLayer::RenderHillshadeLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()) { + +inline const HillshadeLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); } -const style::HillshadeLayer::Impl& RenderHillshadeLayer::impl() const { - return static_cast(*baseImpl); +RenderHillshadeLayer::RenderHillshadeLayer(Immutable _impl) + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()) { } +RenderHillshadeLayer::~RenderHillshadeLayer() = default; + const std::array RenderHillshadeLayer::getLatRange(const UnwrappedTileID& id) { const LatLng latlng0 = LatLng(id); const LatLng latlng1 = LatLng(UnwrappedTileID(id.canonical.z, id.canonical.x, id.canonical.y + 1)); return {{ (float)latlng0.latitude(), (float)latlng1.latitude() }}; } -const std::array RenderHillshadeLayer::getLight(const PaintParameters& parameters){ +const std::array RenderHillshadeLayer::getLight(const PaintParameters& parameters) { + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; float azimuthal = evaluated.get() * util::DEG2RAD; if (evaluated.get() == HillshadeIlluminationAnchorType::Viewport) azimuthal = azimuthal - parameters.state.getBearing(); return {{evaluated.get(), azimuthal}}; } void RenderHillshadeLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& parameters) { - evaluated = unevaluated.evaluate(parameters); - passes = (evaluated.get() > 0) + auto properties = makeMutable( + staticImmutableCast(baseImpl), + unevaluated.evaluate(parameters)); + passes = (properties->evaluated.get() > 0) ? (RenderPass::Translucent | RenderPass::Pass3D) : RenderPass::None; + + evaluatedProperties = std::move(properties); } bool RenderHillshadeLayer::hasTransition() const { @@ -60,7 +68,7 @@ bool RenderHillshadeLayer::hasCrossfade() const { void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src) { if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D) return; - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; auto* demsrc = static_cast(src); const uint8_t TERRAIN_RGB_MAXZOOM = 15; const uint8_t maxzoom = demsrc != nullptr ? demsrc->getMaxZoom() : TERRAIN_RGB_MAXZOOM; diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.hpp b/src/mbgl/renderer/layers/render_hillshade_layer.hpp index 39853897637..7c7bc108359 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.hpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.hpp @@ -9,9 +9,10 @@ namespace mbgl { class RenderHillshadeLayer: public RenderLayer { public: - RenderHillshadeLayer(Immutable); - ~RenderHillshadeLayer() final = default; + explicit RenderHillshadeLayer(Immutable); + ~RenderHillshadeLayer() override; +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; @@ -21,10 +22,7 @@ class RenderHillshadeLayer: public RenderLayer { // Paint properties style::HillshadePaintProperties::Unevaluated unevaluated; - style::HillshadePaintProperties::PossiblyEvaluated evaluated; - const style::HillshadeLayer::Impl& impl() const; -private: const std::array getLatRange(const UnwrappedTileID& id); const std::array getLight(const PaintParameters& parameters); }; diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 2ea910f9115..cf4d3ed9b20 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -18,28 +18,34 @@ namespace mbgl { using namespace style; +inline const LineLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); +} + RenderLineLayer::RenderLineLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()), + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()), colorRamp({256, 1}) { } -const style::LineLayer::Impl& RenderLineLayer::impl() const { - return static_cast(*baseImpl); -} +RenderLineLayer::~RenderLineLayer() = default; void RenderLineLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) { - evaluated = unevaluated.evaluate(parameters); - crossfade = parameters.getCrossfadeParameters(); + auto properties = makeMutable( + staticImmutableCast(baseImpl), + parameters.getCrossfadeParameters(), + unevaluated.evaluate(parameters)); + auto& evaluated = properties->evaluated; passes = (evaluated.get().constantOr(1.0) > 0 && evaluated.get().constantOr(Color::black()).a > 0 && evaluated.get().constantOr(1.0) > 0) ? RenderPass::Translucent : RenderPass::None; + evaluatedProperties = std::move(properties); } bool RenderLineLayer::hasTransition() const { @@ -47,13 +53,15 @@ bool RenderLineLayer::hasTransition() const { } bool RenderLineLayer::hasCrossfade() const { - return crossfade.t != 1; + return static_cast(*evaluatedProperties).crossfade.t != 1; } void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; } + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; + const auto& crossfade = static_cast(*evaluatedProperties).crossfade; for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket(*baseImpl); @@ -213,7 +221,7 @@ bool RenderLineLayer::queryIntersectsFeature( const TransformState& transformState, const float pixelsToTileUnits, const mat4&) const { - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; // Translate query geometry auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, @@ -259,6 +267,7 @@ void RenderLineLayer::updateColorRamp() { } float RenderLineLayer::getLineWidth(const GeometryTileFeature& feature, const float zoom) const { + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; float lineWidth = evaluated.get() .evaluate(feature, zoom, style::LineWidth::defaultValue()); float gapWidth = evaluated.get() diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index cb4492ebc38..da64f584559 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -10,20 +10,18 @@ namespace mbgl { -class RenderLineLayer: public RenderLayer { +class RenderLineLayer final : public RenderLayer { public: - using StyleLayerImpl = style::LineLayer::Impl; - using PatternProperty = style::LinePattern; - - RenderLineLayer(Immutable); - ~RenderLineLayer() final = default; + explicit RenderLineLayer(Immutable); + ~RenderLineLayer() override; +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; - void update() final; + void update() override; bool queryIntersectsFeature( const GeometryCoordinates&, @@ -35,20 +33,12 @@ class RenderLineLayer: public RenderLayer { // Paint properties style::LinePaintProperties::Unevaluated unevaluated; - style::LinePaintProperties::PossiblyEvaluated evaluated; - - const style::LineLayer::Impl& impl() const; -private: float getLineWidth(const GeometryTileFeature&, const float) const; void updateColorRamp(); - CrossfadeParameters crossfade; + PremultipliedImage colorRamp; optional colorRampTexture; }; -inline const RenderLineLayer* toRenderLineLayer(const RenderLayer* layer) { - return static_cast(layer); -} - } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp index 55caeaf5b0f..48ca0584fcf 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.cpp +++ b/src/mbgl/renderer/layers/render_raster_layer.cpp @@ -14,23 +14,27 @@ namespace mbgl { using namespace style; -RenderRasterLayer::RenderRasterLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()) { +inline const RasterLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); } -const style::RasterLayer::Impl& RenderRasterLayer::impl() const { - return static_cast(*baseImpl); +RenderRasterLayer::RenderRasterLayer(Immutable _impl) + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()) { } +RenderRasterLayer::~RenderRasterLayer() = default; + void RenderRasterLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters) { - evaluated = unevaluated.evaluate(parameters); - - passes = evaluated.get() > 0 ? RenderPass::Translucent : RenderPass::None; + auto properties = makeMutable( + staticImmutableCast(baseImpl), + unevaluated.evaluate(parameters)); + passes = properties->evaluated.get() > 0 ? RenderPass::Translucent : RenderPass::None; + evaluatedProperties = std::move(properties); } bool RenderRasterLayer::hasTransition() const { @@ -72,7 +76,7 @@ static std::array spinWeights(float spin) { void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source) { if (parameters.pass != RenderPass::Translucent) return; - + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; RasterProgram::Binders paintAttributeData{ evaluated, 0 }; auto draw = [&] (const mat4& matrix, diff --git a/src/mbgl/renderer/layers/render_raster_layer.hpp b/src/mbgl/renderer/layers/render_raster_layer.hpp index 516c163c27d..9d70e9fb4da 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.hpp +++ b/src/mbgl/renderer/layers/render_raster_layer.hpp @@ -6,11 +6,12 @@ namespace mbgl { -class RenderRasterLayer: public RenderLayer { +class RenderRasterLayer final : public RenderLayer { public: - RenderRasterLayer(Immutable); - ~RenderRasterLayer() final = default; + explicit RenderRasterLayer(Immutable); + ~RenderRasterLayer() override; +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; @@ -20,9 +21,6 @@ class RenderRasterLayer: public RenderLayer { // Paint properties style::RasterPaintProperties::Unevaluated unevaluated; - style::RasterPaintProperties::PossiblyEvaluated evaluated; - - const style::RasterLayer::Impl& impl() const; }; } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 634e0cf01bf..95df9435f90 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -306,24 +306,29 @@ void drawText(const DrawFn& draw, }); } } + +inline const SymbolLayer::Impl& impl(const Immutable& impl) { + return static_cast(*impl); +} + } // namespace RenderSymbolLayer::RenderSymbolLayer(Immutable _impl) - : RenderLayer(std::move(_impl)), - unevaluated(impl().paint.untransitioned()) { + : RenderLayer(makeMutable(std::move(_impl))), + unevaluated(impl(baseImpl).paint.untransitioned()) { } -const style::SymbolLayer::Impl& RenderSymbolLayer::impl() const { - return static_cast(*baseImpl); -} +RenderSymbolLayer::~RenderSymbolLayer() = default; void RenderSymbolLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl().paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters) { - evaluated = unevaluated.evaluate(parameters); - + auto properties = makeMutable( + staticImmutableCast(baseImpl), + unevaluated.evaluate(parameters)); + const auto& evaluated = properties->evaluated; auto hasIconOpacity = evaluated.get().constantOr(Color::black()).a > 0 || evaluated.get().constantOr(Color::black()).a > 0; auto hasTextOpacity = evaluated.get().constantOr(Color::black()).a > 0 || @@ -332,6 +337,7 @@ void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters) passes = ((evaluated.get().constantOr(1) > 0 && hasIconOpacity && iconSize > 0) || (evaluated.get().constantOr(1) > 0 && hasTextOpacity && textSize > 0)) ? RenderPass::Translucent : RenderPass::None; + evaluatedProperties = std::move(properties); } bool RenderSymbolLayer::hasTransition() const { @@ -363,7 +369,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { return; } - const bool sortFeaturesByKey = !impl().layout.get().isUndefined(); + const bool sortFeaturesByKey = !impl(baseImpl).layout.get().isUndefined(); std::set renderableSegments; const auto draw = [¶meters, this] (auto& programInstance, @@ -598,6 +604,7 @@ void RenderSymbolLayer::setRenderTiles(RenderTiles tiles, const TransformState& void RenderSymbolLayer::updateBucketPaintProperties(Bucket* bucket) const { assert(bucket->supportsLayer(*baseImpl)); + const auto& evaluated = static_cast(*evaluatedProperties).evaluated; static_cast(bucket)->updatePaintProperties(getID(), evaluated); } diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index 7b6d249b2eb..552dd30ca25 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -53,15 +53,15 @@ class SymbolPropertyValues { } // namespace style -class BucketParameters; -class SymbolLayout; -class GeometryTileLayer; - class RenderSymbolLayer final: public RenderLayer, public RenderLayerSymbolInterface { public: - RenderSymbolLayer(Immutable); - ~RenderSymbolLayer() final = default; + explicit RenderSymbolLayer(Immutable); + ~RenderSymbolLayer() override; + static style::IconPaintProperties::PossiblyEvaluated iconPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&); + static style::TextPaintProperties::PossiblyEvaluated textPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&); + +private: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; @@ -69,30 +69,20 @@ class RenderSymbolLayer final: public RenderLayer, public RenderLayerSymbolInter void render(PaintParameters&, RenderSource*) override; void setRenderTiles(RenderTiles, const TransformState&) override; - static style::IconPaintProperties::PossiblyEvaluated iconPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&); - static style::TextPaintProperties::PossiblyEvaluated textPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&); - // RenderLayerSymbolInterface overrides - const RenderLayerSymbolInterface* getSymbolInterface() const final; - const std::string& layerID() const final; - const std::vector>& getRenderTiles() const final; - SymbolBucket* getSymbolBucket(const RenderTile&) const final; + const RenderLayerSymbolInterface* getSymbolInterface() const override; + const std::string& layerID() const override; + const std::vector>& getRenderTiles() const override; + SymbolBucket* getSymbolBucket(const RenderTile&) const override; // Paint properties style::SymbolPaintProperties::Unevaluated unevaluated; - style::SymbolPaintProperties::PossiblyEvaluated evaluated; float iconSize = 1.0f; float textSize = 16.0f; - const style::SymbolLayer::Impl& impl() const; - protected: void updateBucketPaintProperties(Bucket*) const final; }; -inline const RenderSymbolLayer* toRenderSymbolLayer(const RenderLayer* layer) { - return static_cast(layer); -} - } // namespace mbgl diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index 24a45b91465..c2719fef914 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -10,8 +10,9 @@ namespace mbgl { using namespace style; -RenderLayer::RenderLayer(Immutable baseImpl_) - : baseImpl(std::move(baseImpl_)) { +RenderLayer::RenderLayer(Immutable properties) + : evaluatedProperties(std::move(properties)), + baseImpl(evaluatedProperties->baseImpl) { } void RenderLayer::setImpl(Immutable impl) { diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 98e151435ac..9654b9213f3 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -1,7 +1,7 @@ #pragma once #include #include -#include +#include #include #include @@ -11,7 +11,6 @@ namespace mbgl { class Bucket; -class BucketParameters; class TransitionParameters; class PropertyEvaluationParameters; class PaintParameters; @@ -22,7 +21,7 @@ class TransformState; class RenderLayer { protected: - RenderLayer(Immutable); + RenderLayer(Immutable); public: virtual ~RenderLayer() = default; @@ -31,6 +30,7 @@ class RenderLayer { virtual void transition(const TransitionParameters&) = 0; // Fully evaluate possibly-transitioning paint properties based on a zoom level. + // Updates the contained `evaluatedProperties` member. virtual void evaluate(const PropertyEvaluationParameters&) = 0; // Returns true if any paint properties have active transitions. @@ -65,6 +65,8 @@ class RenderLayer { using RenderTiles = std::vector>; virtual void setRenderTiles(RenderTiles, const TransformState&); + // Latest evaluated properties. + Immutable evaluatedProperties; // Private implementation Immutable baseImpl; void setImpl(Immutable); diff --git a/src/mbgl/style/layers/custom_layer_impl.hpp b/src/mbgl/style/layers/custom_layer_impl.hpp index 1ebf1b53f1d..d8b8a7f286f 100644 --- a/src/mbgl/style/layers/custom_layer_impl.hpp +++ b/src/mbgl/style/layers/custom_layer_impl.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -24,5 +25,11 @@ class CustomLayer::Impl : public Layer::Impl { DECLARE_LAYER_TYPE_INFO; }; +class CustomLayerProperties final : public LayerProperties { +public: + explicit CustomLayerProperties(Immutable impl) + : LayerProperties(std::move(impl)) {} +}; + } // namespace style } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index 0c8b7a4ca12..56f6401ce7b 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -312,22 +312,23 @@ void GeometryTileWorker::requestNewImages(const ImageDependencies& imageDependen } } -static std::vector> toRenderLayers(const std::vector>& layers, float zoom) { - std::vector> renderLayers; - renderLayers.reserve(layers.size()); +static std::vector> toEvaluatedProperties(const std::vector>& layers, float zoom) { + std::vector> result; + result.reserve(layers.size()); for (auto& layer : layers) { - renderLayers.push_back(LayerManager::get()->createRenderLayer(layer)); + auto renderLayer = LayerManager::get()->createRenderLayer(layer); - renderLayers.back()->transition(TransitionParameters { + renderLayer->transition(TransitionParameters { Clock::time_point::max(), TransitionOptions() }); - renderLayers.back()->evaluate(PropertyEvaluationParameters { + renderLayer->evaluate(PropertyEvaluationParameters { zoom }); + result.push_back(renderLayer->evaluatedProperties); } - return renderLayers; + return result; } void GeometryTileWorker::parse() { @@ -348,10 +349,14 @@ void GeometryTileWorker::parse() { ImageDependencies imageDependencies; // Create render layers and group by layout - std::vector> renderLayers = toRenderLayers(*layers, id.overscaledZ); - std::vector> groups = groupByLayout(renderLayers); + std::vector> evaluatedProperties = toEvaluatedProperties(*layers, id.overscaledZ); + std::unordered_map>> groupMap; + for (auto layer : evaluatedProperties) { + groupMap[layoutKey(*layer->baseImpl)].push_back(std::move(layer)); + } - for (auto& group : groups) { + for (auto& pair : groupMap) { + const auto& group = pair.second; if (obsolete) { return; } @@ -360,35 +365,35 @@ void GeometryTileWorker::parse() { continue; // Tile has no data. } - const RenderLayer& leader = *group.at(0); - BucketParameters parameters { id, mode, pixelRatio, leader.baseImpl->getTypeInfo() }; + const style::Layer::Impl& leaderImpl = *(group.at(0)->baseImpl); + BucketParameters parameters { id, mode, pixelRatio, leaderImpl.getTypeInfo() }; - auto geometryLayer = (*data)->getLayer(leader.baseImpl->sourceLayer); + auto geometryLayer = (*data)->getLayer(leaderImpl.sourceLayer); if (!geometryLayer) { continue; } - std::vector layerIDs; + std::vector layerIDs(group.size()); for (const auto& layer : group) { - layerIDs.push_back(layer->getID()); + layerIDs.push_back(layer->baseImpl->id); } - featureIndex->setBucketLayerIDs(leader.getID(), layerIDs); + featureIndex->setBucketLayerIDs(leaderImpl.id, layerIDs); // Symbol layers and layers that support pattern properties have an extra step at layout time to figure out what images/glyphs // are needed to render the layer. They use the intermediate Layout data structure to accomplish this, // and either immediately create a bucket if no images/glyphs are used, or the Layout is stored until // the images/glyphs are available to add the features to the buckets. - if (leader.baseImpl->getTypeInfo()->layout == LayerTypeInfo::Layout::Required) { - auto layout = LayerManager::get()->createLayout({parameters, glyphDependencies, imageDependencies}, std::move(geometryLayer), group); + if (leaderImpl.getTypeInfo()->layout == LayerTypeInfo::Layout::Required) { + std::unique_ptr layout = LayerManager::get()->createLayout({parameters, glyphDependencies, imageDependencies}, std::move(geometryLayer), group); if (layout->hasDependencies()) { layouts.push_back(std::move(layout)); } else { layout->createBucket({}, featureIndex, buckets, firstLoad, showCollisionBoxes); } } else { - const Filter& filter = leader.baseImpl->filter; - const std::string& sourceLayerID = leader.baseImpl->sourceLayer; + const Filter& filter = leaderImpl.filter; + const std::string& sourceLayerID = leaderImpl.sourceLayer; std::shared_ptr bucket = LayerManager::get()->createBucket(parameters, group); for (std::size_t i = 0; !obsolete && i < geometryLayer->featureCount(); i++) { @@ -399,7 +404,7 @@ void GeometryTileWorker::parse() { GeometryCollection geometries = feature->getGeometries(); bucket->addFeature(*feature, geometries, {}, PatternLayerMap ()); - featureIndex->insert(geometries, i, sourceLayerID, leader.getID()); + featureIndex->insert(geometries, i, sourceLayerID, leaderImpl.id); } if (!bucket->hasData()) { @@ -407,7 +412,7 @@ void GeometryTileWorker::parse() { } for (const auto& layer : group) { - buckets.emplace(layer->getID(), bucket); + buckets.emplace(layer->baseImpl->id, bucket); } } } diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp index 4402875603c..fb841c63be8 100644 --- a/src/mbgl/tile/geometry_tile_worker.hpp +++ b/src/mbgl/tile/geometry_tile_worker.hpp @@ -20,9 +20,6 @@ class GeometryTile; class GeometryTileData; class Layout; -template -class PatternLayout; - namespace style { class Layer; } // namespace style diff --git a/test/renderer/group_by_layout.test.cpp b/test/renderer/group_by_layout.test.cpp deleted file mode 100644 index d1a7a0bf5fe..00000000000 --- a/test/renderer/group_by_layout.test.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace mbgl; -using namespace mbgl::style; -using namespace mbgl::style::expression; - -static std::vector> toRenderLayers(const std::vector>& layers) { - std::vector> result; - result.reserve(layers.size()); - for (auto& layer : layers) { - result.push_back(LayerManager::get()->createRenderLayer(layer->baseImpl)); - } - return result; -} - -TEST(GroupByLayout, Related) { - std::vector> layers; - layers.push_back(std::make_unique("a", "source")); - layers.push_back(std::make_unique("b", "source")); - auto result = groupByLayout(toRenderLayers(layers)); - ASSERT_EQ(1u, result.size()); - ASSERT_EQ(2u, result[0].size()); -} - -TEST(GroupByLayout, UnrelatedType) { - std::vector> layers; - layers.push_back(std::make_unique("background")); - layers.push_back(std::make_unique("circle", "source")); - auto result = groupByLayout(toRenderLayers(layers)); - ASSERT_EQ(2u, result.size()); -} - -TEST(GroupByLayout, UnrelatedFilter) { - using namespace mbgl::style::expression::dsl; - std::vector> layers; - auto lineLayer = std::make_unique("a", "source"); - lineLayer->setFilter(Filter(get("property"))); - layers.push_back(std::move(lineLayer)); - layers.push_back(std::make_unique("b", "source")); - auto result = groupByLayout(toRenderLayers(layers)); - ASSERT_EQ(2u, result.size()); -} - -TEST(GroupByLayout, UnrelatedLayout) { - std::vector> layers; - auto lineLayer = std::make_unique("a", "source"); - lineLayer->setLineCap(LineCapType::Square); - layers.push_back(std::move(lineLayer)); - layers.push_back(std::make_unique("b", "source")); - auto result = groupByLayout(toRenderLayers(layers)); - ASSERT_EQ(2u, result.size()); -} diff --git a/test/test-files.json b/test/test-files.json index 0ba0a07577c..df46689d50b 100644 --- a/test/test-files.json +++ b/test/test-files.json @@ -28,7 +28,6 @@ "test/programs/binary_program.test.cpp", "test/programs/symbol_program.test.cpp", "test/renderer/backend_scope.test.cpp", - "test/renderer/group_by_layout.test.cpp", "test/renderer/image_manager.test.cpp", "test/sprite/sprite_loader.test.cpp", "test/sprite/sprite_parser.test.cpp",