From 397bbfe495368408ff4758d5bb7308778aba175c Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 13 May 2015 16:25:40 +0300 Subject: [PATCH] Always request the SymbolBucket dependencies at the first pass When processing a layer, we request the dependencies of all the SymbolBuckets even if we are not processing it completely. By doing that we are now requesting glyphs in parallel instead of sequentially as we were doing before. This patch is also simplifying the SymbolBucket creation code by getting rid of the ugly "needsResources" return value passed by reference as argument. --- src/mbgl/map/tile_parser.cpp | 36 +++++++++++------------------ src/mbgl/map/tile_parser.hpp | 2 +- src/mbgl/renderer/symbol_bucket.cpp | 36 ++++++++++++----------------- src/mbgl/renderer/symbol_bucket.hpp | 19 +++++++-------- 4 files changed, 37 insertions(+), 56 deletions(-) diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index 388950491..a93245313 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -118,18 +118,7 @@ std::unique_ptr TileParser::createBucket(const StyleBucket &bucketDesc) } else if (bucketDesc.type == StyleLayerType::Line) { return createLineBucket(*layer, bucketDesc); } else if (bucketDesc.type == StyleLayerType::Symbol) { - if (partialParse) { - return nullptr; - } - - bool needsResources = false; - auto symbolBucket = createSymbolBucket(*layer, bucketDesc, needsResources); - if (needsResources) { - partialParse = true; - return nullptr; - } else { - return std::move(symbolBucket); - } + return createSymbolBucket(*layer, bucketDesc); } else if (bucketDesc.type == StyleLayerType::Raster) { return nullptr; } else { @@ -190,13 +179,7 @@ std::unique_ptr TileParser::createLineBucket(const GeometryTileLayer& la } std::unique_ptr TileParser::createSymbolBucket(const GeometryTileLayer& layer, - const StyleBucket& bucket_desc, - bool& needsResources) { - if (!sprite->isLoaded()) { - needsResources = true; - return nullptr; - } - + const StyleBucket& bucket_desc) { auto bucket = util::make_unique(*tile.getCollision()); const float z = tile.id.z; @@ -240,14 +223,21 @@ std::unique_ptr TileParser::createSymbolBucket(const GeometryTileLayer& applyLayoutProperty(PropertyKey::TextOffset, bucket_desc.layout, layout.text.offset, z); applyLayoutProperty(PropertyKey::TextAllowOverlap, bucket_desc.layout, layout.text.allow_overlap, z); - bucket->addFeatures( - layer, bucket_desc.filter, reinterpret_cast(&tile), spriteAtlas, *sprite, glyphAtlas, glyphStore); + if (bucket->needsDependencies(layer, bucket_desc.filter, glyphStore, *sprite)) { + partialParse = true; + } - if (bucket->needsGlyphs()) { - needsResources = 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(&tile), spriteAtlas, *sprite, glyphAtlas, glyphStore); + return bucket->hasData() ? std::move(bucket) : nullptr; } diff --git a/src/mbgl/map/tile_parser.hpp b/src/mbgl/map/tile_parser.hpp index 67150bcd4..88e568780 100644 --- a/src/mbgl/map/tile_parser.hpp +++ b/src/mbgl/map/tile_parser.hpp @@ -53,7 +53,7 @@ private: std::unique_ptr createBucket(const StyleBucket&); std::unique_ptr createFillBucket(const GeometryTileLayer&, const StyleBucket&); std::unique_ptr createLineBucket(const GeometryTileLayer&, const StyleBucket&); - std::unique_ptr createSymbolBucket(const GeometryTileLayer&, const StyleBucket&, bool& needsResources); + std::unique_ptr createSymbolBucket(const GeometryTileLayer&, const StyleBucket&); template void addBucketGeometries(Bucket&, const GeometryTileLayer&, const FilterExpression&); diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 03de3d8a2..4d957a1e5 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -29,7 +29,7 @@ namespace mbgl { SymbolBucket::SymbolBucket(Collision &collision_) - : collision(collision_), needsGlyphs_(false) { + : collision(collision_) { } SymbolBucket::~SymbolBucket() { @@ -62,16 +62,15 @@ bool SymbolBucket::hasTextData() const { return !text.groups.empty(); } bool SymbolBucket::hasIconData() const { return !icon.groups.empty(); } -std::vector SymbolBucket::processFeatures(const GeometryTileLayer& layer, - const FilterExpression& filter, - GlyphStore &glyphStore) { +bool SymbolBucket::needsDependencies(const GeometryTileLayer& layer, + const FilterExpression& filter, + GlyphStore& glyphStore, + Sprite& sprite) { const bool has_text = !layout.text.field.empty() && !layout.text.font.empty(); const bool has_icon = !layout.icon.image.empty(); - std::vector features; - if (!has_text && !has_icon) { - return features; + return false; } // Determine and load glyph ranges @@ -135,28 +134,21 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer } if (glyphStore.requestGlyphRangesIfNeeded(layout.text.font, ranges)) { - needsGlyphs_ = true; - return {}; + return true; } - return features; + if (!sprite.isLoaded()) { + return true; + } + + return false; } -void SymbolBucket::addFeatures(const GeometryTileLayer& layer, - const FilterExpression& filter, - uintptr_t tileUID, +void SymbolBucket::addFeatures(uintptr_t tileUID, SpriteAtlas& spriteAtlas, Sprite& sprite, GlyphAtlas& glyphAtlas, GlyphStore& glyphStore) { - const std::vector features = processFeatures(layer, filter, glyphStore); - - // Stop if we still need glyphs because the - // bucket will be discarded. - if (needsGlyphs()) { - return; - } - float horizontalAlign = 0.5; float verticalAlign = 0.5; @@ -244,6 +236,8 @@ void SymbolBucket::addFeatures(const GeometryTileLayer& layer, } } } + + features.clear(); } bool byScale(const Anchor &a, const Anchor &b) { return a.scale < b.scale; } diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index 9c67d66a5..d0b133bc7 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -61,25 +61,22 @@ public: bool hasTextData() const; bool hasIconData() const; - void addFeatures(const GeometryTileLayer&, - const FilterExpression&, - uintptr_t tileUID, + void addFeatures(uintptr_t tileUID, SpriteAtlas&, Sprite&, GlyphAtlas&, GlyphStore&); - inline bool needsGlyphs() const { return needsGlyphs_; } - void drawGlyphs(SDFShader& shader); void drawIcons(SDFShader& shader); void drawIcons(IconShader& shader); -private: - std::vector processFeatures(const GeometryTileLayer&, - const FilterExpression&, - GlyphStore&); + bool needsDependencies(const GeometryTileLayer&, + const FilterExpression&, + GlyphStore&, + Sprite&); +private: void addFeature(const std::vector &line, const Shaping &shaping, const GlyphPositions &face, const Rect &image); // Adds placed items to the buffer. @@ -92,6 +89,7 @@ public: private: Collision &collision; + std::vector features; struct TextBuffer { TextVertexBuffer vertices; @@ -104,9 +102,8 @@ private: TriangleElementsBuffer triangles; std::vector> groups; } icon; - - bool needsGlyphs_; }; + } #endif