diff --git a/package.json b/package.json index 9f48f4f0b..8b073a7ee 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "lodash": "^4.16.4", "mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#98a56d538b11fb331aa67a6d632d6ecd6821b007", "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#7f62a4fc9f21e619824d68abbc4b03cbc1685572", - "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#d27aab1c74f0f0462e19d4aa5700fb2127567f87", + "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#10a135f01b56989aa03686de94cc67c3efa6139d", "mkdirp": "^0.5.1", "node-cmake": "^1.2.1", "request": "^2.72.0", diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp index 9d7881562..75668fc3b 100644 --- a/src/mbgl/style/source_impl.cpp +++ b/src/mbgl/style/source_impl.cpp @@ -184,6 +184,12 @@ void Source::Impl::removeTiles() { } } +void Source::Impl::updateSymbolDependentTiles() { + for (auto& pair : tiles) { + pair.second->symbolDependenciesChanged(); + } +} + void Source::Impl::reloadTiles() { cache.clear(); diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp index 9efe5205b..1041ebffe 100644 --- a/src/mbgl/style/source_impl.hpp +++ b/src/mbgl/style/source_impl.hpp @@ -43,11 +43,14 @@ public: virtual void loadDescription(FileSource&) = 0; bool isLoaded() const; - // Called when the camera has changed or icons or glyphs are loaded. May load new - // tiles, unload obsolete tiles, and trigger further parsing of incomplete tiles or - // re-placement of existing complete tiles. + // Called when the camera has changed. May load new tiles, unload obsolete tiles, or + // trigger re-placement of existing complete tiles. void updateTiles(const UpdateParameters&); + // Called when icons or glyphs are loaded. Triggers further processing of tiles which + // were waiting on such dependencies. + void updateSymbolDependentTiles(); + // Removes all tiles (by putting them into the cache). void removeTiles(); diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 3c2b97b65..f14be5139 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -220,6 +220,12 @@ void Style::updateTiles(const UpdateParameters& parameters) { } } +void Style::updateSymbolDependentTiles() { + for (const auto& source : sources) { + source->baseImpl->updateSymbolDependentTiles(); + } +} + void Style::relayout() { for (const auto& sourceID : updateBatch.sourceIDs) { Source* source = getSource(sourceID); @@ -475,7 +481,7 @@ void Style::setObserver(style::Observer* observer_) { void Style::onGlyphsLoaded(const FontStack& fontStack, const GlyphRange& glyphRange) { observer->onGlyphsLoaded(fontStack, glyphRange); - observer->onUpdate(Update::Repaint); + updateSymbolDependentTiles(); } void Style::onGlyphsError(const FontStack& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) { @@ -525,7 +531,8 @@ void Style::onTileError(Source& source, const OverscaledTileID& tileID, std::exc void Style::onSpriteLoaded() { observer->onSpriteLoaded(); - observer->onUpdate(Update::Repaint); + observer->onUpdate(Update::Repaint); // For *-pattern properties. + updateSymbolDependentTiles(); } void Style::onSpriteError(std::exception_ptr error) { diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 21b25857d..14aef5de4 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -121,6 +121,7 @@ private: std::vector>::const_iterator findLayer(const std::string& layerID) const; void reloadLayerSource(Layer&); + void updateSymbolDependentTiles(); // GlyphStoreObserver implementation. void onGlyphsLoaded(const FontStack&, const GlyphRange&) override; diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 46e2b414f..c77467ebc 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -65,6 +65,10 @@ void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) { worker.invoke(&GeometryTileWorker::setPlacementConfig, desiredConfig, correlationID); } +void GeometryTile::symbolDependenciesChanged() { + worker.invoke(&GeometryTileWorker::symbolDependenciesChanged); +} + void GeometryTile::redoLayout() { // Mark the tile as pending again if it was complete before to prevent signaling a complete // state despite pending parse operations. diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index bcc71480a..cb3ca5463 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -35,6 +35,7 @@ public: void setData(std::unique_ptr); void setPlacementConfig(const PlacementConfig&) override; + void symbolDependenciesChanged() override; void redoLayout() override; Bucket* getBucket(const style::Layer&) override; diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index b6f166be5..6ff3c6779 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -42,13 +42,13 @@ GeometryTileWorker::~GeometryTileWorker() { States are indicated by [state], lines are transitions triggered by messages, (parentheses) are actions taken on transition. - [idle] <------------------. - | | - set{Data,Layers,Placement} | - | | - (do layout/placement; self-send "coalesced") | - v | - [coalescing] --- coalesced --. + [idle] <----------------------------. + | | + set{Data,Layers,Placement}, symbolDependenciesChanged | + | | + (do layout/placement; self-send "coalesced") | + v | + [coalescing] --- coalesced ------------. | | .-----------------. .---------------. | | @@ -140,6 +140,31 @@ void GeometryTileWorker::setPlacementConfig(PlacementConfig placementConfig_, ui } } +void GeometryTileWorker::symbolDependenciesChanged() { + try { + switch (state) { + case Idle: + if (hasPendingSymbolDependencies()) { + attemptPlacement(); + coalesce(); + } + break; + + case Coalescing: + if (hasPendingSymbolDependencies()) { + state = NeedPlacement; + } + break; + + case NeedPlacement: + case NeedLayout: + break; + } + } catch (...) { + parent.invoke(&GeometryTile::onError, std::current_exception()); + } +} + void GeometryTileWorker::coalesced() { try { switch (state) { @@ -238,6 +263,18 @@ void GeometryTileWorker::redoLayout() { attemptPlacement(); } +bool GeometryTileWorker::hasPendingSymbolDependencies() const { + bool result = false; + + for (const auto& symbolLayout : symbolLayouts) { + if (symbolLayout->state == SymbolLayout::Pending) { + result = true; + } + } + + return result; +} + void GeometryTileWorker::attemptPlacement() { if (!data || !layers || !placementConfig) { return; diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp index d55b29702..58b5e23cf 100644 --- a/src/mbgl/tile/geometry_tile_worker.hpp +++ b/src/mbgl/tile/geometry_tile_worker.hpp @@ -34,12 +34,14 @@ public: void setLayers(std::vector>, uint64_t correlationID); void setData(std::unique_ptr, uint64_t correlationID); void setPlacementConfig(PlacementConfig, uint64_t correlationID); + void symbolDependenciesChanged(); private: void coalesce(); void coalesced(); void redoLayout(); void attemptPlacement(); + bool hasPendingSymbolDependencies() const; ActorRef self; ActorRef parent; diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index 949bc0e33..eea89bd63 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -48,6 +48,7 @@ public: virtual Bucket* getBucket(const style::Layer&) = 0; virtual void setPlacementConfig(const PlacementConfig&) {} + virtual void symbolDependenciesChanged() {}; virtual void redoLayout() {} virtual void queryRenderedFeatures(