summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-06-04 19:32:07 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-07-01 15:21:09 -0700
commit4676553a3e31bef3094e8be5d6f9dce2809ef5ae (patch)
tree2ef00b7c7db4a6a83fb02569a0e7a857b82694c7 /src
parent875ef979be0140332ab219e422022ccb38b99a1e (diff)
downloadqtlocation-mapboxgl-4676553a3e31bef3094e8be5d6f9dce2809ef5ae.tar.gz
Merge TileParser into TileWorker
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/tile_parser.cpp235
-rw-r--r--src/mbgl/map/tile_parser.hpp62
-rw-r--r--src/mbgl/map/tile_worker.cpp218
-rw-r--r--src/mbgl/map/tile_worker.hpp24
4 files changed, 232 insertions, 307 deletions
diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp
deleted file mode 100644
index a88084391f..0000000000
--- a/src/mbgl/map/tile_parser.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-#include <mbgl/map/tile_parser.hpp>
-#include <mbgl/map/vector_tile_data.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/style/style_layer.hpp>
-#include <mbgl/map/source.hpp>
-#include <mbgl/map/sprite.hpp>
-#include <mbgl/renderer/fill_bucket.hpp>
-#include <mbgl/renderer/line_bucket.hpp>
-#include <mbgl/renderer/symbol_bucket.hpp>
-#include <mbgl/util/constants.hpp>
-#include <mbgl/style/style.hpp>
-
-#include <locale>
-
-namespace mbgl {
-
-// Note: This destructor is seemingly empty, but we need to declare it anyway
-// because this object has a std::unique_ptr<> of a forward-declare type in
-// its header file.
-TileParser::~TileParser() = default;
-
-TileParser::TileParser(const GeometryTile& geometryTile_,
- TileWorker& tile_,
- Style& style_)
- : geometryTile(geometryTile_),
- tile(tile_),
- style(style_),
- partialParse(false) {
- assert(style.sprite);
-}
-
-bool TileParser::obsolete() const {
- return tile.getState() == TileData::State::obsolete;
-}
-
-void TileParser::parse() {
- for (const auto& layer_desc : style.layers) {
- // Cancel early when parsing.
- if (obsolete()) {
- return;
- }
-
- if (layer_desc->isBackground()) {
- // background is a special, fake bucket
- continue;
- }
-
- if (layer_desc->bucket) {
- // This is a singular layer. Check if this bucket already exists. If not,
- // parse this bucket.
- if (tile.getBucket(*layer_desc)) {
- continue;
- }
-
- std::unique_ptr<Bucket> bucket = createBucket(*layer_desc->bucket);
- if (bucket) {
- // Bucket creation might fail because the data tile may not
- // contain any data that falls into this bucket.
- tile.setBucket(*layer_desc, std::move(bucket));
- }
- } else {
- Log::Warning(Event::ParseTile, "layer '%s' does not have buckets", layer_desc->id.c_str());
- }
- }
-}
-
-template <typename T>
-struct PropertyEvaluator {
- typedef T result_type;
- PropertyEvaluator(float z_) : z(z_) {}
-
- template <typename P, typename std::enable_if<std::is_convertible<P, T>::value, int>::type = 0>
- T operator()(const P &value) const {
- return value;
- }
-
- T operator()(const Function<T> &value) const {
- return mapbox::util::apply_visitor(FunctionEvaluator<T>(z), value);
- }
-
- template <typename P, typename std::enable_if<!std::is_convertible<P, T>::value, int>::type = 0>
- T operator()(const P &) const {
- return T();
- }
-
-private:
- const float z;
-};
-
-template <typename T>
-void applyLayoutProperty(PropertyKey key, const ClassProperties &classProperties, T &target, const float z) {
- auto it = classProperties.properties.find(key);
- if (it != classProperties.properties.end()) {
- const PropertyEvaluator<T> evaluator(z);
- target = mapbox::util::apply_visitor(evaluator, it->second);
- }
-}
-
-std::unique_ptr<Bucket> TileParser::createBucket(const StyleBucket &bucketDesc) {
- // Skip this bucket if we are to not render this
- if (tile.id.z < std::floor(bucketDesc.min_zoom) && std::floor(bucketDesc.min_zoom) < tile.maxZoom) return nullptr;
- if (tile.id.z >= std::ceil(bucketDesc.max_zoom)) return nullptr;
- if (bucketDesc.visibility == mbgl::VisibilityType::None) return nullptr;
-
- auto layer = geometryTile.getLayer(bucketDesc.source_layer);
- if (layer) {
- if (bucketDesc.type == StyleLayerType::Fill) {
- return createFillBucket(*layer, bucketDesc);
- } else if (bucketDesc.type == StyleLayerType::Line) {
- return createLineBucket(*layer, bucketDesc);
- } else if (bucketDesc.type == StyleLayerType::Symbol) {
- return createSymbolBucket(*layer, bucketDesc);
- } else if (bucketDesc.type == StyleLayerType::Raster) {
- return nullptr;
- } else {
- Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')",
- bucketDesc.name.c_str(), bucketDesc.source_layer.c_str());
- }
- } else {
- // The layer specified in the bucket does not exist. Do nothing.
- if (debug::tileParseWarnings) {
- Log::Warning(Event::ParseTile, "layer '%s' does not exist in tile %d/%d/%d",
- bucketDesc.source_layer.c_str(), tile.id.z, tile.id.x, tile.id.y);
- }
- }
-
- return nullptr;
-}
-
-template <class Bucket>
-void TileParser::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 (obsolete())
- return;
-
- GeometryTileFeatureExtractor extractor(*feature);
- if (!evaluate(filter, extractor))
- continue;
-
- bucket->addGeometry(feature->getGeometries());
- }
-}
-
-std::unique_ptr<Bucket> TileParser::createFillBucket(const GeometryTileLayer& layer,
- const StyleBucket& bucket_desc) {
- auto bucket = std::make_unique<FillBucket>(tile.fillVertexBuffer,
- tile.triangleElementsBuffer,
- tile.lineElementsBuffer);
- addBucketGeometries(bucket, layer, bucket_desc.filter);
- return bucket->hasData() ? std::move(bucket) : nullptr;
-}
-
-std::unique_ptr<Bucket> TileParser::createLineBucket(const GeometryTileLayer& layer,
- const StyleBucket& bucket_desc) {
- auto bucket = std::make_unique<LineBucket>(tile.lineVertexBuffer,
- tile.triangleElementsBuffer);
-
- const float z = tile.id.z;
- auto& layout = bucket->layout;
-
- applyLayoutProperty(PropertyKey::LineCap, bucket_desc.layout, layout.cap, z);
- applyLayoutProperty(PropertyKey::LineJoin, bucket_desc.layout, layout.join, z);
- applyLayoutProperty(PropertyKey::LineMiterLimit, bucket_desc.layout, layout.miter_limit, z);
- applyLayoutProperty(PropertyKey::LineRoundLimit, bucket_desc.layout, layout.round_limit, z);
-
- addBucketGeometries(bucket, layer, bucket_desc.filter);
- return bucket->hasData() ? std::move(bucket) : nullptr;
-}
-
-std::unique_ptr<Bucket> TileParser::createSymbolBucket(const GeometryTileLayer& layer,
- const StyleBucket& bucket_desc) {
- auto bucket = std::make_unique<SymbolBucket>(*tile.getCollision(), tile.id.overscaling);
-
- const float z = tile.id.z;
- auto& layout = bucket->layout;
-
- applyLayoutProperty(PropertyKey::SymbolPlacement, bucket_desc.layout, layout.placement, z);
- if (layout.placement == PlacementType::Line) {
- layout.icon.rotation_alignment = RotationAlignmentType::Map;
- layout.text.rotation_alignment = RotationAlignmentType::Map;
- };
- applyLayoutProperty(PropertyKey::SymbolMinDistance, bucket_desc.layout, layout.min_distance, z);
- applyLayoutProperty(PropertyKey::SymbolAvoidEdges, bucket_desc.layout, layout.avoid_edges, z);
-
- applyLayoutProperty(PropertyKey::IconAllowOverlap, bucket_desc.layout, layout.icon.allow_overlap, z);
- applyLayoutProperty(PropertyKey::IconIgnorePlacement, bucket_desc.layout, layout.icon.ignore_placement, z);
- applyLayoutProperty(PropertyKey::IconOptional, bucket_desc.layout, layout.icon.optional, z);
- applyLayoutProperty(PropertyKey::IconRotationAlignment, bucket_desc.layout, layout.icon.rotation_alignment, z);
- applyLayoutProperty(PropertyKey::IconMaxSize, bucket_desc.layout, layout.icon.max_size, z);
- applyLayoutProperty(PropertyKey::IconImage, bucket_desc.layout, layout.icon.image, z);
- applyLayoutProperty(PropertyKey::IconPadding, bucket_desc.layout, layout.icon.padding, z);
- applyLayoutProperty(PropertyKey::IconRotate, bucket_desc.layout, layout.icon.rotate, z);
- applyLayoutProperty(PropertyKey::IconKeepUpright, bucket_desc.layout, layout.icon.keep_upright, z);
- applyLayoutProperty(PropertyKey::IconOffset, bucket_desc.layout, layout.icon.offset, z);
-
- applyLayoutProperty(PropertyKey::TextRotationAlignment, bucket_desc.layout, layout.text.rotation_alignment, z);
- applyLayoutProperty(PropertyKey::TextField, bucket_desc.layout, layout.text.field, z);
- applyLayoutProperty(PropertyKey::TextFont, bucket_desc.layout, layout.text.font, z);
- applyLayoutProperty(PropertyKey::TextMaxSize, bucket_desc.layout, layout.text.max_size, z);
- applyLayoutProperty(PropertyKey::TextMaxWidth, bucket_desc.layout, layout.text.max_width, z);
- applyLayoutProperty(PropertyKey::TextLineHeight, bucket_desc.layout, layout.text.line_height, z);
- applyLayoutProperty(PropertyKey::TextLetterSpacing, bucket_desc.layout, layout.text.letter_spacing, z);
- applyLayoutProperty(PropertyKey::TextMaxAngle, bucket_desc.layout, layout.text.max_angle, z);
- applyLayoutProperty(PropertyKey::TextRotate, bucket_desc.layout, layout.text.rotate, z);
- applyLayoutProperty(PropertyKey::TextPadding, bucket_desc.layout, layout.text.padding, z);
- applyLayoutProperty(PropertyKey::TextIgnorePlacement, bucket_desc.layout, layout.text.ignore_placement, z);
- applyLayoutProperty(PropertyKey::TextOptional, bucket_desc.layout, layout.text.optional, z);
- applyLayoutProperty(PropertyKey::TextJustify, bucket_desc.layout, layout.text.justify, z);
- applyLayoutProperty(PropertyKey::TextAnchor, bucket_desc.layout, layout.text.anchor, z);
- applyLayoutProperty(PropertyKey::TextKeepUpright, bucket_desc.layout, layout.text.keep_upright, z);
- applyLayoutProperty(PropertyKey::TextTransform, bucket_desc.layout, layout.text.transform, z);
- applyLayoutProperty(PropertyKey::TextOffset, bucket_desc.layout, layout.text.offset, z);
- applyLayoutProperty(PropertyKey::TextAllowOverlap, bucket_desc.layout, layout.text.allow_overlap, z);
-
- if (bucket->needsDependencies(layer, bucket_desc.filter, *style.glyphStore, *style.sprite)) {
- partialParse = true;
- }
-
- // We do not proceed 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 (partialParse) {
- return nullptr;
- }
-
- bucket->addFeatures(
- reinterpret_cast<uintptr_t>(&tile), *style.spriteAtlas, *style.sprite, *style.glyphAtlas, *style.glyphStore);
-
- return bucket->hasData() ? std::move(bucket) : nullptr;
-}
-
-}
diff --git a/src/mbgl/map/tile_parser.hpp b/src/mbgl/map/tile_parser.hpp
deleted file mode 100644
index 63c1fd72aa..0000000000
--- a/src/mbgl/map/tile_parser.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef MBGL_MAP_TILE_PARSER
-#define MBGL_MAP_TILE_PARSER
-
-#include <mbgl/map/geometry_tile.hpp>
-#include <mbgl/map/vector_tile.hpp>
-#include <mbgl/style/filter_expression.hpp>
-#include <mbgl/style/class_properties.hpp>
-#include <mbgl/style/style_bucket.hpp>
-#include <mbgl/text/glyph.hpp>
-#include <mbgl/util/ptr.hpp>
-#include <mbgl/util/noncopyable.hpp>
-
-#include <cstdint>
-#include <iosfwd>
-#include <string>
-
-namespace mbgl {
-
-class Bucket;
-class FontStack;
-class Style;
-class StyleBucket;
-class StyleLayoutFill;
-class StyleLayoutRaster;
-class StyleLayoutLine;
-class StyleLayoutSymbol;
-class TileWorker;
-
-class TileParser : private util::noncopyable {
-public:
- TileParser(const GeometryTile&, TileWorker&, Style&);
- ~TileParser();
-
-public:
- void parse();
- inline bool isPartialParse() const {
- return partialParse;
- }
-
-private:
- bool obsolete() const;
-
- std::unique_ptr<Bucket> createBucket(const StyleBucket&);
- std::unique_ptr<Bucket> createFillBucket(const GeometryTileLayer&, const StyleBucket&);
- std::unique_ptr<Bucket> createLineBucket(const GeometryTileLayer&, const StyleBucket&);
- std::unique_ptr<Bucket> createSymbolBucket(const GeometryTileLayer&, const StyleBucket&);
-
- template <class Bucket>
- void addBucketGeometries(Bucket&, const GeometryTileLayer&, const FilterExpression&);
-
- const GeometryTile& geometryTile;
- TileWorker& tile;
-
- // Cross-thread shared data.
- Style& style;
-
- bool partialParse;
-};
-
-}
-
-#endif
diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp
index 1991ab1885..a70e5a772f 100644
--- a/src/mbgl/map/tile_worker.cpp
+++ b/src/mbgl/map/tile_worker.cpp
@@ -1,9 +1,13 @@
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/map/tile_worker.hpp>
-#include <mbgl/map/tile_parser.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/geometry/glyph_atlas.hpp>
+#include <mbgl/renderer/fill_bucket.hpp>
+#include <mbgl/renderer/line_bucket.hpp>
+#include <mbgl/renderer/symbol_bucket.hpp>
+#include <mbgl/platform/log.hpp>
+#include <mbgl/util/constants.hpp>
using namespace mbgl;
@@ -12,11 +16,12 @@ TileWorker::TileWorker(const TileID& id_,
const uint16_t maxZoom_,
const std::atomic<TileData::State>& state_,
std::unique_ptr<CollisionTile> collision_)
- : id(id_),
- style(style_),
+ : style(style_),
+ id(id_),
maxZoom(maxZoom_),
state(state_),
collision(std::move(collision_)) {
+ assert(style.sprite);
}
TileWorker::~TileWorker() {
@@ -53,13 +58,36 @@ size_t TileWorker::countBuckets() const {
}
TileParseResult TileWorker::parse(const GeometryTile& geometryTile) {
- // Parsing creates state that is encapsulated in TileParser. While parsing,
- // the TileParser object writes results into this objects. All other state
- // is going to be discarded afterwards.
- TileParser parser(geometryTile, *this, style);
- parser.parse();
+ for (const auto& layer_desc : style.layers) {
+ // Cancel early when parsing.
+ if (obsolete()) {
+ return TileData::State::obsolete;
+ }
+
+ if (layer_desc->isBackground()) {
+ // background is a special, fake bucket
+ continue;
+ }
+
+ if (layer_desc->bucket) {
+ // This is a singular layer. Check if this bucket already exists. If not,
+ // parse this bucket.
+ if (getBucket(*layer_desc)) {
+ continue;
+ }
+
+ std::unique_ptr<Bucket> bucket = createBucket(*layer_desc->bucket, geometryTile);
+ if (bucket) {
+ // Bucket creation might fail because the data tile may not
+ // contain any data that falls into this bucket.
+ setBucket(*layer_desc, std::move(bucket));
+ }
+ } else {
+ Log::Warning(Event::ParseTile, "layer '%s' does not have buckets", layer_desc->id.c_str());
+ }
+ }
- if (parser.isPartialParse()) {
+ if (isPartialParse()) {
return TileData::State::partial;
} else {
return TileData::State::parsed;
@@ -76,3 +104,175 @@ void TileWorker::redoPlacement(float angle, bool collisionDebug) {
}
}
}
+
+bool TileWorker::obsolete() const {
+ return getState() == TileData::State::obsolete;
+}
+
+template <typename T>
+struct PropertyEvaluator {
+ typedef T result_type;
+ PropertyEvaluator(float z_) : z(z_) {}
+
+ template <typename P, typename std::enable_if<std::is_convertible<P, T>::value, int>::type = 0>
+ T operator()(const P &value) const {
+ return value;
+ }
+
+ T operator()(const Function<T> &value) const {
+ return mapbox::util::apply_visitor(FunctionEvaluator<T>(z), value);
+ }
+
+ template <typename P, typename std::enable_if<!std::is_convertible<P, T>::value, int>::type = 0>
+ T operator()(const P &) const {
+ return T();
+ }
+
+private:
+ const float z;
+};
+
+template <typename T>
+void applyLayoutProperty(PropertyKey key, const ClassProperties &classProperties, T &target, const float z) {
+ auto it = classProperties.properties.find(key);
+ if (it != classProperties.properties.end()) {
+ const PropertyEvaluator<T> evaluator(z);
+ target = mapbox::util::apply_visitor(evaluator, it->second);
+ }
+}
+
+std::unique_ptr<Bucket> TileWorker::createBucket(const StyleBucket& bucketDesc, const GeometryTile& geometryTile) {
+ // Skip this bucket if we are to not render this
+ if (id.z < std::floor(bucketDesc.min_zoom) && std::floor(bucketDesc.min_zoom) < maxZoom) return nullptr;
+ if (id.z >= std::ceil(bucketDesc.max_zoom)) return nullptr;
+ if (bucketDesc.visibility == mbgl::VisibilityType::None) return nullptr;
+
+ auto layer = geometryTile.getLayer(bucketDesc.source_layer);
+ if (layer) {
+ if (bucketDesc.type == StyleLayerType::Fill) {
+ return createFillBucket(*layer, bucketDesc);
+ } else if (bucketDesc.type == StyleLayerType::Line) {
+ return createLineBucket(*layer, bucketDesc);
+ } else if (bucketDesc.type == StyleLayerType::Symbol) {
+ return createSymbolBucket(*layer, bucketDesc);
+ } else if (bucketDesc.type == StyleLayerType::Raster) {
+ return nullptr;
+ } else {
+ Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')",
+ bucketDesc.name.c_str(), bucketDesc.source_layer.c_str());
+ }
+ } else {
+ // The layer specified in the bucket does not exist. Do nothing.
+ if (debug::tileParseWarnings) {
+ Log::Warning(Event::ParseTile, "layer '%s' does not exist in tile %d/%d/%d",
+ bucketDesc.source_layer.c_str(), id.z, id.x, id.y);
+ }
+ }
+
+ return nullptr;
+}
+
+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 (obsolete())
+ return;
+
+ GeometryTileFeatureExtractor extractor(*feature);
+ if (!evaluate(filter, extractor))
+ continue;
+
+ bucket->addGeometry(feature->getGeometries());
+ }
+}
+
+std::unique_ptr<Bucket> TileWorker::createFillBucket(const GeometryTileLayer& layer,
+ const StyleBucket& bucket_desc) {
+ auto bucket = std::make_unique<FillBucket>(fillVertexBuffer,
+ triangleElementsBuffer,
+ lineElementsBuffer);
+ addBucketGeometries(bucket, layer, bucket_desc.filter);
+ return bucket->hasData() ? std::move(bucket) : nullptr;
+}
+
+std::unique_ptr<Bucket> TileWorker::createLineBucket(const GeometryTileLayer& layer,
+ const StyleBucket& bucket_desc) {
+ auto bucket = std::make_unique<LineBucket>(lineVertexBuffer,
+ triangleElementsBuffer);
+
+ const float z = id.z;
+ auto& layout = bucket->layout;
+
+ applyLayoutProperty(PropertyKey::LineCap, bucket_desc.layout, layout.cap, z);
+ applyLayoutProperty(PropertyKey::LineJoin, bucket_desc.layout, layout.join, z);
+ applyLayoutProperty(PropertyKey::LineMiterLimit, bucket_desc.layout, layout.miter_limit, z);
+ applyLayoutProperty(PropertyKey::LineRoundLimit, bucket_desc.layout, layout.round_limit, z);
+
+ addBucketGeometries(bucket, layer, bucket_desc.filter);
+ return bucket->hasData() ? std::move(bucket) : nullptr;
+}
+
+std::unique_ptr<Bucket> TileWorker::createSymbolBucket(const GeometryTileLayer& layer,
+ const StyleBucket& bucket_desc) {
+ auto bucket = std::make_unique<SymbolBucket>(*getCollision(), id.overscaling);
+
+ const float z = id.z;
+ auto& layout = bucket->layout;
+
+ applyLayoutProperty(PropertyKey::SymbolPlacement, bucket_desc.layout, layout.placement, z);
+ if (layout.placement == PlacementType::Line) {
+ layout.icon.rotation_alignment = RotationAlignmentType::Map;
+ layout.text.rotation_alignment = RotationAlignmentType::Map;
+ };
+ applyLayoutProperty(PropertyKey::SymbolMinDistance, bucket_desc.layout, layout.min_distance, z);
+ applyLayoutProperty(PropertyKey::SymbolAvoidEdges, bucket_desc.layout, layout.avoid_edges, z);
+
+ applyLayoutProperty(PropertyKey::IconAllowOverlap, bucket_desc.layout, layout.icon.allow_overlap, z);
+ applyLayoutProperty(PropertyKey::IconIgnorePlacement, bucket_desc.layout, layout.icon.ignore_placement, z);
+ applyLayoutProperty(PropertyKey::IconOptional, bucket_desc.layout, layout.icon.optional, z);
+ applyLayoutProperty(PropertyKey::IconRotationAlignment, bucket_desc.layout, layout.icon.rotation_alignment, z);
+ applyLayoutProperty(PropertyKey::IconMaxSize, bucket_desc.layout, layout.icon.max_size, z);
+ applyLayoutProperty(PropertyKey::IconImage, bucket_desc.layout, layout.icon.image, z);
+ applyLayoutProperty(PropertyKey::IconPadding, bucket_desc.layout, layout.icon.padding, z);
+ applyLayoutProperty(PropertyKey::IconRotate, bucket_desc.layout, layout.icon.rotate, z);
+ applyLayoutProperty(PropertyKey::IconKeepUpright, bucket_desc.layout, layout.icon.keep_upright, z);
+ applyLayoutProperty(PropertyKey::IconOffset, bucket_desc.layout, layout.icon.offset, z);
+
+ applyLayoutProperty(PropertyKey::TextRotationAlignment, bucket_desc.layout, layout.text.rotation_alignment, z);
+ applyLayoutProperty(PropertyKey::TextField, bucket_desc.layout, layout.text.field, z);
+ applyLayoutProperty(PropertyKey::TextFont, bucket_desc.layout, layout.text.font, z);
+ applyLayoutProperty(PropertyKey::TextMaxSize, bucket_desc.layout, layout.text.max_size, z);
+ applyLayoutProperty(PropertyKey::TextMaxWidth, bucket_desc.layout, layout.text.max_width, z);
+ applyLayoutProperty(PropertyKey::TextLineHeight, bucket_desc.layout, layout.text.line_height, z);
+ applyLayoutProperty(PropertyKey::TextLetterSpacing, bucket_desc.layout, layout.text.letter_spacing, z);
+ applyLayoutProperty(PropertyKey::TextMaxAngle, bucket_desc.layout, layout.text.max_angle, z);
+ applyLayoutProperty(PropertyKey::TextRotate, bucket_desc.layout, layout.text.rotate, z);
+ applyLayoutProperty(PropertyKey::TextPadding, bucket_desc.layout, layout.text.padding, z);
+ applyLayoutProperty(PropertyKey::TextIgnorePlacement, bucket_desc.layout, layout.text.ignore_placement, z);
+ applyLayoutProperty(PropertyKey::TextOptional, bucket_desc.layout, layout.text.optional, z);
+ applyLayoutProperty(PropertyKey::TextJustify, bucket_desc.layout, layout.text.justify, z);
+ applyLayoutProperty(PropertyKey::TextAnchor, bucket_desc.layout, layout.text.anchor, z);
+ applyLayoutProperty(PropertyKey::TextKeepUpright, bucket_desc.layout, layout.text.keep_upright, z);
+ applyLayoutProperty(PropertyKey::TextTransform, bucket_desc.layout, layout.text.transform, z);
+ applyLayoutProperty(PropertyKey::TextOffset, bucket_desc.layout, layout.text.offset, z);
+ applyLayoutProperty(PropertyKey::TextAllowOverlap, bucket_desc.layout, layout.text.allow_overlap, z);
+
+ if (bucket->needsDependencies(layer, bucket_desc.filter, *style.glyphStore, *style.sprite)) {
+ partialParse = true;
+ }
+
+ // We do not proceed 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 (partialParse) {
+ return nullptr;
+ }
+
+ bucket->addFeatures(
+ reinterpret_cast<uintptr_t>(this), *style.spriteAtlas, *style.sprite, *style.glyphAtlas, *style.glyphStore);
+
+ return bucket->hasData() ? std::move(bucket) : nullptr;
+}
diff --git a/src/mbgl/map/tile_worker.hpp b/src/mbgl/map/tile_worker.hpp
index 420b0bf9f2..c3f131ccd4 100644
--- a/src/mbgl/map/tile_worker.hpp
+++ b/src/mbgl/map/tile_worker.hpp
@@ -7,7 +7,9 @@
#include <mbgl/geometry/fill_buffer.hpp>
#include <mbgl/geometry/line_buffer.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/style/filter_expression.hpp>
+#include <string>
#include <memory>
#include <mutex>
#include <unordered_map>
@@ -18,6 +20,8 @@ class CollisionTile;
class GeometryTile;
class Style;
class Bucket;
+class StyleBucket;
+class GeometryTileLayer;
using TileParseResult = mapbox::util::variant<
TileData::State, // success
@@ -44,14 +48,32 @@ public:
return collision.get();
}
+ inline bool isPartialParse() const {
+ return partialParse;
+ }
+
TileParseResult parse(const GeometryTile&);
void redoPlacement(float angle, bool collisionDebug);
- const TileID id;
Style& style;
+
+private:
+ bool obsolete() const;
+
+ std::unique_ptr<Bucket> createBucket(const StyleBucket&, const GeometryTile&);
+ std::unique_ptr<Bucket> createFillBucket(const GeometryTileLayer&, const StyleBucket&);
+ std::unique_ptr<Bucket> createLineBucket(const GeometryTileLayer&, const StyleBucket&);
+ std::unique_ptr<Bucket> createSymbolBucket(const GeometryTileLayer&, const StyleBucket&);
+
+ template <class Bucket>
+ void addBucketGeometries(Bucket&, const GeometryTileLayer&, const FilterExpression&);
+
+ const TileID id;
const uint16_t maxZoom;
const std::atomic<TileData::State>& state;
+ bool partialParse = false;
+
FillVertexBuffer fillVertexBuffer;
LineVertexBuffer lineVertexBuffer;