diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-05-17 13:49:48 -0700 |
---|---|---|
committer | Chris Loer <chris.loer@mapbox.com> | 2017-05-17 16:25:06 -0700 |
commit | 77b24bc0d3ddfda494cf1a7ce4090ff3a79324e4 (patch) | |
tree | cc5866773c159f1b3573f507069bf1c26660d560 | |
parent | e7154adac3985b8d877c40d16c7d4b3916c7246b (diff) | |
download | qtlocation-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.cmake | 2 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/util/throttler.cpp | 36 | ||||
-rw-r--r-- | src/mbgl/util/throttler.hpp | 22 |
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 |