summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-10-20 15:05:06 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-10-30 11:19:28 -0700
commitddc4251074dae9115d6e252099ec04995188e29a (patch)
tree654c626ed9329edc3c85848aac1b3259db690272 /src
parent540c6eca1544dd9617a7a19ffa9d396ed96df4ec (diff)
downloadqtlocation-mapboxgl-ddc4251074dae9115d6e252099ec04995188e29a.tar.gz
[core] Polymorphic bucket creation
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/layer/background_layer.cpp4
-rw-r--r--src/mbgl/layer/background_layer.hpp2
-rw-r--r--src/mbgl/layer/circle_layer.cpp12
-rw-r--r--src/mbgl/layer/circle_layer.hpp2
-rw-r--r--src/mbgl/layer/fill_layer.cpp12
-rw-r--r--src/mbgl/layer/fill_layer.hpp2
-rw-r--r--src/mbgl/layer/line_layer.cpp19
-rw-r--r--src/mbgl/layer/line_layer.hpp2
-rw-r--r--src/mbgl/layer/raster_layer.cpp5
-rw-r--r--src/mbgl/layer/raster_layer.hpp2
-rw-r--r--src/mbgl/layer/symbol_layer.cpp69
-rw-r--r--src/mbgl/layer/symbol_layer.hpp2
-rw-r--r--src/mbgl/map/tile_worker.cpp163
-rw-r--r--src/mbgl/map/tile_worker.hpp15
-rw-r--r--src/mbgl/renderer/bucket.hpp2
-rw-r--r--src/mbgl/style/class_properties.hpp10
-rw-r--r--src/mbgl/style/style_bucket_parameters.cpp19
-rw-r--r--src/mbgl/style/style_bucket_parameters.hpp63
-rw-r--r--src/mbgl/style/style_layer.hpp4
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;