diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/algorithm/update_tile_masks.hpp | 72 | ||||
-rw-r--r-- | src/mbgl/renderer/tile_mask.hpp | 11 | ||||
-rw-r--r-- | src/mbgl/tile/tile_id.hpp | 10 | ||||
-rw-r--r-- | src/mbgl/tile/tile_id_io.cpp | 5 |
4 files changed, 98 insertions, 0 deletions
diff --git a/src/mbgl/algorithm/update_tile_masks.hpp b/src/mbgl/algorithm/update_tile_masks.hpp new file mode 100644 index 0000000000..5c53f8f379 --- /dev/null +++ b/src/mbgl/algorithm/update_tile_masks.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include <mbgl/renderer/tile_mask.hpp> + +#include <vector> +#include <functional> +#include <algorithm> + +namespace mbgl { +namespace algorithm { + +namespace { + +template <typename Renderable> +void computeTileMasks( + const CanonicalTileID& root, + const UnwrappedTileID ref, + typename std::vector<std::reference_wrapper<Renderable>>::const_iterator it, + const typename std::vector<std::reference_wrapper<Renderable>>::const_iterator end, + TileMask& mask) { + // If the reference or any of its children is found in the list, we need to recurse. + for (; it != end; ++it) { + auto& renderable = it->get(); + if (!renderable.used) { + continue; + } + if (ref == renderable.id) { + // The current tile is masked out, so we don't need to add them to the mask set. + return; + } else if (renderable.id.isChildOf(ref)) { + // There's at least one child tile that is masked out, so recursively descend. + for (const auto& child : ref.children()) { + computeTileMasks<Renderable>(root, child, it, end, mask); + } + return; + } + } + // We couldn't find a child, so it's definitely a masked part. + mask.emplace(ref.canonical - root); +} + +} // namespace + +template <typename Renderable> +void updateTileMasks(std::vector<std::reference_wrapper<Renderable>> renderables) { + std::sort(renderables.begin(), renderables.end(), + [](const Renderable& a, const Renderable& b) { return a.id < b.id; }); + + const auto end = renderables.end(); + for (auto it = renderables.begin(); it != end; it++) { + auto& renderable = it->get(); + if (!renderable.used) { + continue; + } + // Try to add all remaining ids as children. We sorted the tile list + // by z earlier, so all preceding items cannot be children of the current + // tile. We also compute the lower bound of the next wrap, because items of the next wrap + // can never be children of the current wrap. + auto child_it = std::next(it); + const auto children_end = std::lower_bound( + child_it, end, + UnwrappedTileID{ static_cast<int16_t>(renderable.id.wrap + 1), { 0, 0, 0 } }, + [](auto& a, auto& b) { return a.get().id < b; }); + + renderable.mask.clear(); + computeTileMasks<Renderable>(renderable.id.canonical, renderable.id, child_it, children_end, + renderable.mask); + } +} + +} // namespace algorithm +} // namespace mbgl diff --git a/src/mbgl/renderer/tile_mask.hpp b/src/mbgl/renderer/tile_mask.hpp new file mode 100644 index 0000000000..a4cbff864f --- /dev/null +++ b/src/mbgl/renderer/tile_mask.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include <mbgl/tile/tile_id.hpp> + +#include <set> + +namespace mbgl { + +using TileMask = std::set<CanonicalTileID>; + +} // namespace mbgl diff --git a/src/mbgl/tile/tile_id.hpp b/src/mbgl/tile/tile_id.hpp index 1ce3eea98e..38adbaa107 100644 --- a/src/mbgl/tile/tile_id.hpp +++ b/src/mbgl/tile/tile_id.hpp @@ -28,6 +28,7 @@ public: bool operator<(const CanonicalTileID&) const; bool isChildOf(const CanonicalTileID&) const; CanonicalTileID scaledTo(uint8_t z) const; + CanonicalTileID operator-(const CanonicalTileID&) const; std::array<CanonicalTileID, 4> children() const; const uint8_t z; @@ -125,6 +126,15 @@ inline CanonicalTileID CanonicalTileID::scaledTo(uint8_t targetZ) const { } } +inline CanonicalTileID CanonicalTileID::operator-(const CanonicalTileID& rhs) const { + if (!isChildOf(rhs)) { + return { 0, 0, 0 }; + } else { + const uint8_t diffZ = z - rhs.z; + return { diffZ, x - (rhs.x << diffZ), y - (rhs.y << diffZ) }; + } +} + inline std::array<CanonicalTileID, 4> CanonicalTileID::children() const { const uint8_t childZ = z + 1; const uint32_t childX = x * 2; diff --git a/src/mbgl/tile/tile_id_io.cpp b/src/mbgl/tile/tile_id_io.cpp index f6adbf183f..d8be6b93d6 100644 --- a/src/mbgl/tile/tile_id_io.cpp +++ b/src/mbgl/tile/tile_id_io.cpp @@ -6,6 +6,8 @@ namespace mbgl { ::std::ostream& operator<<(::std::ostream& os, const CanonicalTileID& rhs) { + // Uncomment this to create code instead of shorthands. + // return os << "CanonicalTileID{ " << uint32_t(rhs.z) << ", " << rhs.x << ", " << rhs.y << " }"; return os << uint32_t(rhs.z) << "/" << rhs.x << "/" << rhs.y; } @@ -26,6 +28,9 @@ std::string toString(const OverscaledTileID& rhs) { } // namespace util ::std::ostream& operator<<(::std::ostream& os, const UnwrappedTileID& rhs) { + // Uncomment this to create code instead of shorthands. + // return os << "UnwrappedTileID{ " << uint32_t(rhs.wrap) << ", { " << uint32_t(rhs.canonical.z) + // << ", " << rhs.canonical.x << ", " << rhs.canonical.y << " } }"; return os << rhs.canonical << (rhs.wrap >= 0 ? "+" : "") << rhs.wrap; } |