From 25cfb5863c9ac3705d2bcf4086c237608264e3ae Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Tue, 14 Nov 2017 15:30:27 -0800 Subject: [core] Symbol cross-fading. Hold onto tiles after they've been removed from the render tree long enough to run a fade animation on their symbols. --- src/mbgl/renderer/renderer_impl.cpp | 23 +++++++++++++++++++++++ src/mbgl/renderer/renderer_impl.hpp | 3 +++ src/mbgl/renderer/tile_pyramid.cpp | 20 ++++++++++++++++++++ 3 files changed, 46 insertions(+) (limited to 'src/mbgl/renderer') diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 032b4558ce..aa138df662 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -339,6 +339,10 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { } else { std::sort(sortedTiles.begin(), sortedTiles.end(), [](const auto& a, const auto& b) { return a.get().id < b.get().id; }); + // Don't render non-symbol layers for tiles that we're only holding on to for symbol fading + sortedTiles.erase(std::remove_if(sortedTiles.begin(), sortedTiles.end(), + [](const auto& tile) { return tile.get().tile.holdForFade(); }), + sortedTiles.end()); } std::vector> sortedTilesForInsertion; @@ -389,6 +393,8 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { } placement->setRecent(parameters.timePoint); + + updateFadingTiles(); } else { placement->setStale(); } @@ -754,10 +760,27 @@ bool Renderer::Impl::hasTransitions(TimePoint timePoint) const { if (placement->hasTransitions(timePoint)) { return true; } + + if (fadingTiles) { + return true; + } return false; } +void Renderer::Impl::updateFadingTiles() { + fadingTiles = false; + for (auto& source : renderSources) { + for (auto& renderTile : source.second->getRenderTiles()) { + Tile& tile = renderTile.get().tile; + if (tile.holdForFade()) { + fadingTiles = true; + tile.performedFadePlacement(); + } + } + } +} + bool Renderer::Impl::isLoaded() const { for (const auto& entry: renderSources) { if (!entry.second->isLoaded()) { diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp index 32e2dc99f2..4f8139791c 100644 --- a/src/mbgl/renderer/renderer_impl.hpp +++ b/src/mbgl/renderer/renderer_impl.hpp @@ -74,6 +74,8 @@ private: void onTileChanged(RenderSource&, const OverscaledTileID&) override; void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override; + void updateFadingTiles(); + friend class Renderer; RendererBackend& backend; @@ -113,6 +115,7 @@ private: std::unique_ptr placement; bool contextLost = false; + bool fadingTiles = false; }; } // namespace mbgl diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index fae16c9ce6..c1566d12a5 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -148,9 +148,17 @@ void TilePyramid::update(const std::vector>& layer } return tiles.emplace(tileID, std::move(tile)).first->second.get(); }; + + std::map previouslyRenderedTiles; + for (auto& renderTile : renderTiles) { + previouslyRenderedTiles[renderTile.id] = &renderTile.tile; + } + auto renderTileFn = [&](const UnwrappedTileID& tileID, Tile& tile) { renderTiles.emplace_back(tileID, tile); rendered.emplace(tileID); + previouslyRenderedTiles.erase(tileID); // Still rendering this tile, no need for special fading logic. + tile.markRenderedIdeal(); }; renderTiles.clear(); @@ -162,6 +170,18 @@ void TilePyramid::update(const std::vector>& layer algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, renderTileFn, idealTiles, zoomRange, tileZoom); + + for (auto previouslyRenderedTile : previouslyRenderedTiles) { + Tile& tile = *previouslyRenderedTile.second; + tile.markRenderedPreviously(); + if (tile.holdForFade()) { + // Since it was rendered in the last frame, we know we have it + // Don't mark the tile "Required" to avoid triggering a new network request + retainTileFn(tile, TileNecessity::Optional); + renderTiles.emplace_back(previouslyRenderedTile.first, tile); + rendered.emplace(previouslyRenderedTile.first); + } + } if (type != SourceType::Annotations) { size_t conservativeCacheSize = -- cgit v1.2.1