From 0d9e4afd20f4e28479fcc725b7579d66477ed07a Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Fri, 13 Sep 2019 11:21:27 +0300 Subject: [core] Coalesce buckets updates from several tiles --- src/mbgl/renderer/render_orchestrator.cpp | 6 +++++- src/mbgl/text/placement.cpp | 20 ++++++++++++++++---- src/mbgl/text/placement.hpp | 4 +++- 3 files changed, 24 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index 1e2541c4d4..a62ccb0a0a 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -367,7 +367,11 @@ std::unique_ptr RenderOrchestrator::createRenderTree(const UpdatePar symbolBucketsAdded = symbolBucketsAdded || (result & CrossTileSymbolIndex::AddLayerResult::BucketsAdded); symbolBucketsChanged = symbolBucketsChanged || (result != CrossTileSymbolIndex::AddLayerResult::NoChanges); } - renderTreeParameters->placementChanged = !placement->stillRecent(updateParameters.timePoint, updateParameters.transformState.getZoom()) || symbolBucketsAdded; + // We want new symbols to show up faster, however simple setting `placementChanged` to `true` would + // initiate placement too often as new buckets ususally come from several rendered tiles in a row within + // a short period of time. Instead, we squeeze placement update period to coalesce buckets updates from several tiles. + if (symbolBucketsAdded) placement->setMaximumUpdatePeriod(Milliseconds(30)); + renderTreeParameters->placementChanged = !placement->stillRecent(updateParameters.timePoint, updateParameters.transformState.getZoom()); std::set usedSymbolLayers; if (renderTreeParameters->placementChanged) { diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 89b3189b83..06777dea44 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -964,6 +964,17 @@ float Placement::zoomAdjustment(const float zoom) const { return std::max(0.0, (placementZoom - zoom) / 1.5); } +Duration Placement::getUpdatePeriod(const float zoom) const { + // Even if transitionOptions.duration is set to a value < 300ms, we still wait for this default transition duration + // before attempting another placement operation. + const auto fadeDuration = std::max(util::DEFAULT_TRANSITION_DURATION, transitionOptions.duration.value_or(util::DEFAULT_TRANSITION_DURATION)); + const auto adjustedDuration = std::chrono::duration_cast(fadeDuration * (1.0 - zoomAdjustment(zoom))); + if (maximumUpdatePeriod) { + return std::min(*maximumUpdatePeriod, adjustedDuration); + } + return adjustedDuration; +} + bool Placement::hasTransitions(TimePoint now) const { if (mapMode == MapMode::Continuous && transitionOptions.enablePlacementTransitions) { return stale || std::chrono::duration(now - fadeStartTime) < transitionOptions.duration.value_or(util::DEFAULT_TRANSITION_DURATION); @@ -973,12 +984,13 @@ bool Placement::hasTransitions(TimePoint now) const { } bool Placement::stillRecent(TimePoint now, const float zoom) const { - // Even if transitionOptions.duration is set to a value < 300ms, we still wait for this default transition duration - // before attempting another placement operation. - const auto fadeDuration = std::max(util::DEFAULT_TRANSITION_DURATION, transitionOptions.duration.value_or(util::DEFAULT_TRANSITION_DURATION)); return mapMode == MapMode::Continuous && transitionOptions.enablePlacementTransitions && - commitTime + fadeDuration * (1.0 - zoomAdjustment(zoom)) > now; + commitTime + getUpdatePeriod(zoom) > now; +} + +void Placement::setMaximumUpdatePeriod(Duration duration) { + maximumUpdatePeriod = duration; } void Placement::setStale() { diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index c1fe69b852..b5405cbcd7 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -110,7 +110,7 @@ public: const CollisionIndex& getCollisionIndex() const; bool stillRecent(TimePoint now, const float zoom) const; - void setRecent(TimePoint now); + void setMaximumUpdatePeriod(Duration); void setStale(); const RetainedQueryData& getQueryData(uint32_t bucketInstanceId) const; @@ -126,6 +126,7 @@ private: void markUsedJustification(SymbolBucket&, style::TextVariableAnchorType, const SymbolInstance&, style::TextWritingModeType orientation); void markUsedOrientation(SymbolBucket&, style::TextWritingModeType, const SymbolInstance&); float zoomAdjustment(const float zoom) const; + Duration getUpdatePeriod(const float zoom) const; CollisionIndex collisionIndex; @@ -147,6 +148,7 @@ private: std::unordered_map retainedQueryData; CollisionGroups collisionGroups; std::unique_ptr prevPlacement; + optional maximumUpdatePeriod; // Used for debug purposes. std::unordered_map> collisionCircles; -- cgit v1.2.1