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

Commit

Permalink
[core] fix symbol flickering after data updates
Browse files Browse the repository at this point in the history
  • Loading branch information
ansis committed Jan 11, 2018
1 parent bb46c86 commit 7ce8588
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 29 deletions.
1 change: 1 addition & 0 deletions src/mbgl/renderer/buckets/symbol_bucket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class SymbolBucket : public Bucket {
} collisionCircle;

uint32_t bucketInstanceId = 0;
bool justReloaded = false;
};

} // namespace mbgl
41 changes: 20 additions & 21 deletions src/mbgl/text/placement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_)
{
}
Expand All @@ -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)) {}

Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -234,10 +236,17 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
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) {
Expand Down Expand Up @@ -293,16 +302,6 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
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<float>(now - commitTime) / Duration(std::chrono::milliseconds(300));
Expand Down
13 changes: 6 additions & 7 deletions src/mbgl/text/placement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -23,7 +23,7 @@ class OpacityState {

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;
Expand All @@ -32,17 +32,17 @@ class JointOpacityState {

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 {
Expand All @@ -51,7 +51,6 @@ class Placement {
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;

Expand Down
7 changes: 6 additions & 1 deletion src/mbgl/tile/geometry_tile_worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,12 +425,17 @@ void GeometryTileWorker::attemptPlacement() {
continue;
}

std::shared_ptr<Bucket> bucket = symbolLayout->place(showCollisionBoxes);
std::shared_ptr<SymbolBucket> 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),
Expand Down
1 change: 1 addition & 0 deletions src/mbgl/tile/geometry_tile_worker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class GeometryTileWorker {
ImageMap imageMap;

bool showCollisionBoxes;
bool firstLoad = true;
};

} // namespace mbgl

0 comments on commit 7ce8588

Please sign in to comment.