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

Commit

Permalink
[core] re-assign ids when lng jumps to avoid flicker
Browse files Browse the repository at this point in the history
  • Loading branch information
ansis committed May 22, 2018
1 parent 5e36f66 commit ba07c87
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 4 deletions.
9 changes: 7 additions & 2 deletions include/mbgl/tile/tile_id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,10 @@ class UnwrappedTileID {
std::array<UnwrappedTileID, 4> children() const;
OverscaledTileID overscaleTo(uint8_t z) const;
float pixelsToTileUnits(float pixelValue, float zoom) const;
UnwrappedTileID unwrapTo(int16_t wrap);

const int16_t wrap;
const CanonicalTileID canonical;
int16_t wrap;
CanonicalTileID canonical;
};

::std::ostream& operator<<(::std::ostream& os, const UnwrappedTileID& rhs);
Expand Down Expand Up @@ -220,6 +221,10 @@ inline bool UnwrappedTileID::operator<(const UnwrappedTileID& rhs) const {
return std::tie(wrap, canonical) < std::tie(rhs.wrap, rhs.canonical);
}

inline UnwrappedTileID UnwrappedTileID::unwrapTo(int16_t newWrap) {
return { newWrap, canonical };
}

inline bool UnwrappedTileID::isChildOf(const UnwrappedTileID& parent) const {
return wrap == parent.wrap && canonical.isChildOf(parent.canonical);
}
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/render_tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class RenderTile final {
RenderTile& operator=(const RenderTile&) = delete;
RenderTile& operator=(RenderTile&&) = default;

const UnwrappedTileID id;
UnwrappedTileID id;
Tile& tile;
ClipID clip;
mat4 matrix;
Expand Down
40 changes: 40 additions & 0 deletions src/mbgl/renderer/tile_pyramid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
return;
}

handleWrapJump(parameters.transformState.getLatLng().longitude());

// Determine the overzooming/underzooming amounts and required tiles.
int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize);
int32_t tileZoom = overscaledZoom;
Expand Down Expand Up @@ -238,6 +240,44 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
}
}

void TilePyramid::handleWrapJump(float lng) {
// On top of the regular z/x/y values, TileIDs have a `wrap` value that specify
// which cppy of the world the tile belongs to. For example, at `lng: 10` you
// might render z/x/y/0 while at `lng: 370` you would render z/x/y/1.
//
// When lng values get wrapped (going from `lng: 370` to `long: 10`) you expect
// to see the same thing on the screen (370 degrees and 10 degrees is the same
// place in the world) but all the TileIDs will have different wrap values.
//
// In order to make this transition seamless, we calculate the rounded difference of
// "worlds" between the last frame and the current frame. If the map panned by
// a world, then we can assign all the tiles new TileIDs with updated wrap values.
// For example, assign z/x/y/1 a new id: z/x/y/0. It is the same tile, just rendered
// in a different position.
//
// This enables us to reuse the tiles at more ideal locations and prevent flickering.

const float lngDifference = lng - prevLng;
const float worldDifference = lngDifference / 360;
const int wrapDelta = ::round(worldDifference);
prevLng = lng;

if (wrapDelta) {
std::map<OverscaledTileID, std::unique_ptr<Tile>> newTiles;
for (auto& tile : tiles) {
auto newID = tile.second->id.unwrapTo(tile.second->id.wrap + wrapDelta);
tile.second->id = newID;
newTiles.emplace(newID, std::move(tile.second));
}
tiles = std::move(newTiles);

for (auto& renderTile : renderTiles) {
renderTile.id = renderTile.id.unwrapTo(renderTile.id.wrap + wrapDelta);
}
}
}


std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
Expand Down
4 changes: 4 additions & 0 deletions src/mbgl/renderer/tile_pyramid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class TilePyramid {
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles();
Tile* getTile(const OverscaledTileID&);

void handleWrapJump(float lng);

std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
Expand All @@ -72,6 +74,8 @@ class TilePyramid {
std::vector<RenderTile> renderTiles;

TileObserver* observer = nullptr;

float prevLng = 0;
};

} // namespace mbgl
2 changes: 1 addition & 1 deletion src/mbgl/tile/tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class Tile : private util::noncopyable {

void dumpDebugLogs() const;

const OverscaledTileID id;
OverscaledTileID id;
optional<Timestamp> modified;
optional<Timestamp> expires;

Expand Down

0 comments on commit ba07c87

Please sign in to comment.