diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-10-20 15:05:06 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-10-30 11:19:28 -0700 |
commit | ddc4251074dae9115d6e252099ec04995188e29a (patch) | |
tree | 654c626ed9329edc3c85848aac1b3259db690272 | |
parent | 540c6eca1544dd9617a7a19ffa9d396ed96df4ec (diff) | |
download | qtlocation-mapboxgl-ddc4251074dae9115d6e252099ec04995188e29a.tar.gz |
[core] Polymorphic bucket creation
-rw-r--r-- | src/mbgl/layer/background_layer.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/layer/background_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/circle_layer.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/layer/circle_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/fill_layer.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/layer/fill_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/line_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/layer/line_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/raster_layer.cpp | 5 | ||||
-rw-r--r-- | src/mbgl/layer/raster_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layer/symbol_layer.cpp | 69 | ||||
-rw-r--r-- | src/mbgl/layer/symbol_layer.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/tile_worker.cpp | 163 | ||||
-rw-r--r-- | src/mbgl/map/tile_worker.hpp | 15 | ||||
-rw-r--r-- | src/mbgl/renderer/bucket.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/class_properties.hpp | 10 | ||||
-rw-r--r-- | src/mbgl/style/style_bucket_parameters.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/style/style_bucket_parameters.hpp | 63 | ||||
-rw-r--r-- | src/mbgl/style/style_layer.hpp | 4 |
19 files changed, 247 insertions, 162 deletions
diff --git a/src/mbgl/layer/background_layer.cpp b/src/mbgl/layer/background_layer.cpp index 70c6488ce1..bbfd56a1b3 100644 --- a/src/mbgl/layer/background_layer.cpp +++ b/src/mbgl/layer/background_layer.cpp @@ -21,4 +21,8 @@ void BackgroundLayer::recalculate(const StyleCalculationParameters& parameters) passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None; } +std::unique_ptr<Bucket> BackgroundLayer::createBucket(StyleBucketParameters&) const { + return nullptr; +} + } diff --git a/src/mbgl/layer/background_layer.hpp b/src/mbgl/layer/background_layer.hpp index 86dfd24a4b..b333cd4636 100644 --- a/src/mbgl/layer/background_layer.hpp +++ b/src/mbgl/layer/background_layer.hpp @@ -15,6 +15,8 @@ public: void recalculate(const StyleCalculationParameters&) override; + std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override; + BackgroundPaintProperties properties; }; diff --git a/src/mbgl/layer/circle_layer.cpp b/src/mbgl/layer/circle_layer.cpp index e3fa4b4dee..e74e87ea9d 100644 --- a/src/mbgl/layer/circle_layer.cpp +++ b/src/mbgl/layer/circle_layer.cpp @@ -1,5 +1,7 @@ #include <mbgl/layer/circle_layer.hpp> #include <mbgl/style/property_parsing.hpp> +#include <mbgl/style/style_bucket_parameters.hpp> +#include <mbgl/renderer/circle_bucket.hpp> namespace mbgl { @@ -27,4 +29,14 @@ void CircleLayer::recalculate(const StyleCalculationParameters& parameters) { passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None; } +std::unique_ptr<Bucket> CircleLayer::createBucket(StyleBucketParameters& parameters) const { + auto bucket = std::make_unique<CircleBucket>(); + + parameters.eachFilteredFeature(filter, [&] (const auto& feature) { + bucket->addGeometry(feature.getGeometries()); + }); + + return std::move(bucket); +} + } diff --git a/src/mbgl/layer/circle_layer.hpp b/src/mbgl/layer/circle_layer.hpp index 957d6b9cae..f07d304846 100644 --- a/src/mbgl/layer/circle_layer.hpp +++ b/src/mbgl/layer/circle_layer.hpp @@ -15,6 +15,8 @@ public: void recalculate(const StyleCalculationParameters&) override; + std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override; + CirclePaintProperties properties; }; diff --git a/src/mbgl/layer/fill_layer.cpp b/src/mbgl/layer/fill_layer.cpp index 53bf0ac89c..5ff26337b7 100644 --- a/src/mbgl/layer/fill_layer.cpp +++ b/src/mbgl/layer/fill_layer.cpp @@ -1,5 +1,7 @@ #include <mbgl/layer/fill_layer.hpp> #include <mbgl/style/property_parsing.hpp> +#include <mbgl/style/style_bucket_parameters.hpp> +#include <mbgl/renderer/fill_bucket.hpp> namespace mbgl { @@ -43,4 +45,14 @@ void FillLayer::recalculate(const StyleCalculationParameters& parameters) { } } +std::unique_ptr<Bucket> FillLayer::createBucket(StyleBucketParameters& parameters) const { + auto bucket = std::make_unique<FillBucket>(); + + parameters.eachFilteredFeature(filter, [&] (const auto& feature) { + bucket->addGeometry(feature.getGeometries()); + }); + + return std::move(bucket); +} + } diff --git a/src/mbgl/layer/fill_layer.hpp b/src/mbgl/layer/fill_layer.hpp index 7a5d468bb3..fd22efa826 100644 --- a/src/mbgl/layer/fill_layer.hpp +++ b/src/mbgl/layer/fill_layer.hpp @@ -15,6 +15,8 @@ public: void recalculate(const StyleCalculationParameters&) override; + std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override; + FillPaintProperties properties; }; diff --git a/src/mbgl/layer/line_layer.cpp b/src/mbgl/layer/line_layer.cpp index 793c133325..a27cf65ee2 100644 --- a/src/mbgl/layer/line_layer.cpp +++ b/src/mbgl/layer/line_layer.cpp @@ -1,5 +1,7 @@ #include <mbgl/layer/line_layer.hpp> #include <mbgl/style/property_parsing.hpp> +#include <mbgl/style/style_bucket_parameters.hpp> +#include <mbgl/renderer/line_bucket.hpp> #include <mbgl/map/tile_id.hpp> namespace mbgl { @@ -52,4 +54,21 @@ void LineLayer::recalculate(const StyleCalculationParameters& parameters) { passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None; } +std::unique_ptr<Bucket> LineLayer::createBucket(StyleBucketParameters& parameters) const { + auto bucket = std::make_unique<LineBucket>(); + + const float z = parameters.tileID.z; + + layout.calculate(PropertyKey::LineCap, bucket->layout.cap, z); + layout.calculate(PropertyKey::LineJoin, bucket->layout.join, z); + layout.calculate(PropertyKey::LineMiterLimit, bucket->layout.miter_limit, z); + layout.calculate(PropertyKey::LineRoundLimit, bucket->layout.round_limit, z); + + parameters.eachFilteredFeature(filter, [&] (const auto& feature) { + bucket->addGeometry(feature.getGeometries()); + }); + + return std::move(bucket); +} + } diff --git a/src/mbgl/layer/line_layer.hpp b/src/mbgl/layer/line_layer.hpp index 5f8c0f2b3a..8acd58f01f 100644 --- a/src/mbgl/layer/line_layer.hpp +++ b/src/mbgl/layer/line_layer.hpp @@ -15,6 +15,8 @@ public: void recalculate(const StyleCalculationParameters&) override; + std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override; + LinePaintProperties properties; }; diff --git a/src/mbgl/layer/raster_layer.cpp b/src/mbgl/layer/raster_layer.cpp index 3f210233ac..8649b58ab8 100644 --- a/src/mbgl/layer/raster_layer.cpp +++ b/src/mbgl/layer/raster_layer.cpp @@ -1,5 +1,6 @@ #include <mbgl/layer/raster_layer.hpp> #include <mbgl/style/property_parsing.hpp> +#include <mbgl/renderer/bucket.hpp> namespace mbgl { @@ -35,4 +36,8 @@ void RasterLayer::recalculate(const StyleCalculationParameters& parameters) { passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None; } +std::unique_ptr<Bucket> RasterLayer::createBucket(StyleBucketParameters&) const { + return nullptr; +} + } diff --git a/src/mbgl/layer/raster_layer.hpp b/src/mbgl/layer/raster_layer.hpp index 6a0de8a38c..a5b09191a6 100644 --- a/src/mbgl/layer/raster_layer.hpp +++ b/src/mbgl/layer/raster_layer.hpp @@ -15,6 +15,8 @@ public: void recalculate(const StyleCalculationParameters&) override; + std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override; + RasterPaintProperties properties; }; diff --git a/src/mbgl/layer/symbol_layer.cpp b/src/mbgl/layer/symbol_layer.cpp index bde588de02..a82eae3aaa 100644 --- a/src/mbgl/layer/symbol_layer.cpp +++ b/src/mbgl/layer/symbol_layer.cpp @@ -1,6 +1,9 @@ #include <mbgl/layer/symbol_layer.hpp> +#include <mbgl/renderer/symbol_bucket.hpp> +#include <mbgl/map/tile_id.hpp> #include <mbgl/style/property_evaluator.hpp> #include <mbgl/style/property_parsing.hpp> +#include <mbgl/style/style_bucket_parameters.hpp> namespace mbgl { @@ -108,4 +111,70 @@ void SymbolLayer::recalculate(const StyleCalculationParameters& parameters) { passes = properties.isVisible() ? RenderPass::Translucent : RenderPass::None; } +std::unique_ptr<Bucket> SymbolLayer::createBucket(StyleBucketParameters& parameters) const { + const float z = parameters.tileID.z; + auto bucket = std::make_unique<SymbolBucket>(parameters.tileID.overscaling, z); + + layout.calculate(PropertyKey::SymbolPlacement, bucket->layout.placement, z); + if (bucket->layout.placement == PlacementType::Line) { + bucket->layout.icon.rotation_alignment = RotationAlignmentType::Map; + bucket->layout.text.rotation_alignment = RotationAlignmentType::Map; + }; + layout.calculate(PropertyKey::SymbolSpacing, bucket->layout.spacing, z); + layout.calculate(PropertyKey::SymbolAvoidEdges, bucket->layout.avoid_edges, z); + + layout.calculate(PropertyKey::IconAllowOverlap, bucket->layout.icon.allow_overlap, z); + layout.calculate(PropertyKey::IconIgnorePlacement, bucket->layout.icon.ignore_placement, z); + layout.calculate(PropertyKey::IconOptional, bucket->layout.icon.optional, z); + layout.calculate(PropertyKey::IconRotationAlignment, bucket->layout.icon.rotation_alignment, z); + layout.calculate(PropertyKey::IconImage, bucket->layout.icon.image, z); + layout.calculate(PropertyKey::IconPadding, bucket->layout.icon.padding, z); + layout.calculate(PropertyKey::IconRotate, bucket->layout.icon.rotate, z); + layout.calculate(PropertyKey::IconKeepUpright, bucket->layout.icon.keep_upright, z); + layout.calculate(PropertyKey::IconOffset, bucket->layout.icon.offset, z); + + layout.calculate(PropertyKey::TextRotationAlignment, bucket->layout.text.rotation_alignment, z); + layout.calculate(PropertyKey::TextField, bucket->layout.text.field, z); + layout.calculate(PropertyKey::TextFont, bucket->layout.text.font, z); + layout.calculate(PropertyKey::TextMaxWidth, bucket->layout.text.max_width, z); + layout.calculate(PropertyKey::TextLineHeight, bucket->layout.text.line_height, z); + layout.calculate(PropertyKey::TextLetterSpacing, bucket->layout.text.letter_spacing, z); + layout.calculate(PropertyKey::TextMaxAngle, bucket->layout.text.max_angle, z); + layout.calculate(PropertyKey::TextRotate, bucket->layout.text.rotate, z); + layout.calculate(PropertyKey::TextPadding, bucket->layout.text.padding, z); + layout.calculate(PropertyKey::TextIgnorePlacement, bucket->layout.text.ignore_placement, z); + layout.calculate(PropertyKey::TextOptional, bucket->layout.text.optional, z); + layout.calculate(PropertyKey::TextJustify, bucket->layout.text.justify, z); + layout.calculate(PropertyKey::TextAnchor, bucket->layout.text.anchor, z); + layout.calculate(PropertyKey::TextKeepUpright, bucket->layout.text.keep_upright, z); + layout.calculate(PropertyKey::TextTransform, bucket->layout.text.transform, z); + layout.calculate(PropertyKey::TextOffset, bucket->layout.text.offset, z); + layout.calculate(PropertyKey::TextAllowOverlap, bucket->layout.text.allow_overlap, z); + + layout.calculate(PropertyKey::IconSize, bucket->layout.icon.size, z + 1); + layout.calculate(PropertyKey::IconSize, bucket->layout.icon.max_size, 18); + layout.calculate(PropertyKey::TextSize, bucket->layout.text.size, z + 1); + layout.calculate(PropertyKey::TextSize, bucket->layout.text.max_size, 18); + + bucket->parseFeatures(parameters.layer, filter); + + if (bucket->needsDependencies(parameters.glyphStore, parameters.sprite)) { + parameters.partialParse = true; + } + + // We do not add features if the parser is in a "partial" state because + // the layer ordering needs to be respected when calculating text + // collisions. Although, at this point, we requested all the resources + // needed by this tile. + if (!parameters.partialParse) { + bucket->addFeatures(parameters.tileUID, + parameters.spriteAtlas, + parameters.glyphAtlas, + parameters.glyphStore, + parameters.collisionTile); + } + + return std::move(bucket); +} + } diff --git a/src/mbgl/layer/symbol_layer.hpp b/src/mbgl/layer/symbol_layer.hpp index ce92c19594..21f0f41d07 100644 --- a/src/mbgl/layer/symbol_layer.hpp +++ b/src/mbgl/layer/symbol_layer.hpp @@ -15,6 +15,8 @@ public: void recalculate(const StyleCalculationParameters&) override; + std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override; + SymbolPaintProperties properties; }; diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp index ede55c0239..8c1115170d 100644 --- a/src/mbgl/map/tile_worker.cpp +++ b/src/mbgl/map/tile_worker.cpp @@ -1,13 +1,11 @@ #include <mbgl/text/collision_tile.hpp> #include <mbgl/map/tile_worker.hpp> +#include <mbgl/map/geometry_tile.hpp> #include <mbgl/style/style.hpp> #include <mbgl/style/style_layer.hpp> -#include <mbgl/style/property_evaluator.hpp> +#include <mbgl/style/style_bucket_parameters.hpp> #include <mbgl/geometry/sprite_atlas.hpp> #include <mbgl/geometry/glyph_atlas.hpp> -#include <mbgl/renderer/fill_bucket.hpp> -#include <mbgl/renderer/line_bucket.hpp> -#include <mbgl/renderer/circle_bucket.hpp> #include <mbgl/renderer/symbol_bucket.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/util/constants.hpp> @@ -21,7 +19,6 @@ TileWorker::TileWorker(TileID id_, const std::atomic<TileData::State>& state_) : id(id_), sourceID(sourceID_), - parameters(id.z), style(style_), state(state_) { assert(style.sprite); @@ -36,6 +33,7 @@ TileParseResult TileWorker::parseAllLayers(std::vector<util::ptr<StyleLayer>> la PlacementConfig config) { // We're doing a fresh parse of the tile, because the underlying data has changed. pending.clear(); + partialParse = false; // Reset the collision tile so we have a clean slate; we're placing all features anyway. collisionTile = std::make_unique<CollisionTile>(config); @@ -99,15 +97,6 @@ void TileWorker::redoPlacement( } } -template <typename T> -void applyLayoutProperty(PropertyKey key, const ClassProperties &classProperties, T &target, const StyleCalculationParameters& parameters) { - auto it = classProperties.properties.find(key); - if (it != classProperties.properties.end()) { - const PropertyEvaluator<T> evaluator(parameters); - target = mapbox::util::apply_visitor(evaluator, it->second); - } -} - void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometryTile) { // Cancel early when parsing. if (state == TileData::State::obsolete) @@ -135,145 +124,23 @@ void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometr return; } - switch (layer.type) { - case StyleLayerType::Fill: - createFillBucket(*geometryLayer, layer); - break; - case StyleLayerType::Line: - createLineBucket(*geometryLayer, layer); - break; - case StyleLayerType::Circle: - createCircleBucket(*geometryLayer, layer); - break; - case StyleLayerType::Symbol: - createSymbolBucket(*geometryLayer, layer); - break; - case StyleLayerType::Raster: - break; - default: - Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')", - layer.id.c_str(), layer.sourceLayer.c_str()); - } -} - -template <class Bucket> -void TileWorker::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& layer, const FilterExpression &filter) { - for (std::size_t i = 0; i < layer.featureCount(); i++) { - auto feature = layer.getFeature(i); - - if (state == TileData::State::obsolete) - return; - - GeometryTileFeatureExtractor extractor(*feature); - if (!evaluate(filter, extractor)) - continue; - - bucket->addGeometry(feature->getGeometries()); - } -} - -void TileWorker::createFillBucket(const GeometryTileLayer& tileLayer, - const StyleLayer& layer) { - auto bucket = std::make_unique<FillBucket>(); - - // Fill does not have layout properties to apply. - - addBucketGeometries(bucket, tileLayer, layer.filter); - - insertBucket(layer.bucketName(), std::move(bucket)); -} - -void TileWorker::createLineBucket(const GeometryTileLayer& tileLayer, - const StyleLayer& layer) { - auto bucket = std::make_unique<LineBucket>(); + StyleBucketParameters parameters(id, + *geometryLayer, + state, + reinterpret_cast<uintptr_t>(this), + partialParse, + *style.spriteAtlas, + *style.sprite, + *style.glyphAtlas, + *style.glyphStore, + *collisionTile); - const float z = id.z; - auto& layout = bucket->layout; + std::unique_ptr<Bucket> bucket = layer.createBucket(parameters); - applyLayoutProperty(PropertyKey::LineCap, layer.layout, layout.cap, z); - applyLayoutProperty(PropertyKey::LineJoin, layer.layout, layout.join, z); - applyLayoutProperty(PropertyKey::LineMiterLimit, layer.layout, layout.miter_limit, z); - applyLayoutProperty(PropertyKey::LineRoundLimit, layer.layout, layout.round_limit, z); - - addBucketGeometries(bucket, tileLayer, layer.filter); - - insertBucket(layer.bucketName(), std::move(bucket)); -} - -void TileWorker::createCircleBucket(const GeometryTileLayer& tileLayer, - const StyleLayer& layer) { - auto bucket = std::make_unique<CircleBucket>(); - - // Circle does not have layout properties to apply. - - addBucketGeometries(bucket, tileLayer, layer.filter); - - insertBucket(layer.bucketName(), std::move(bucket)); -} - -void TileWorker::createSymbolBucket(const GeometryTileLayer& tileLayer, - const StyleLayer& layer) { - auto bucket = std::make_unique<SymbolBucket>(id.overscaling, id.z); - - const float z = id.z; - auto& layout = bucket->layout; - - applyLayoutProperty(PropertyKey::SymbolPlacement, layer.layout, layout.placement, z); - if (layout.placement == PlacementType::Line) { - layout.icon.rotation_alignment = RotationAlignmentType::Map; - layout.text.rotation_alignment = RotationAlignmentType::Map; - }; - applyLayoutProperty(PropertyKey::SymbolSpacing, layer.layout, layout.spacing, z); - applyLayoutProperty(PropertyKey::SymbolAvoidEdges, layer.layout, layout.avoid_edges, z); - - applyLayoutProperty(PropertyKey::IconAllowOverlap, layer.layout, layout.icon.allow_overlap, z); - applyLayoutProperty(PropertyKey::IconIgnorePlacement, layer.layout, layout.icon.ignore_placement, z); - applyLayoutProperty(PropertyKey::IconOptional, layer.layout, layout.icon.optional, z); - applyLayoutProperty(PropertyKey::IconRotationAlignment, layer.layout, layout.icon.rotation_alignment, z); - applyLayoutProperty(PropertyKey::IconImage, layer.layout, layout.icon.image, z); - applyLayoutProperty(PropertyKey::IconPadding, layer.layout, layout.icon.padding, z); - applyLayoutProperty(PropertyKey::IconRotate, layer.layout, layout.icon.rotate, z); - applyLayoutProperty(PropertyKey::IconKeepUpright, layer.layout, layout.icon.keep_upright, z); - applyLayoutProperty(PropertyKey::IconOffset, layer.layout, layout.icon.offset, z); - - applyLayoutProperty(PropertyKey::TextRotationAlignment, layer.layout, layout.text.rotation_alignment, z); - applyLayoutProperty(PropertyKey::TextField, layer.layout, layout.text.field, z); - applyLayoutProperty(PropertyKey::TextFont, layer.layout, layout.text.font, z); - applyLayoutProperty(PropertyKey::TextMaxWidth, layer.layout, layout.text.max_width, z); - applyLayoutProperty(PropertyKey::TextLineHeight, layer.layout, layout.text.line_height, z); - applyLayoutProperty(PropertyKey::TextLetterSpacing, layer.layout, layout.text.letter_spacing, z); - applyLayoutProperty(PropertyKey::TextMaxAngle, layer.layout, layout.text.max_angle, z); - applyLayoutProperty(PropertyKey::TextRotate, layer.layout, layout.text.rotate, z); - applyLayoutProperty(PropertyKey::TextPadding, layer.layout, layout.text.padding, z); - applyLayoutProperty(PropertyKey::TextIgnorePlacement, layer.layout, layout.text.ignore_placement, z); - applyLayoutProperty(PropertyKey::TextOptional, layer.layout, layout.text.optional, z); - applyLayoutProperty(PropertyKey::TextJustify, layer.layout, layout.text.justify, z); - applyLayoutProperty(PropertyKey::TextAnchor, layer.layout, layout.text.anchor, z); - applyLayoutProperty(PropertyKey::TextKeepUpright, layer.layout, layout.text.keep_upright, z); - applyLayoutProperty(PropertyKey::TextTransform, layer.layout, layout.text.transform, z); - applyLayoutProperty(PropertyKey::TextOffset, layer.layout, layout.text.offset, z); - applyLayoutProperty(PropertyKey::TextAllowOverlap, layer.layout, layout.text.allow_overlap, z); - - applyLayoutProperty(PropertyKey::IconSize, layer.layout, layout.icon.size, z + 1); - applyLayoutProperty(PropertyKey::IconSize, layer.layout, layout.icon.max_size, 18); - applyLayoutProperty(PropertyKey::TextSize, layer.layout, layout.text.size, z + 1); - applyLayoutProperty(PropertyKey::TextSize, layer.layout, layout.text.max_size, 18); - - bucket->parseFeatures(tileLayer, layer.filter); - - assert(style.glyphStore); - assert(style.sprite); - const bool needsDependencies = bucket->needsDependencies(*style.glyphStore, *style.sprite); - if (needsDependencies) { + if (layer.type == StyleLayerType::Symbol && partialParse) { // We cannot parse this bucket yet. Instead, we're saving it for later. pending.emplace_back(layer, std::move(bucket)); } else { - assert(style.spriteAtlas); - assert(style.glyphAtlas); - assert(style.glyphStore); - assert(collisionTile); - bucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas, - *style.glyphAtlas, *style.glyphStore, *collisionTile); insertBucket(layer.bucketName(), std::move(bucket)); } } diff --git a/src/mbgl/map/tile_worker.hpp b/src/mbgl/map/tile_worker.hpp index be07488aea..ee94f756ed 100644 --- a/src/mbgl/map/tile_worker.hpp +++ b/src/mbgl/map/tile_worker.hpp @@ -6,8 +6,6 @@ #include <mbgl/map/tile_data.hpp> #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/ptr.hpp> -#include <mbgl/style/filter_expression.hpp> -#include <mbgl/style/style_calculation_parameters.hpp> #include <mbgl/text/placement_config.hpp> #include <string> @@ -23,7 +21,6 @@ class GeometryTile; class Style; class Bucket; class StyleLayer; -class GeometryTileLayer; // We're using this class to shuttle the resulting buckets from the worker thread to the MapContext // thread. This class is movable-only because the vector contains movable-only value elements. @@ -56,24 +53,16 @@ public: private: void parseLayer(const StyleLayer&, const GeometryTile&); - - void createFillBucket(const GeometryTileLayer&, const StyleLayer&); - void createLineBucket(const GeometryTileLayer&, const StyleLayer&); - void createCircleBucket(const GeometryTileLayer&, const StyleLayer&); - void createSymbolBucket(const GeometryTileLayer&, const StyleLayer&); - void insertBucket(const std::string& name, std::unique_ptr<Bucket>); - template <class Bucket> - void addBucketGeometries(Bucket&, const GeometryTileLayer&, const FilterExpression&); - const TileID id; const std::string sourceID; - const StyleCalculationParameters parameters; Style& style; const std::atomic<TileData::State>& state; + bool partialParse = false; + std::unique_ptr<CollisionTile> collisionTile; // Contains buckets that we couldn't parse so far due to missing resources. diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index 9e89c88135..bfe715a157 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -21,7 +21,7 @@ class CollisionTile; class Bucket : private util::noncopyable { public: Bucket() : uploaded(false) {} - + // 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() = 0; diff --git a/src/mbgl/style/class_properties.hpp b/src/mbgl/style/class_properties.hpp index d115f14d50..84b91d769e 100644 --- a/src/mbgl/style/class_properties.hpp +++ b/src/mbgl/style/class_properties.hpp @@ -3,6 +3,7 @@ #include <mbgl/style/property_key.hpp> #include <mbgl/style/property_value.hpp> +#include <mbgl/style/property_evaluator.hpp> #include <mbgl/style/property_transition.hpp> #include <map> @@ -29,6 +30,15 @@ public: return properties.end(); } + template <typename T> + void calculate(PropertyKey key, T& target, const float z) const { + auto it = properties.find(key); + if (it != properties.end()) { + const PropertyEvaluator<T> evaluator(z); + target = mapbox::util::apply_visitor(evaluator, it->second); + } + } + public: std::map<PropertyKey, PropertyValue> properties; std::map<PropertyKey, PropertyTransition> transitions; diff --git a/src/mbgl/style/style_bucket_parameters.cpp b/src/mbgl/style/style_bucket_parameters.cpp new file mode 100644 index 0000000000..1f9b5ab1c0 --- /dev/null +++ b/src/mbgl/style/style_bucket_parameters.cpp @@ -0,0 +1,19 @@ +#include <mbgl/style/style_bucket_parameters.hpp> +#include <mbgl/map/geometry_tile.hpp> + +namespace mbgl { + +void StyleBucketParameters::eachFilteredFeature(const FilterExpression& filter, + std::function<void (const GeometryTileFeature&)> function) { + for (std::size_t i = 0; !cancelled() && i < layer.featureCount(); i++) { + auto feature = layer.getFeature(i); + + GeometryTileFeatureExtractor extractor(*feature); + if (!evaluate(filter, extractor)) + continue; + + function(*feature); + } +} + +} diff --git a/src/mbgl/style/style_bucket_parameters.hpp b/src/mbgl/style/style_bucket_parameters.hpp new file mode 100644 index 0000000000..8328e254ca --- /dev/null +++ b/src/mbgl/style/style_bucket_parameters.hpp @@ -0,0 +1,63 @@ +#ifndef STYLE_BUCKET_PARAMETERS +#define STYLE_BUCKET_PARAMETERS + +#include <mbgl/style/filter_expression.hpp> +#include <mbgl/map/tile_data.hpp> + +#include <functional> + +namespace mbgl { + +class TileID; +class GeometryTileLayer; +class GeometryTileFeature; +class SpriteAtlas; +class Sprite; +class GlyphAtlas; +class GlyphStore; +class CollisionTile; + +class StyleBucketParameters { +public: + StyleBucketParameters(const TileID& tileID_, + const GeometryTileLayer& layer_, + const std::atomic<TileData::State>& state_, + uintptr_t tileUID_, + bool& partialParse_, + SpriteAtlas& spriteAtlas_, + Sprite& sprite_, + GlyphAtlas& glyphAtlas_, + GlyphStore& glyphStore_, + CollisionTile& collisionTile_) + : tileID(tileID_), + layer(layer_), + state(state_), + tileUID(tileUID_), + partialParse(partialParse_), + spriteAtlas(spriteAtlas_), + sprite(sprite_), + glyphAtlas(glyphAtlas_), + glyphStore(glyphStore_), + collisionTile(collisionTile_) {} + + bool cancelled() const { + return state == TileData::State::obsolete; + } + + void eachFilteredFeature(const FilterExpression&, std::function<void (const GeometryTileFeature&)>); + + const TileID& tileID; + const GeometryTileLayer& layer; + const std::atomic<TileData::State>& state; + uintptr_t tileUID; + bool& partialParse; + SpriteAtlas& spriteAtlas; + Sprite& sprite; + GlyphAtlas& glyphAtlas; + GlyphStore& glyphStore; + CollisionTile& collisionTile; +}; + +} + +#endif diff --git a/src/mbgl/style/style_layer.hpp b/src/mbgl/style/style_layer.hpp index 8ab41c6a6d..191c239a1f 100644 --- a/src/mbgl/style/style_layer.hpp +++ b/src/mbgl/style/style_layer.hpp @@ -7,6 +7,7 @@ #include <mbgl/style/paint_properties_map.hpp> #include <mbgl/renderer/render_pass.hpp> +#include <mbgl/map/tile_data.hpp> #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/chrono.hpp> @@ -20,6 +21,7 @@ namespace mbgl { class StyleCalculationParameters; +class StyleBucketParameters; class PropertyTransition; using JSVal = rapidjson::Value; @@ -44,6 +46,8 @@ public: // Fully evaluate cascaded paint properties based on a zoom level. virtual void recalculate(const StyleCalculationParameters&) = 0; + virtual std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const = 0; + // Checks whether this layer has any active paint properties with transitions. bool hasTransitions() const; |