summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/algorithm/update_tile_masks.hpp72
-rw-r--r--src/mbgl/renderer/tile_mask.hpp11
-rw-r--r--src/mbgl/tile/tile_id.hpp10
-rw-r--r--src/mbgl/tile/tile_id_io.cpp5
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;
}