From 407fbc70b1dc6dab6b7aa5a4b9c57b4e08906c79 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sun, 15 Jan 2017 11:27:52 -0500 Subject: [core] Prefetch low resolution tiles --- include/mbgl/map/map.hpp | 9 +++++++++ include/mbgl/util/constants.hpp | 2 ++ src/mbgl/map/map.cpp | 15 ++++++++++++++- src/mbgl/renderer/render_style.cpp | 3 ++- src/mbgl/renderer/tile_parameters.hpp | 1 + src/mbgl/renderer/tile_pyramid.cpp | 28 ++++++++++++++++++++++++++-- src/mbgl/renderer/update_parameters.hpp | 2 ++ 7 files changed, 56 insertions(+), 4 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 1b45c87c28..158e9d733d 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -156,6 +156,15 @@ public: AnnotationIDs queryPointAnnotations(const ScreenBox&); + // Tile prefetching + // + // When loading a map, if `PrefetchZoomDelta` is set to any number greater than 0, the map will + // first request a tile for `zoom = getZoom() - delta` in a attempt to display a full map at + // lower resolution as quick as possible. It will get clamped at the tile source minimum zoom. + // The default `delta` is 4. + void setPrefetchZoomDelta(uint8_t delta); + uint8_t getPrefetchZoomDelta() const; + // Memory void onLowMemory(); diff --git a/include/mbgl/util/constants.hpp b/include/mbgl/util/constants.hpp index 14aaa752bc..c2250c6f2e 100644 --- a/include/mbgl/util/constants.hpp +++ b/include/mbgl/util/constants.hpp @@ -38,6 +38,8 @@ constexpr double MAX_ZOOM = 25.5; constexpr float MIN_ZOOM_F = MIN_ZOOM; constexpr float MAX_ZOOM_F = MAX_ZOOM; +constexpr uint8_t DEFAULT_PREFETCH_ZOOM_DELTA = 4; + constexpr uint64_t DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024; constexpr Duration DEFAULT_TRANSITION_DURATION = Milliseconds(300); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 034e43f260..565d39c515 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,9 @@ public: std::unique_ptr renderStyle; bool cameraMutated = false; + + uint8_t prefetchZoomDelta = util::DEFAULT_PREFETCH_ZOOM_DELTA; + bool loading = false; util::AsyncTask asyncInvalidate; @@ -245,7 +249,8 @@ void Map::Impl::render(View& view) { style->impl->getLayerImpls(), scheduler, fileSource, - annotationManager + annotationManager, + prefetchZoomDelta }); bool loaded = style->impl->isLoaded() && renderStyle->isLoaded(); @@ -823,6 +828,14 @@ bool Map::isFullyLoaded() const { return impl->style->impl->isLoaded() && impl->renderStyle && impl->renderStyle->isLoaded(); } +void Map::setPrefetchZoomDelta(uint8_t delta) { + impl->prefetchZoomDelta = delta; +} + +uint8_t Map::getPrefetchZoomDelta() const { + return impl->prefetchZoomDelta; +} + void Map::onLowMemory() { if (impl->painter) { BackendScope guard(impl->backend); diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp index bae879dca7..aacabe563d 100644 --- a/src/mbgl/renderer/render_style.cpp +++ b/src/mbgl/renderer/render_style.cpp @@ -105,7 +105,8 @@ void RenderStyle::update(const UpdateParameters& parameters) { parameters.mode, parameters.annotationManager, *imageManager, - *glyphManager + *glyphManager, + parameters.prefetchZoomDelta }; glyphManager->setURL(parameters.glyphURL); diff --git a/src/mbgl/renderer/tile_parameters.hpp b/src/mbgl/renderer/tile_parameters.hpp index cf7a5b100a..9769ae6897 100644 --- a/src/mbgl/renderer/tile_parameters.hpp +++ b/src/mbgl/renderer/tile_parameters.hpp @@ -22,6 +22,7 @@ public: AnnotationManager& annotationManager; ImageManager& imageManager; GlyphManager& glyphManager; + const uint8_t prefetchZoomDelta = 0; }; } // namespace mbgl diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index caf55d64e8..a8e6c128ba 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -88,14 +88,30 @@ void TilePyramid::update(const std::vector>& layer // Determine the overzooming/underzooming amounts and required tiles. int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize); int32_t tileZoom = overscaledZoom; + int32_t panZoom = zoomRange.max; std::vector idealTiles; + std::vector panTiles; + if (overscaledZoom >= zoomRange.min) { int32_t idealZoom = std::min(zoomRange.max, overscaledZoom); // Make sure we're not reparsing overzoomed raster tiles. if (type == SourceType::Raster) { tileZoom = idealZoom; + + // FIXME: Prefetching is only enabled for raster + // tiles until we fix #7026. + + // Request lower zoom level tiles (if configure to do so) in an attempt + // to show something on the screen faster at the cost of a little of bandwidth. + if (parameters.prefetchZoomDelta) { + panZoom = std::max(tileZoom - parameters.prefetchZoomDelta, zoomRange.min); + } + + if (panZoom < tileZoom) { + panTiles = util::tileCover(parameters.transformState, panZoom); + } } idealTiles = util::tileCover(parameters.transformState, idealZoom); @@ -108,8 +124,10 @@ void TilePyramid::update(const std::vector>& layer std::set retain; auto retainTileFn = [&](Tile& tile, Resource::Necessity necessity) -> void { - retain.emplace(tile.id); - tile.setNecessity(necessity); + if (retain.emplace(tile.id).second) { + tile.setNecessity(necessity); + } + if (needsRelayout) { tile.setLayers(layers); } @@ -137,6 +155,12 @@ void TilePyramid::update(const std::vector>& layer }; renderTiles.clear(); + + if (!panTiles.empty()) { + algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, + [](const UnwrappedTileID&, Tile&) {}, panTiles, zoomRange, panZoom); + } + algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, renderTileFn, idealTiles, zoomRange, tileZoom); diff --git a/src/mbgl/renderer/update_parameters.hpp b/src/mbgl/renderer/update_parameters.hpp index ce79a4f31b..8ebcd11e21 100644 --- a/src/mbgl/renderer/update_parameters.hpp +++ b/src/mbgl/renderer/update_parameters.hpp @@ -33,6 +33,8 @@ public: Scheduler& scheduler; FileSource& fileSource; AnnotationManager& annotationManager; + + const uint8_t prefetchZoomDelta = 0; }; } // namespace mbgl -- cgit v1.2.1