From 7ce8588f4eff7c7f3e1b855e40e24947a2487ee4 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 10 Jan 2018 16:52:00 -0500 Subject: [core] fix symbol flickering after data updates --- src/mbgl/renderer/buckets/symbol_bucket.hpp | 1 + src/mbgl/text/placement.cpp | 41 ++++++++++++++--------------- src/mbgl/text/placement.hpp | 13 +++++---- src/mbgl/tile/geometry_tile_worker.cpp | 7 ++++- src/mbgl/tile/geometry_tile_worker.hpp | 1 + 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index 4abea90508..ed8afb052c 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -130,6 +130,7 @@ public: } collisionCircle; uint32_t bucketInstanceId = 0; + bool justReloaded = false; }; } // namespace mbgl diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 84e53f74eb..400fe79ac5 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -8,8 +8,8 @@ namespace mbgl { -OpacityState::OpacityState(bool placed_, bool offscreen) - : opacity((offscreen && placed_) ? 1 : 0) +OpacityState::OpacityState(bool placed_, bool skipFade) + : opacity((skipFade && placed_) ? 1 : 0) , placed(placed_) { } @@ -22,11 +22,11 @@ bool OpacityState::isHidden() const { return opacity == 0 && !placed; } -JointOpacityState::JointOpacityState(bool placedIcon, bool placedText, bool offscreen) : - icon(OpacityState(placedIcon, offscreen)), - text(OpacityState(placedText, offscreen)) {} +JointOpacityState::JointOpacityState(bool placedText, bool placedIcon, bool skipFade) : + icon(OpacityState(placedIcon, skipFade)), + text(OpacityState(placedText, skipFade)) {} -JointOpacityState::JointOpacityState(const JointOpacityState& prevOpacityState, float increment, bool placedIcon, bool placedText) : +JointOpacityState::JointOpacityState(const JointOpacityState& prevOpacityState, float increment, bool placedText, bool placedIcon) : icon(OpacityState(prevOpacityState.icon, increment, placedIcon)), text(OpacityState(prevOpacityState.text, increment, placedText)) {} @@ -165,10 +165,12 @@ void Placement::placeLayerBucket( placements.erase(symbolInstance.crossTileID); } - placements.emplace(symbolInstance.crossTileID, JointPlacement(placeText, placeIcon, offscreen)); + placements.emplace(symbolInstance.crossTileID, JointPlacement(placeText, placeIcon, offscreen || bucket.justReloaded)); seenCrossTileIDs.insert(symbolInstance.crossTileID); } } + + bucket.justReloaded = false; } bool Placement::commit(const Placement& prevPlacement, TimePoint now) { @@ -184,12 +186,12 @@ bool Placement::commit(const Placement& prevPlacement, TimePoint now) { for (auto& jointPlacement : placements) { auto prevOpacity = prevPlacement.opacities.find(jointPlacement.first); if (prevOpacity != prevPlacement.opacities.end()) { - opacities.emplace(jointPlacement.first, JointOpacityState(prevOpacity->second, increment, jointPlacement.second.icon, jointPlacement.second.text)); + opacities.emplace(jointPlacement.first, JointOpacityState(prevOpacity->second, increment, jointPlacement.second.text, jointPlacement.second.icon)); placementChanged = placementChanged || jointPlacement.second.icon != prevOpacity->second.icon.placed || jointPlacement.second.text != prevOpacity->second.text.placed; } else { - opacities.emplace(jointPlacement.first, JointOpacityState(jointPlacement.second.icon, jointPlacement.second.text, jointPlacement.second.offscreen)); + opacities.emplace(jointPlacement.first, JointOpacityState(jointPlacement.second.text, jointPlacement.second.icon, jointPlacement.second.skipFade)); placementChanged = placementChanged || jointPlacement.second.icon || jointPlacement.second.text; } } @@ -234,10 +236,17 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set& true); for (SymbolInstance& symbolInstance : bucket.symbolInstances) { - auto opacityState = seenCrossTileIDs.count(symbolInstance.crossTileID) == 0 ? - getOpacity(symbolInstance.crossTileID) : + bool isDuplicate = seenCrossTileIDs.count(symbolInstance.crossTileID) > 0; + + auto it = opacities.find(symbolInstance.crossTileID); + auto opacityState = it != opacities.end() && !isDuplicate ? + it->second : defaultOpacityState; + if (it == opacities.end()) { + opacities.emplace(symbolInstance.crossTileID, defaultOpacityState); + } + seenCrossTileIDs.insert(symbolInstance.crossTileID); if (symbolInstance.hasText) { @@ -293,16 +302,6 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set& bucket.sortFeatures(state.getAngle()); } -JointOpacityState Placement::getOpacity(uint32_t crossTileSymbolID) const { - auto it = opacities.find(crossTileSymbolID); - if (it != opacities.end()) { - return it->second; - } else { - return JointOpacityState(false, false, false); - } - -} - float Placement::symbolFadeChange(TimePoint now) const { if (mapMode == MapMode::Continuous) { return std::chrono::duration(now - commitTime) / Duration(std::chrono::milliseconds(300)); diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index bcc20f15a4..653ae352ed 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -14,7 +14,7 @@ class SymbolBucket; class OpacityState { public: - OpacityState(bool placed, bool offscreen); + OpacityState(bool placed, bool skipFade); OpacityState(const OpacityState& prevOpacityState, float increment, bool placed); bool isHidden() const; float opacity; @@ -23,7 +23,7 @@ public: class JointOpacityState { public: - JointOpacityState(bool placedIcon, bool placedText, bool offscreen); + JointOpacityState(bool placedIcon, bool placedText, bool skipFade); JointOpacityState(const JointOpacityState& prevOpacityState, float increment, bool placedIcon, bool placedText); bool isHidden() const; OpacityState icon; @@ -32,17 +32,17 @@ public: class JointPlacement { public: - JointPlacement(bool text_, bool icon_, bool offscreen_) - : text(text_), icon(icon_), offscreen(offscreen_) + JointPlacement(bool text_, bool icon_, bool skipFade_) + : text(text_), icon(icon_), skipFade(skipFade_) {} const bool text; const bool icon; - // offscreen = outside viewport, but within CollisionIndex::viewportPadding px of the edge + // skipFade = outside viewport, but within CollisionIndex::viewportPadding px of the edge // Because these symbols aren't onscreen yet, we can skip the "fade in" animation, // and if a subsequent viewport change brings them into view, they'll be fully // visible right away. - const bool offscreen; + const bool skipFade; }; class Placement { @@ -51,7 +51,6 @@ public: void placeLayer(RenderSymbolLayer&, const mat4&, bool showCollisionBoxes); bool commit(const Placement& prevPlacement, TimePoint); void updateLayerOpacities(RenderSymbolLayer&); - JointOpacityState getOpacity(uint32_t crossTileSymbolID) const; float symbolFadeChange(TimePoint now) const; bool hasTransitions(TimePoint now) const; diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index cf74bf3647..24841dd125 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -425,12 +425,17 @@ void GeometryTileWorker::attemptPlacement() { continue; } - std::shared_ptr bucket = symbolLayout->place(showCollisionBoxes); + std::shared_ptr bucket = symbolLayout->place(showCollisionBoxes); for (const auto& pair : symbolLayout->layerPaintProperties) { + if (!firstLoad) { + bucket->justReloaded = true; + } buckets.emplace(pair.first, bucket); } } + firstLoad = false; + parent.invoke(&GeometryTile::onPlacement, GeometryTile::PlacementResult { std::move(buckets), std::move(glyphAtlasImage), diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp index cc86248cec..0276392679 100644 --- a/src/mbgl/tile/geometry_tile_worker.hpp +++ b/src/mbgl/tile/geometry_tile_worker.hpp @@ -86,6 +86,7 @@ private: ImageMap imageMap; bool showCollisionBoxes; + bool firstLoad = true; }; } // namespace mbgl -- cgit v1.2.1