summaryrefslogtreecommitdiff
path: root/src/mbgl/tile
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/tile')
-rw-r--r--src/mbgl/tile/raster_dem_tile.cpp124
-rw-r--r--src/mbgl/tile/raster_dem_tile.hpp104
-rw-r--r--src/mbgl/tile/raster_dem_tile_worker.cpp27
-rw-r--r--src/mbgl/tile/raster_dem_tile_worker.hpp22
-rw-r--r--src/mbgl/tile/raster_tile.cpp3
-rw-r--r--src/mbgl/tile/raster_tile.hpp4
-rw-r--r--src/mbgl/tile/tile.cpp3
-rw-r--r--src/mbgl/tile/tile.hpp2
-rw-r--r--src/mbgl/tile/tile_cache.cpp13
-rw-r--r--src/mbgl/tile/tile_cache.hpp3
10 files changed, 295 insertions, 10 deletions
diff --git a/src/mbgl/tile/raster_dem_tile.cpp b/src/mbgl/tile/raster_dem_tile.cpp
new file mode 100644
index 0000000000..b270378ece
--- /dev/null
+++ b/src/mbgl/tile/raster_dem_tile.cpp
@@ -0,0 +1,124 @@
+#include <mbgl/tile/raster_dem_tile.hpp>
+#include <mbgl/tile/raster_dem_tile_worker.hpp>
+#include <mbgl/tile/tile_observer.hpp>
+#include <mbgl/tile/tile_loader_impl.hpp>
+#include <mbgl/style/source.hpp>
+#include <mbgl/storage/resource.hpp>
+#include <mbgl/storage/response.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/renderer/tile_parameters.hpp>
+#include <mbgl/renderer/buckets/hillshade_bucket.hpp>
+#include <mbgl/actor/scheduler.hpp>
+
+namespace mbgl {
+
+RasterDEMTile::RasterDEMTile(const OverscaledTileID& id_,
+ const TileParameters& parameters,
+ const Tileset& tileset)
+ : Tile(id_),
+ loader(*this, id_, parameters, tileset),
+ mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())),
+ worker(parameters.workerScheduler,
+ ActorRef<RasterDEMTile>(*this, mailbox)) {
+
+ if ( id.canonical.y == 0 ){
+ // this tile doesn't have upper neighboring tiles so marked those as backfilled
+ neighboringTiles = neighboringTiles | DEMTileNeighbors::NoUpper;
+ }
+
+ if (id.canonical.y + 1 == std::pow(2, id.canonical.z)){
+ // this tile doesn't have lower neighboring tiles so marked those as backfilled
+ neighboringTiles = neighboringTiles | DEMTileNeighbors::NoLower;
+ }
+}
+
+RasterDEMTile::~RasterDEMTile() = default;
+
+void RasterDEMTile::setError(std::exception_ptr err) {
+ loaded = true;
+ observer->onTileError(*this, err);
+}
+
+void RasterDEMTile::setMetadata(optional<Timestamp> modified_, optional<Timestamp> expires_) {
+ modified = modified_;
+ expires = expires_;
+}
+
+void RasterDEMTile::setData(std::shared_ptr<const std::string> data) {
+ pending = true;
+ ++correlationID;
+ worker.invoke(&RasterDEMTileWorker::parse, data, correlationID);
+}
+
+void RasterDEMTile::onParsed(std::unique_ptr<HillshadeBucket> result, const uint64_t resultCorrelationID) {
+ bucket = std::move(result);
+ loaded = true;
+ if (resultCorrelationID == correlationID) {
+ pending = false;
+ }
+ renderable = bucket ? true : false;
+ observer->onTileChanged(*this);
+}
+
+void RasterDEMTile::onError(std::exception_ptr err, const uint64_t resultCorrelationID) {
+ loaded = true;
+ if (resultCorrelationID == correlationID) {
+ pending = false;
+ }
+ observer->onTileError(*this, err);
+}
+
+void RasterDEMTile::upload(gl::Context& context) {
+ if (bucket) {
+ bucket->upload(context);
+ }
+}
+
+
+Bucket* RasterDEMTile::getBucket(const style::Layer::Impl&) const {
+ return bucket.get();
+}
+
+HillshadeBucket* RasterDEMTile::getBucket() const {
+ return bucket.get();
+}
+
+void RasterDEMTile::backfillBorder(const RasterDEMTile& borderTile, const DEMTileNeighbors mask) {
+ int32_t dx = borderTile.id.canonical.x - id.canonical.x;
+ const int8_t dy = borderTile.id.canonical.y - id.canonical.y;
+ const uint32_t dim = pow(2, id.canonical.z);
+ if (dx == 0 && dy == 0) return;
+ if (std::abs(dy) > 1) return;
+ // neighbor is in another world wrap
+ if (std::abs(dx) > 1) {
+ if (std::abs(int(dx + dim)) == 1) {
+ dx += dim;
+ } else if (std::abs(int(dx - dim)) == 1) {
+ dx -= dim;
+ }
+ }
+ const HillshadeBucket* borderBucket = borderTile.getBucket();
+ if (borderBucket) {
+ const DEMData& borderDEM = borderBucket->getDEMData();
+ DEMData& tileDEM = bucket->getDEMData();
+
+ tileDEM.backfillBorder(borderDEM, dx, dy);
+ // update the bitmask to indicate that this tiles have been backfilled by flipping the relevant bit
+ this->neighboringTiles = this->neighboringTiles | mask;
+ // mark HillshadeBucket.prepared as false so it runs through the prepare render pass
+ // with the new texture data we just backfilled
+ bucket->setPrepared(false);
+ }
+}
+
+void RasterDEMTile::setMask(TileMask&& mask) {
+ if (bucket) {
+ bucket->setMask(std::move(mask));
+ }
+}
+
+void RasterDEMTile::setNecessity(TileNecessity necessity) {
+ loader.setNecessity(necessity);
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/tile/raster_dem_tile.hpp b/src/mbgl/tile/raster_dem_tile.hpp
new file mode 100644
index 0000000000..68f8a91e00
--- /dev/null
+++ b/src/mbgl/tile/raster_dem_tile.hpp
@@ -0,0 +1,104 @@
+#pragma once
+
+#include <mbgl/tile/tile.hpp>
+#include <mbgl/tile/tile_loader.hpp>
+#include <mbgl/tile/raster_dem_tile_worker.hpp>
+#include <mbgl/actor/actor.hpp>
+
+namespace mbgl {
+
+class Tileset;
+class TileParameters;
+class HillshadeBucket;
+
+enum class DEMTileNeighbors : uint8_t {
+ // 0b00000000
+ Empty = 0 << 1,
+
+ // 0b00000001
+ Left = 1 << 0,
+ // 0b00000010
+ Right = 1 << 1,
+ // 0b00000100
+ TopLeft = 1 << 2,
+ // 0b00001000
+ TopCenter = 1 << 3,
+ // 0b00010000
+ TopRight = 1 << 4,
+ // 0b00100000
+ BottomLeft = 1 << 5,
+ // 0b01000000
+ BottomCenter = 1 << 6,
+ // 0b10000000
+ BottomRight = 1 << 7,
+
+ // helper enums for tiles with no upper/lower neighbors
+ // and completely backfilled tiles
+
+ // 0b00011100
+ NoUpper = 0b00011100,
+ // 0b11100000
+ NoLower = 0b11100000,
+ // 0b11111111
+ Complete = 0b11111111
+};
+
+inline DEMTileNeighbors operator|(DEMTileNeighbors a, DEMTileNeighbors b) {
+ return static_cast<DEMTileNeighbors>(int(a) | int(b));
+};
+
+inline DEMTileNeighbors operator&(DEMTileNeighbors a, DEMTileNeighbors b) {
+ return static_cast<DEMTileNeighbors>(int(a) & int(b));
+}
+
+inline bool operator!=(DEMTileNeighbors a, DEMTileNeighbors b) {
+ return static_cast<unsigned char>(a) != static_cast<unsigned char>(b);
+}
+
+namespace style {
+class Layer;
+} // namespace style
+
+class RasterDEMTile : public Tile {
+public:
+ RasterDEMTile(const OverscaledTileID&,
+ const TileParameters&,
+ const Tileset&);
+ ~RasterDEMTile() override;
+
+ void setNecessity(TileNecessity) final;
+
+ void setError(std::exception_ptr);
+ void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
+ void setData(std::shared_ptr<const std::string> data);
+
+ void upload(gl::Context&) override;
+ Bucket* getBucket(const style::Layer::Impl&) const override;
+
+ HillshadeBucket* getBucket() const;
+ void backfillBorder(const RasterDEMTile& borderTile, const DEMTileNeighbors mask);
+
+ // neighboringTiles is a bitmask for which neighboring tiles have been backfilled
+ // there are max 8 possible neighboring tiles, so each bit represents one neighbor
+ DEMTileNeighbors neighboringTiles = DEMTileNeighbors::Empty;
+
+ void setMask(TileMask&&) override;
+
+ void onParsed(std::unique_ptr<HillshadeBucket> result, uint64_t correlationID);
+ void onError(std::exception_ptr, uint64_t correlationID);
+
+private:
+ TileLoader<RasterDEMTile> loader;
+
+ std::shared_ptr<Mailbox> mailbox;
+ Actor<RasterDEMTileWorker> worker;
+
+ uint64_t correlationID = 0;
+
+ // Contains the Bucket object for the tile. Buckets are render
+ // objects and they get added by tile parsing operations.
+ std::unique_ptr<HillshadeBucket> bucket;
+
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/tile/raster_dem_tile_worker.cpp b/src/mbgl/tile/raster_dem_tile_worker.cpp
new file mode 100644
index 0000000000..ed8573788f
--- /dev/null
+++ b/src/mbgl/tile/raster_dem_tile_worker.cpp
@@ -0,0 +1,27 @@
+#include <mbgl/tile/raster_dem_tile_worker.hpp>
+#include <mbgl/tile/raster_dem_tile.hpp>
+#include <mbgl/renderer/buckets/hillshade_bucket.hpp>
+#include <mbgl/actor/actor.hpp>
+#include <mbgl/util/premultiply.hpp>
+
+namespace mbgl {
+
+RasterDEMTileWorker::RasterDEMTileWorker(ActorRef<RasterDEMTileWorker>, ActorRef<RasterDEMTile> parent_)
+ : parent(std::move(parent_)) {
+}
+
+void RasterDEMTileWorker::parse(std::shared_ptr<const std::string> data, uint64_t correlationID) {
+ if (!data) {
+ parent.invoke(&RasterDEMTile::onParsed, nullptr, correlationID); // No data; empty tile.
+ return;
+ }
+
+ try {
+ auto bucket = std::make_unique<HillshadeBucket>(decodeImage(*data));
+ parent.invoke(&RasterDEMTile::onParsed, std::move(bucket), correlationID);
+ } catch (...) {
+ parent.invoke(&RasterDEMTile::onError, std::current_exception(), correlationID);
+ }
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/tile/raster_dem_tile_worker.hpp b/src/mbgl/tile/raster_dem_tile_worker.hpp
new file mode 100644
index 0000000000..14fd1f43b5
--- /dev/null
+++ b/src/mbgl/tile/raster_dem_tile_worker.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <mbgl/actor/actor_ref.hpp>
+
+#include <memory>
+#include <string>
+
+namespace mbgl {
+
+class RasterDEMTile;
+
+class RasterDEMTileWorker {
+public:
+ RasterDEMTileWorker(ActorRef<RasterDEMTileWorker>, ActorRef<RasterDEMTile>);
+
+ void parse(std::shared_ptr<const std::string> data, uint64_t correlationID);
+
+private:
+ ActorRef<RasterDEMTile> parent;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/tile/raster_tile.cpp b/src/mbgl/tile/raster_tile.cpp
index 85fcea77b7..ff23d4493e 100644
--- a/src/mbgl/tile/raster_tile.cpp
+++ b/src/mbgl/tile/raster_tile.cpp
@@ -24,9 +24,6 @@ RasterTile::RasterTile(const OverscaledTileID& id_,
RasterTile::~RasterTile() = default;
-void RasterTile::cancel() {
-}
-
void RasterTile::setError(std::exception_ptr err) {
loaded = true;
observer->onTileError(*this, err);
diff --git a/src/mbgl/tile/raster_tile.hpp b/src/mbgl/tile/raster_tile.hpp
index 192769ed8f..e25329119a 100644
--- a/src/mbgl/tile/raster_tile.hpp
+++ b/src/mbgl/tile/raster_tile.hpp
@@ -20,7 +20,7 @@ public:
RasterTile(const OverscaledTileID&,
const TileParameters&,
const Tileset&);
- ~RasterTile() final;
+ ~RasterTile() override;
void setNecessity(TileNecessity) final;
@@ -28,8 +28,6 @@ public:
void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
void setData(std::shared_ptr<const std::string> data);
- void cancel() override;
-
void upload(gl::Context&) override;
Bucket* getBucket(const style::Layer::Impl&) const override;
diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp
index 85899a98cb..88db2ba07c 100644
--- a/src/mbgl/tile/tile.cpp
+++ b/src/mbgl/tile/tile.cpp
@@ -18,6 +18,9 @@ void Tile::setObserver(TileObserver* observer_) {
observer = observer_;
}
+void Tile::cancel() {
+}
+
void Tile::setTriedCache() {
triedOptional = true;
observer->onTileChanged(*this);
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index 1bed180f3d..23365c6ae3 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -43,7 +43,7 @@ public:
virtual void setNecessity(TileNecessity) {}
// Mark this tile as no longer needed and cancel any pending work.
- virtual void cancel() = 0;
+ virtual void cancel();
virtual void upload(gl::Context&) = 0;
virtual Bucket* getBucket(const style::Layer::Impl&) const = 0;
diff --git a/src/mbgl/tile/tile_cache.cpp b/src/mbgl/tile/tile_cache.cpp
index 3fafb1259c..463d397608 100644
--- a/src/mbgl/tile/tile_cache.cpp
+++ b/src/mbgl/tile/tile_cache.cpp
@@ -33,13 +33,22 @@ void TileCache::add(const OverscaledTileID& key, std::unique_ptr<Tile> tile) {
// purge oldest key/tile if necessary
if (orderedKeys.size() > size) {
- get(orderedKeys.front());
+ pop(orderedKeys.front());
}
assert(orderedKeys.size() <= size);
}
-std::unique_ptr<Tile> TileCache::get(const OverscaledTileID& key) {
+Tile* TileCache::get(const OverscaledTileID& key) {
+ auto it = tiles.find(key);
+ if (it != tiles.end()) {
+ return it->second.get();
+ } else {
+ return nullptr;
+ }
+}
+
+std::unique_ptr<Tile> TileCache::pop(const OverscaledTileID& key) {
std::unique_ptr<Tile> tile;
diff --git a/src/mbgl/tile/tile_cache.hpp b/src/mbgl/tile/tile_cache.hpp
index 80fe98a20c..88358b8cdc 100644
--- a/src/mbgl/tile/tile_cache.hpp
+++ b/src/mbgl/tile/tile_cache.hpp
@@ -17,7 +17,8 @@ public:
void setSize(size_t);
size_t getSize() const { return size; };
void add(const OverscaledTileID& key, std::unique_ptr<Tile> data);
- std::unique_ptr<Tile> get(const OverscaledTileID& key);
+ std::unique_ptr<Tile> pop(const OverscaledTileID& key);
+ Tile* get(const OverscaledTileID& key);
bool has(const OverscaledTileID& key);
void clear();