diff options
author | Molly Lloyd <mollymerp@users.noreply.github.com> | 2018-01-23 10:49:23 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-23 10:49:23 -0800 |
commit | f3294200c6c866e5ab031ad8346c59a76aa37249 (patch) | |
tree | 6d9aedb552552607641a15c415a60be99a0877d5 /src/mbgl/tile | |
parent | 2d15aed43c9faa875a8f625c3afc286f1175e0ce (diff) | |
download | qtlocation-mapboxgl-f3294200c6c866e5ab031ad8346c59a76aa37249.tar.gz |
[core] add raster-dem source type and hillshade layer type (#10642)
Diffstat (limited to 'src/mbgl/tile')
-rw-r--r-- | src/mbgl/tile/raster_dem_tile.cpp | 124 | ||||
-rw-r--r-- | src/mbgl/tile/raster_dem_tile.hpp | 104 | ||||
-rw-r--r-- | src/mbgl/tile/raster_dem_tile_worker.cpp | 27 | ||||
-rw-r--r-- | src/mbgl/tile/raster_dem_tile_worker.hpp | 22 | ||||
-rw-r--r-- | src/mbgl/tile/raster_tile.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/tile/raster_tile.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/tile/tile.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/tile/tile.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/tile/tile_cache.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/tile/tile_cache.hpp | 3 |
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(); |