From d596d9dc381170013563348b7af46812f6fcf790 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 4 Jun 2015 19:58:43 -0700 Subject: [PATCH] Clean up bucket creation loop --- src/mbgl/map/tile_worker.cpp | 122 ++++++++++++++++------------------- src/mbgl/map/tile_worker.hpp | 13 ++-- 2 files changed, 62 insertions(+), 73 deletions(-) diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp index ae291b04e..b69698689 100644 --- a/src/mbgl/map/tile_worker.cpp +++ b/src/mbgl/map/tile_worker.cpp @@ -28,18 +28,6 @@ TileWorker::~TileWorker() { style.glyphAtlas->removeGlyphs(reinterpret_cast(this)); } -void TileWorker::setBucket(const StyleLayer& layer, std::unique_ptr bucket) { - assert(layer.bucket); - - std::lock_guard lock(bucketsMutex); - - if (buckets.find(layer.bucket->name) != buckets.end()) { - return; - } - - buckets[layer.bucket->name] = std::move(bucket); -} - Bucket* TileWorker::getBucket(const StyleLayer& layer) const { std::lock_guard lock(bucketsMutex); @@ -60,40 +48,11 @@ size_t TileWorker::countBuckets() const { TileParseResult TileWorker::parse(const GeometryTile& geometryTile) { partialParse = false; - for (const auto& layer_desc : style.layers) { - // Cancel early when parsing. - if (state == TileData::State::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 = 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()); - } + for (const auto& layer : style.layers) { + parseLayer(*layer, geometryTile); } - if (partialParse) { - return TileData::State::partial; - } else { - return TileData::State::parsed; - } + return partialParse ? TileData::State::partial : TileData::State::parsed; } void TileWorker::redoPlacement(float angle, bool collisionDebug) { @@ -139,35 +98,66 @@ void applyLayoutProperty(PropertyKey key, const ClassProperties &classProperties } } -std::unique_ptr 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; +void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometryTile) { + // Cancel early when parsing. + if (state == TileData::State::obsolete) + return; - 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 { + // Background is a special case. + if (layer.isBackground()) + return; + + if (!layer.bucket) { + Log::Warning(Event::ParseTile, "layer '%s' does not have buckets", layer.id.c_str()); + return; + } + + // This is a singular layer. Check if this bucket already exists. + if (getBucket(layer)) + return; + + const StyleBucket& styleBucket = *layer.bucket; + + // Skip this bucket if we are to not render this + if (id.z < std::floor(styleBucket.min_zoom) && std::floor(styleBucket.min_zoom) < maxZoom) + return; + if (id.z >= std::ceil(styleBucket.max_zoom)) + return; + if (styleBucket.visibility == mbgl::VisibilityType::None) + return; + + auto geometryLayer = geometryTile.getLayer(styleBucket.source_layer); + if (!geometryLayer) { // 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); + styleBucket.source_layer.c_str(), id.z, id.x, id.y); } + return; } - return nullptr; + std::unique_ptr bucket; + + if (styleBucket.type == StyleLayerType::Fill) { + bucket = createFillBucket(*geometryLayer, styleBucket); + } else if (styleBucket.type == StyleLayerType::Line) { + bucket = createLineBucket(*geometryLayer, styleBucket); + } else if (styleBucket.type == StyleLayerType::Symbol) { + bucket = createSymbolBucket(*geometryLayer, styleBucket); + } else if (styleBucket.type == StyleLayerType::Raster) { + return; + } else { + Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')", + styleBucket.name.c_str(), styleBucket.source_layer.c_str()); + } + + // Bucket creation might fail because the data tile may not + // contain any data that falls into this bucket. + if (!bucket) + return; + + std::lock_guard lock(bucketsMutex); + buckets[styleBucket.name] = std::move(bucket); } template diff --git a/src/mbgl/map/tile_worker.hpp b/src/mbgl/map/tile_worker.hpp index ae97e08cb..7fb474a5e 100644 --- a/src/mbgl/map/tile_worker.hpp +++ b/src/mbgl/map/tile_worker.hpp @@ -36,7 +36,6 @@ public: std::unique_ptr); ~TileWorker(); - void setBucket(const StyleLayer&, std::unique_ptr); Bucket* getBucket(const StyleLayer&) const; size_t countBuckets() const; @@ -46,7 +45,8 @@ public: Style& style; private: - std::unique_ptr createBucket(const StyleBucket&, const GeometryTile&); + void parseLayer(const StyleLayer&, const GeometryTile&); + std::unique_ptr createFillBucket(const GeometryTileLayer&, const StyleBucket&); std::unique_ptr createLineBucket(const GeometryTileLayer&, const StyleBucket&); std::unique_ptr createSymbolBucket(const GeometryTileLayer&, const StyleBucket&); @@ -69,11 +69,10 @@ private: std::unique_ptr collision; // Contains all the Bucket objects for the tile. Buckets are render - // objects and they get added to this std::map<> by the workers doing - // the actual tile parsing as they get processed. Tiles partially - // parsed can get new buckets at any moment but are also fit for - // rendering. That said, access to this list needs locking unless - // the tile is completely parsed. + // objects and they get added to this map as they get processed. + // Tiles partially parsed can get new buckets at any moment but are + // also fit for rendering. That said, access to this list needs locking + // unless the tile is completely parsed. std::unordered_map> buckets; mutable std::mutex bucketsMutex; };