summaryrefslogtreecommitdiff
path: root/src/mbgl/algorithm/update_renderables_impl.hpp
blob: d7221be21c8fb8232bef2e4767c9f98bcc45df25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifndef MBGL_ALGORITHM_UPDATE_RENDERABLES_IMPL
#define MBGL_ALGORITHM_UPDATE_RENDERABLES_IMPL

#include <mbgl/algorithm/update_renderables.hpp>
#include <mbgl/tile/tile_id.hpp>

#include <map>

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->isReady()) {
            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;

    // 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);

        // 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 (overscaledZ > info.maxZoom) {
                // We're looking for an overzoomed child tile.
                const auto childDataTileID = dataTileID.scaledTo(overscaledZ);
                if (!tryTile(renderTileID, childDataTileID, dataTiles, renderables)) {
                    covered = false;
                }
            } else {
                // Check all four actual child tiles.
                for (const auto& childTileID : dataTileID.canonical.children()) {
                    const OverscaledTileID childDataTileID(overscaledZ, childTileID);
                    const UnwrappedTileID childRenderTileID(wrap, childTileID);
                    if (!tryTile(childRenderTileID, childDataTileID, dataTiles, renderables)) {
                        // At least one child tile doesn't exist, so we are going to look for
                        // parents as well.
                        covered = false;
                    }
                }
            }

            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)) {
                        // Break parent tile ascent, since we found one.
                        break;
                    }
                }
            }
        }
    }

    return renderables;
}

} // namespace algorithm
} // namespace mbgl

#endif