From f2754f9458cea294a078a9965e7e1f412f912981 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sun, 15 Jan 2017 11:27:52 -0500 Subject: [PATCH] [core] Prefetch low resolution tiles --- include/mbgl/map/map.hpp | 4 +++ src/mbgl/map/map.cpp | 15 ++++++++++- src/mbgl/style/source_impl.cpp | 37 ++++++++++++++++++++++------ src/mbgl/style/update_parameters.hpp | 11 +++++++-- src/mbgl/util/tile_cover.cpp | 4 +-- src/mbgl/util/tile_cover.hpp | 2 +- 6 files changed, 60 insertions(+), 13 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index c80420371dd..dcd0b88cd64 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -185,6 +185,10 @@ class Map : private util::noncopyable { std::vector queryRenderedFeatures(const ScreenBox&, const optional>& layerIDs = {}); AnnotationIDs queryPointAnnotations(const ScreenBox&); + // Tile prefatching + void setFixedPrefetchZoom(uint32_t); + void setDynamicPrefetchZoom(uint32_t); + // Memory void setSourceTileCacheSize(size_t); void onLowMemory(); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index e9d4d9e2475..9a0b40ce59b 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -95,6 +95,9 @@ class Map::Impl : public style::Observer { std::unique_ptr styleRequest; + uint32_t fixedPrefetchZoom = 0; + uint32_t dynamicPrefetchZoom = 0; + size_t sourceCacheSize; bool loading = false; @@ -251,7 +254,9 @@ void Map::Impl::render(View& view) { fileSource, mode, *annotationManager, - *style); + *style, + fixedPrefetchZoom, + dynamicPrefetchZoom); style->updateTiles(parameters); @@ -1064,6 +1069,14 @@ void Map::setSourceTileCacheSize(size_t size) { } } +void Map::setFixedPrefetchZoom(uint32_t zoom) { + impl->fixedPrefetchZoom = zoom; +} + +void Map::setDynamicPrefetchZoom(uint32_t zoom) { + impl->dynamicPrefetchZoom = zoom; +} + void Map::onLowMemory() { if (impl->painter) { BackendScope guard(impl->backend); diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp index 149bf99f9df..629f84d76eb 100644 --- a/src/mbgl/style/source_impl.cpp +++ b/src/mbgl/style/source_impl.cpp @@ -89,12 +89,15 @@ void Source::Impl::updateTiles(const UpdateParameters& parameters) { const Range zoomRange = getZoomRange(); // Determine the overzooming/underzooming amounts and required tiles. - int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize); - int32_t tileZoom = overscaledZoom; + uint32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize); + uint32_t tileZoom = overscaledZoom; + uint32_t lowResolutionZoom = 0; std::vector idealTiles; + std::vector lowResolutionTiles; + if (overscaledZoom >= zoomRange.min) { - int32_t idealZoom = std::min(zoomRange.max, overscaledZoom); + uint32_t idealZoom = std::min(zoomRange.max, overscaledZoom); // Make sure we're not reparsing overzoomed raster tiles. if (type == SourceType::Raster) { @@ -102,6 +105,18 @@ void Source::Impl::updateTiles(const UpdateParameters& parameters) { } idealTiles = util::tileCover(parameters.transformState, idealZoom); + + // 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. + lowResolutionZoom = parameters.fixedPrefetchZoom ? + parameters.fixedPrefetchZoom : + idealZoom - parameters.dynamicPrefetchZoom; + + lowResolutionZoom = lowResolutionZoom < zoomRange.min ? zoomRange.min : lowResolutionZoom; + + if (lowResolutionZoom < idealZoom) { + lowResolutionTiles = util::tileCover(parameters.transformState, lowResolutionZoom); + } } // Stores a list of all the tiles that we're definitely going to retain. There are two @@ -111,8 +126,10 @@ void Source::Impl::updateTiles(const UpdateParameters& parameters) { std::set retain; auto retainTileFn = [&retain](Tile& tile, Resource::Necessity necessity) -> void { - retain.emplace(tile.id); - tile.setNecessity(necessity); + if (retain.find(tile.id) == retain.end()) { + retain.emplace(tile.id); + tile.setNecessity(necessity); + } }; auto getTileFn = [this](const OverscaledTileID& tileID) -> Tile* { auto it = tiles.find(tileID); @@ -136,8 +153,14 @@ void Source::Impl::updateTiles(const UpdateParameters& parameters) { }; renderTiles.clear(); - algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, renderTileFn, - idealTiles, zoomRange, tileZoom); + + if (!lowResolutionTiles.empty()) { + algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, + [](const UnwrappedTileID&, Tile&) {}, lowResolutionTiles, zoomRange, lowResolutionZoom); + } + + algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, + renderTileFn, idealTiles, zoomRange, tileZoom); if (type != SourceType::Annotations && cache.getSize() == 0) { size_t conservativeCacheSize = diff --git a/src/mbgl/style/update_parameters.hpp b/src/mbgl/style/update_parameters.hpp index 900f4b51833..903dffbe0c9 100644 --- a/src/mbgl/style/update_parameters.hpp +++ b/src/mbgl/style/update_parameters.hpp @@ -22,7 +22,9 @@ class UpdateParameters { FileSource& fileSource_, const MapMode mode_, AnnotationManager& annotationManager_, - Style& style_) + Style& style_, + uint32_t fixedPrefetchZoom_, + uint32_t dynamicPrefetchZoom_) : pixelRatio(pixelRatio_), debugOptions(debugOptions_), transformState(transformState_), @@ -30,7 +32,9 @@ class UpdateParameters { fileSource(fileSource_), mode(mode_), annotationManager(annotationManager_), - style(style_) {} + style(style_), + fixedPrefetchZoom(fixedPrefetchZoom_), + dynamicPrefetchZoom(dynamicPrefetchZoom_) {} float pixelRatio; MapDebugOptions debugOptions; @@ -42,6 +46,9 @@ class UpdateParameters { // TODO: remove Style& style; + + const uint32_t fixedPrefetchZoom; + const uint32_t dynamicPrefetchZoom; }; } // namespace style diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp index 2fb7371aba9..92b45698ed5 100644 --- a/src/mbgl/util/tile_cover.cpp +++ b/src/mbgl/util/tile_cover.cpp @@ -127,8 +127,8 @@ std::vector tileCover(const Point& tl, } // namespace -int32_t coveringZoomLevel(double zoom, SourceType type, uint16_t size) { - zoom += std::log(util::tileSize / size) / std::log(2); +uint32_t coveringZoomLevel(double zoom, SourceType type, uint16_t size) { + zoom = std::max(0., zoom) + std::log(util::tileSize / size) / std::log(2); if (type == SourceType::Raster || type == SourceType::Video) { return ::round(zoom); } else { diff --git a/src/mbgl/util/tile_cover.hpp b/src/mbgl/util/tile_cover.hpp index 2d32d8bf41f..632676156c6 100644 --- a/src/mbgl/util/tile_cover.hpp +++ b/src/mbgl/util/tile_cover.hpp @@ -13,7 +13,7 @@ class LatLngBounds; namespace util { -int32_t coveringZoomLevel(double z, SourceType type, uint16_t tileSize); +uint32_t coveringZoomLevel(double z, SourceType type, uint16_t tileSize); std::vector tileCover(const TransformState&, int32_t z); std::vector tileCover(const LatLngBounds&, int32_t z);