diff options
-rw-r--r-- | src/mbgl/style/source_impl.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/style/source_impl.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.cpp | 61 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/tile/tile.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/tile/tile_worker.cpp | 14 | ||||
-rw-r--r-- | src/mbgl/tile/tile_worker.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/util/worker.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/util/worker.hpp | 5 |
9 files changed, 96 insertions, 27 deletions
diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp index ba2fbb7c30..d5e33caa55 100644 --- a/src/mbgl/style/source_impl.cpp +++ b/src/mbgl/style/source_impl.cpp @@ -182,6 +182,15 @@ bool Source::Impl::parseTiles(const UpdateParameters& parameters) { return allTilesUpdated; } +void Source::Impl::reload() { + cache.clear(); + + for (auto& pair : tiles) { + auto tile = pair.second.get(); + tile->redoLayout(); + } +} + static Point<int16_t> coordinateToTilePoint(const UnwrappedTileID& tileID, const Point<double>& p) { auto zoomedCoord = TileCoordinate { p, 0 }.zoomTo(tileID.canonical.z); return { diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp index 61baccfcb7..93add4ad13 100644 --- a/src/mbgl/style/source_impl.hpp +++ b/src/mbgl/style/source_impl.hpp @@ -50,6 +50,10 @@ public: void loadTiles(const UpdateParameters&); bool parseTiles(const UpdateParameters&); + // Request that all loaded tiles re-run the layout operation on the existing source + // data with fresh style information. + void reload(); + void startRender(algorithm::ClipIDGenerator&, const mat4& projMatrix, const TransformState&); diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index bd2d8f760f..d353acf574 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -83,33 +83,52 @@ void GeometryTile::setData(std::unique_ptr<const GeometryTileData> data_) { // when tile data changed. Replacing the workdRequest will cancel a pending work // request in case there is one. workRequest.reset(); - workRequest = worker.parseGeometryTile(tileWorker, cloneStyleLayers(), std::move(data_), targetConfig, [this, config = targetConfig] (TileParseResult result) { - workRequest.reset(); + workRequest = worker.parseGeometryTile(tileWorker, cloneStyleLayers(), std::move(data_), targetConfig, + [this, config = targetConfig] (TileParseResult result) { + tileLoaded(std::move(result), config); + }); +} - if (result.is<TileParseResultData>()) { - auto& resultBuckets = result.get<TileParseResultData>(); - availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; +void GeometryTile::redoLayout() { + // Mark the tile as pending again if it was complete before to prevent signaling a complete + // state despite pending parse operations. + if (availableData == DataAvailability::All) { + availableData = DataAvailability::Some; + } - // Persist the configuration we just placed so that we can later check whether we need to - // place again in case the configuration has changed. - placedConfig = config; + workRequest.reset(); + workRequest = worker.redoLayout(tileWorker, cloneStyleLayers(), targetConfig, + [this, config = targetConfig] (TileParseResult result) { + tileLoaded(std::move(result), config); + }); +} - // Move over all buckets we received in this parse request, potentially overwriting - // existing buckets in case we got a refresh parse. - buckets = std::move(resultBuckets.buckets); +void GeometryTile::tileLoaded(TileParseResult result, PlacementConfig config) { + workRequest.reset(); - if (isComplete()) { - featureIndex = std::move(resultBuckets.featureIndex); - data = std::move(resultBuckets.tileData); - } + if (result.is<TileParseResultData>()) { + auto& resultBuckets = result.get<TileParseResultData>(); + availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; - redoPlacement(); - observer->onTileLoaded(*this, true); - } else { - availableData = DataAvailability::All; - observer->onTileError(*this, result.get<std::exception_ptr>()); + // Persist the configuration we just placed so that we can later check whether we need to + // place again in case the configuration has changed. + placedConfig = config; + + // Move over all buckets we received in this parse request, potentially overwriting + // existing buckets in case we got a refresh parse. + buckets = std::move(resultBuckets.buckets); + + if (isComplete()) { + featureIndex = std::move(resultBuckets.featureIndex); + data = std::move(resultBuckets.tileData); } - }); + + redoPlacement(); + observer->onTileLoaded(*this, true); + } else { + availableData = DataAvailability::All; + observer->onTileError(*this, result.get<std::exception_ptr>()); + } } bool GeometryTile::parsePending() { diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index adbe81e29f..e0db58325c 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -37,6 +37,7 @@ public: bool parsePending() override; + void redoLayout() override; void redoPlacement(PlacementConfig) override; void queryRenderedFeatures( @@ -51,6 +52,8 @@ private: std::vector<std::unique_ptr<style::Layer>> cloneStyleLayers() const; void redoPlacement(); + void tileLoaded(TileParseResult, PlacementConfig); + const std::string sourceID; style::Style& style; Worker& worker; diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index 65f3aaa245..740ced3898 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 bool parsePending() { return true; } + virtual void redoLayout() {} virtual void redoPlacement(PlacementConfig) {} virtual void queryRenderedFeatures( diff --git a/src/mbgl/tile/tile_worker.cpp b/src/mbgl/tile/tile_worker.cpp index 0c90456da0..8fe75d71d4 100644 --- a/src/mbgl/tile/tile_worker.cpp +++ b/src/mbgl/tile/tile_worker.cpp @@ -39,15 +39,19 @@ TileWorker::~TileWorker() { TileParseResult TileWorker::parseAllLayers(std::vector<std::unique_ptr<Layer>> layers_, std::unique_ptr<const GeometryTileData> tileData_, PlacementConfig config) { - // We're doing a fresh parse of the tile, because the underlying data has changed. + tileData = std::move(tileData_); + return redoLayout(std::move(layers_), config); +} + +TileParseResult TileWorker::redoLayout(std::vector<std::unique_ptr<Layer>> layers_, + const PlacementConfig config) { + layers = std::move(layers_); + + // We're doing a fresh parse of the tile, because the underlying data or style has changed. pending.clear(); placementPending.clear(); partialParse = false; featureIndex = std::make_unique<FeatureIndex>(); - tileData = std::move(tileData_); - - // Store the layers for use in redoPlacement. - layers = std::move(layers_); // We're storing a set of bucket names we've parsed to avoid parsing a bucket twice that is // referenced from more than one layer diff --git a/src/mbgl/tile/tile_worker.hpp b/src/mbgl/tile/tile_worker.hpp index f0113f738c..5f38c898ff 100644 --- a/src/mbgl/tile/tile_worker.hpp +++ b/src/mbgl/tile/tile_worker.hpp @@ -53,11 +53,14 @@ public: ~TileWorker(); TileParseResult parseAllLayers(std::vector<std::unique_ptr<style::Layer>>, - std::unique_ptr<const GeometryTileData> tileData, + std::unique_ptr<const GeometryTileData>, PlacementConfig); TileParseResult parsePendingLayers(PlacementConfig); + TileParseResult redoLayout(std::vector<std::unique_ptr<style::Layer>>, + PlacementConfig); + std::unique_ptr<CollisionTile> redoPlacement(const std::unordered_map<std::string, std::unique_ptr<Bucket>>*, PlacementConfig); diff --git a/src/mbgl/util/worker.cpp b/src/mbgl/util/worker.cpp index 39e3b1cea6..e05a5cf837 100644 --- a/src/mbgl/util/worker.cpp +++ b/src/mbgl/util/worker.cpp @@ -51,6 +51,17 @@ public: } } + void redoLayout(TileWorker* worker, + std::vector<std::unique_ptr<style::Layer>> layers, + PlacementConfig config, + std::function<void(TileParseResult)> callback) { + try { + callback(worker->redoLayout(std::move(layers), config)); + } catch (...) { + callback(std::current_exception()); + } + } + void redoPlacement(TileWorker* worker, const std::unordered_map<std::string, std::unique_ptr<Bucket>>* buckets, PlacementConfig config, @@ -98,6 +109,16 @@ Worker::parsePendingGeometryTileLayers(TileWorker& worker, } std::unique_ptr<AsyncRequest> +Worker::redoLayout(TileWorker& worker, + std::vector<std::unique_ptr<style::Layer>> layers, + PlacementConfig config, + std::function<void(TileParseResult)> callback) { + current = (current + 1) % threads.size(); + return threads[current]->invokeWithCallback(&Worker::Impl::redoLayout, callback, &worker, + std::move(layers), config); +} + +std::unique_ptr<AsyncRequest> Worker::redoPlacement(TileWorker& worker, const std::unordered_map<std::string, std::unique_ptr<Bucket>>& buckets, PlacementConfig config, diff --git a/src/mbgl/util/worker.hpp b/src/mbgl/util/worker.hpp index 3c6d3f64b0..31c41debf2 100644 --- a/src/mbgl/util/worker.hpp +++ b/src/mbgl/util/worker.hpp @@ -49,6 +49,11 @@ public: PlacementConfig config, std::function<void(TileParseResult)> callback); + Request redoLayout(TileWorker&, + std::vector<std::unique_ptr<style::Layer>>, + PlacementConfig, + std::function<void(TileParseResult)> callback); + Request redoPlacement(TileWorker&, const std::unordered_map<std::string, std::unique_ptr<Bucket>>&, PlacementConfig config, |