diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-05-24 16:58:09 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2016-05-27 10:15:06 +0200 |
commit | 1b8d280e3fff3d9be1631dd960b9f426d329b36c (patch) | |
tree | b56eb79c9df4f79340f12203b6ee8b411721d425 /src/mbgl/algorithm | |
parent | ebff2234e42df1ad14c5e567f87271bc4d9274b2 (diff) | |
download | qtlocation-mapboxgl-1b8d280e3fff3d9be1631dd960b9f426d329b36c.tar.gz |
[core] refactor updateRenderables algorithm
Diffstat (limited to 'src/mbgl/algorithm')
-rw-r--r-- | src/mbgl/algorithm/update_renderables.hpp | 115 |
1 files changed, 65 insertions, 50 deletions
diff --git a/src/mbgl/algorithm/update_renderables.hpp b/src/mbgl/algorithm/update_renderables.hpp index 8948b8eafe..22d4205d90 100644 --- a/src/mbgl/algorithm/update_renderables.hpp +++ b/src/mbgl/algorithm/update_renderables.hpp @@ -2,65 +2,69 @@ #include <mbgl/tile/tile_id.hpp> -#include <map> +#include <set> namespace mbgl { namespace algorithm { -namespace { - -template <typename DataTiles, typename Renderables> -bool tryTile(const UnwrappedTileID& renderTileID, - const OverscaledTileID& dataTileID, - const DataTiles& dataTiles, - Renderables& renderables) { - if (renderables.find(renderTileID) == renderables.end()) { - const auto it = dataTiles.find(dataTileID); - if (it == dataTiles.end() || !it->second->isRenderable()) { - return false; - } - - using Renderable = typename Renderables::mapped_type; - renderables.emplace(renderTileID, Renderable{ renderTileID, *it->second }); - } - - return true; -} - -} // namespace - -template <typename Renderable, typename DataTiles, typename IdealTileIDs, typename SourceInfo> -std::map<UnwrappedTileID, Renderable> updateRenderables(const DataTiles& dataTiles, - const IdealTileIDs& idealTileIDs, - const SourceInfo& info, - const uint8_t z) { - std::map<UnwrappedTileID, Renderable> renderables; +template <typename GetTileDataFn, + typename CreateTileDataFn, + typename RetainTileDataFn, + typename RenderTileFn, + typename IdealTileIDs, + typename SourceInfo> +void updateRenderables(GetTileDataFn getTileData, + CreateTileDataFn createTileData, + RetainTileDataFn retainTileData, + RenderTileFn renderTile, + const IdealTileIDs& idealTileIDs, + const SourceInfo& info, + const uint8_t dataTileZoom) { + std::set<UnwrappedTileID> checked; + bool covered; + int32_t overscaledZ; // for (all in the set of ideal tiles of the source) { - for (const auto& renderTileID : idealTileIDs) { - assert(renderTileID.canonical.z >= info.minZoom); - assert(renderTileID.canonical.z <= info.maxZoom); - assert(z >= renderTileID.canonical.z); - const auto wrap = renderTileID.wrap; - const OverscaledTileID dataTileID(z, renderTileID.canonical); + for (const auto& idealRenderTileID : idealTileIDs) { + assert(idealRenderTileID.canonical.z >= info.minZoom); + assert(idealRenderTileID.canonical.z <= info.maxZoom); + assert(dataTileZoom >= idealRenderTileID.canonical.z); + + const OverscaledTileID idealDataTileID(dataTileZoom, idealRenderTileID.canonical); + auto data = getTileData(idealDataTileID); + if (!data) { + data = createTileData(idealDataTileID); + assert(data); + } // if (source has the tile and bucket is loaded) { - if (!tryTile(renderTileID, dataTileID, dataTiles, renderables)) { - // The source doesn't have the tile, or the bucket isn't loaded. - bool covered = true; - int32_t overscaledZ = z + 1; + if (data->isRenderable()) { + retainTileData(*data); + renderTile(idealRenderTileID, *data); + } else { + // The tile isn't loaded yet, but retain it anyway because it's an ideal tile. + retainTileData(*data); + covered = true; + overscaledZ = dataTileZoom + 1; if (overscaledZ > info.maxZoom) { // We're looking for an overzoomed child tile. - const auto childDataTileID = dataTileID.scaledTo(overscaledZ); - if (!tryTile(renderTileID, childDataTileID, dataTiles, renderables)) { + const auto childDataTileID = idealDataTileID.scaledTo(overscaledZ); + data = getTileData(childDataTileID); + if (data && data->isRenderable()) { + retainTileData(*data); + renderTile(idealRenderTileID, *data); + } else { covered = false; } } else { // Check all four actual child tiles. - for (const auto& childTileID : dataTileID.canonical.children()) { + for (const auto& childTileID : idealDataTileID.canonical.children()) { const OverscaledTileID childDataTileID(overscaledZ, childTileID); - const UnwrappedTileID childRenderTileID(wrap, childTileID); - if (!tryTile(childRenderTileID, childDataTileID, dataTiles, renderables)) { + data = getTileData(childDataTileID); + if (data && data->isRenderable()) { + retainTileData(*data); + renderTile(childDataTileID.unwrapTo(idealRenderTileID.wrap), *data); + } else { // At least one child tile doesn't exist, so we are going to look for // parents as well. covered = false; @@ -70,10 +74,23 @@ std::map<UnwrappedTileID, Renderable> updateRenderables(const DataTiles& dataTil if (!covered) { // We couldn't find child tiles that entirely cover the ideal tile. - for (overscaledZ = z - 1; overscaledZ >= info.minZoom; --overscaledZ) { - const auto parentDataTileID = dataTileID.scaledTo(overscaledZ); - const auto parentRenderTileID = parentDataTileID.unwrapTo(renderTileID.wrap); - if (tryTile(parentRenderTileID, parentDataTileID, dataTiles, renderables)) { + for (overscaledZ = dataTileZoom - 1; overscaledZ >= info.minZoom; --overscaledZ) { + const auto parentDataTileID = idealDataTileID.scaledTo(overscaledZ); + const auto parentRenderTileID = + parentDataTileID.unwrapTo(idealRenderTileID.wrap); + + if (checked.find(parentRenderTileID) != checked.end()) { + // Break parent tile ascent, this route has been checked by another child + // tile before. + break; + } else { + checked.emplace(parentRenderTileID); + } + + data = getTileData(parentDataTileID); + if (data && data->isRenderable()) { + retainTileData(*data); + renderTile(parentRenderTileID, *data); // Break parent tile ascent, since we found one. break; } @@ -81,8 +98,6 @@ std::map<UnwrappedTileID, Renderable> updateRenderables(const DataTiles& dataTil } } } - - return renderables; } } // namespace algorithm |