Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Throttle tiles to redo symbol placement at most once every 300ms. #9031

Merged
merged 1 commit into from
May 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 10 additions & 2 deletions src/mbgl/tile/geometry_tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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() {
Expand Down Expand Up @@ -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() {
Expand Down
4 changes: 4 additions & 0 deletions src/mbgl/tile/geometry_tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -88,6 +89,7 @@ class GeometryTile : public Tile, public GlyphRequestor, IconRequestor {

private:
void markObsolete();
void invokePlacement();

const std::string sourceID;
style::Style& style;
Expand All @@ -110,6 +112,8 @@ class GeometryTile : public Tile, public GlyphRequestor, IconRequestor {

std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets;
std::unique_ptr<CollisionTile> collisionTile;

util::Throttler placementThrottler;
};

} // namespace mbgl
36 changes: 36 additions & 0 deletions src/mbgl/util/throttler.cpp
Original file line number Diff line number Diff line change
@@ -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
22 changes: 22 additions & 0 deletions src/mbgl/util/throttler.hpp
Original file line number Diff line number Diff line change
@@ -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