summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mbgl/style/source_impl.cpp9
-rw-r--r--src/mbgl/style/source_impl.hpp4
-rw-r--r--src/mbgl/tile/geometry_tile.cpp61
-rw-r--r--src/mbgl/tile/geometry_tile.hpp3
-rw-r--r--src/mbgl/tile/tile.hpp1
-rw-r--r--src/mbgl/tile/tile_worker.cpp14
-rw-r--r--src/mbgl/tile/tile_worker.hpp5
-rw-r--r--src/mbgl/util/worker.cpp21
-rw-r--r--src/mbgl/util/worker.hpp5
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,