summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2017-05-17 13:49:48 -0700
committerChris Loer <chris.loer@mapbox.com>2017-05-17 16:25:06 -0700
commit77b24bc0d3ddfda494cf1a7ce4090ff3a79324e4 (patch)
treecc5866773c159f1b3573f507069bf1c26660d560
parente7154adac3985b8d877c40d16c7d4b3916c7246b (diff)
downloadqtlocation-mapboxgl-77b24bc0d3ddfda494cf1a7ce4090ff3a79324e4.tar.gz
[core] Throttle tiles to redo symbol placement at most once every 300ms.
Fixes issue #8435 and prepares for pitch-scaling changes in issue #8967.
-rw-r--r--cmake/core-files.cmake2
-rw-r--r--src/mbgl/tile/geometry_tile.cpp12
-rw-r--r--src/mbgl/tile/geometry_tile.hpp4
-rw-r--r--src/mbgl/util/throttler.cpp36
-rw-r--r--src/mbgl/util/throttler.hpp22
5 files changed, 74 insertions, 2 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index 90b8d97afe..dfe11b82b8 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -593,6 +593,8 @@ set(MBGL_CORE_FILES
src/mbgl/util/thread_context.cpp
src/mbgl/util/thread_context.hpp
src/mbgl/util/thread_local.hpp
+ src/mbgl/util/throttler.cpp
+ src/mbgl/util/throttler.hpp
src/mbgl/util/tile_coordinate.hpp
src/mbgl/util/tile_cover.cpp
src/mbgl/util/tile_cover.hpp
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 3da429ddf6..8f14a9c8aa 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -18,6 +18,7 @@
#include <mbgl/map/query.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/style/filter_evaluator.hpp>
+#include <mbgl/util/chrono.hpp>
#include <mbgl/util/logging.hpp>
#include <iostream>
@@ -41,7 +42,8 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_,
obsolete,
parameters.mode),
glyphAtlas(glyphAtlas_),
- spriteAtlas(spriteAtlas_) {
+ spriteAtlas(spriteAtlas_),
+ placementThrottler(Milliseconds(300), [this] { invokePlacement(); }) {
}
GeometryTile::~GeometryTile() {
@@ -85,7 +87,13 @@ void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) {
++correlationID;
requestedConfig = desiredConfig;
- worker.invoke(&GeometryTileWorker::setPlacementConfig, desiredConfig, correlationID);
+ placementThrottler.invoke();
+}
+
+void GeometryTile::invokePlacement() {
+ if (requestedConfig) {
+ worker.invoke(&GeometryTileWorker::setPlacementConfig, *requestedConfig, correlationID);
+ }
}
void GeometryTile::redoLayout() {
diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index 7d275fc72c..6e4c29d723 100644
--- a/src/mbgl/tile/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
@@ -6,6 +6,7 @@
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/text/placement_config.hpp>
#include <mbgl/util/feature.hpp>
+#include <mbgl/util/throttler.hpp>
#include <mbgl/actor/actor.hpp>
#include <atomic>
@@ -88,6 +89,7 @@ protected:
private:
void markObsolete();
+ void invokePlacement();
const std::string sourceID;
style::Style& style;
@@ -110,6 +112,8 @@ private:
std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets;
std::unique_ptr<CollisionTile> collisionTile;
+
+ util::Throttler placementThrottler;
};
} // namespace mbgl
diff --git a/src/mbgl/util/throttler.cpp b/src/mbgl/util/throttler.cpp
new file mode 100644
index 0000000000..910810ce2f
--- /dev/null
+++ b/src/mbgl/util/throttler.cpp
@@ -0,0 +1,36 @@
+#include <mbgl/util/throttler.hpp>
+
+namespace mbgl {
+namespace util {
+
+Throttler::Throttler(Duration frequency_, std::function<void()>&& function_)
+ : frequency(frequency_)
+ , function(std::move(function_))
+ , pendingInvocation(false)
+ , lastInvocation(TimePoint::min())
+{}
+
+void Throttler::invoke() {
+ if (pendingInvocation) {
+ return;
+ }
+
+ Duration timeToNextInvocation = lastInvocation == TimePoint::min()
+ ? Duration::zero()
+ : (lastInvocation + frequency) - Clock::now();
+
+ if (timeToNextInvocation <= Duration::zero()) {
+ lastInvocation = Clock::now();
+ function();
+ } else {
+ pendingInvocation = true;
+ timer.start(timeToNextInvocation, Duration::zero(), [this]{
+ pendingInvocation = false;
+ lastInvocation = Clock::now();
+ function();
+ });
+ }
+}
+
+} // namespace util
+} // namespace mbgl
diff --git a/src/mbgl/util/throttler.hpp b/src/mbgl/util/throttler.hpp
new file mode 100644
index 0000000000..175de7ccaf
--- /dev/null
+++ b/src/mbgl/util/throttler.hpp
@@ -0,0 +1,22 @@
+#include <mbgl/util/chrono.hpp>
+#include <mbgl/util/timer.hpp>
+
+namespace mbgl {
+namespace util {
+
+class Throttler {
+public:
+ Throttler(Duration frequency, std::function<void()>&& function);
+
+ void invoke();
+private:
+ Duration frequency;
+ std::function<void()> function;
+
+ Timer timer;
+ bool pendingInvocation;
+ TimePoint lastInvocation;
+};
+
+} // namespace util
+} // namespace mbgl