1 #include <mbgl/tile/raster_dem_tile.hpp>
2 #include <mbgl/tile/raster_dem_tile_worker.hpp>
3 #include <mbgl/tile/tile_observer.hpp>
4 #include <mbgl/tile/tile_loader_impl.hpp>
5 #include <mbgl/style/source.hpp>
6 #include <mbgl/storage/resource.hpp>
7 #include <mbgl/storage/response.hpp>
8 #include <mbgl/storage/file_source.hpp>
9 #include <mbgl/renderer/tile_parameters.hpp>
10 #include <mbgl/renderer/buckets/hillshade_bucket.hpp>
11 #include <mbgl/actor/scheduler.hpp>
12
13 namespace mbgl {
14
RasterDEMTile(const OverscaledTileID & id_,const TileParameters & parameters,const Tileset & tileset)15 RasterDEMTile::RasterDEMTile(const OverscaledTileID& id_,
16 const TileParameters& parameters,
17 const Tileset& tileset)
18 : Tile(id_),
19 loader(*this, id_, parameters, tileset),
20 mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())),
21 worker(parameters.workerScheduler,
22 ActorRef<RasterDEMTile>(*this, mailbox)) {
23
24 encoding = tileset.encoding;
25 if ( id.canonical.y == 0 ){
26 // this tile doesn't have upper neighboring tiles so marked those as backfilled
27 neighboringTiles = neighboringTiles | DEMTileNeighbors::NoUpper;
28 }
29
30 if (id.canonical.y + 1 == std::pow(2, id.canonical.z)){
31 // this tile doesn't have lower neighboring tiles so marked those as backfilled
32 neighboringTiles = neighboringTiles | DEMTileNeighbors::NoLower;
33 }
34 }
35
36 RasterDEMTile::~RasterDEMTile() = default;
37
setError(std::exception_ptr err)38 void RasterDEMTile::setError(std::exception_ptr err) {
39 loaded = true;
40 observer->onTileError(*this, err);
41 }
42
setMetadata(optional<Timestamp> modified_,optional<Timestamp> expires_)43 void RasterDEMTile::setMetadata(optional<Timestamp> modified_, optional<Timestamp> expires_) {
44 modified = modified_;
45 expires = expires_;
46 }
47
setData(std::shared_ptr<const std::string> data)48 void RasterDEMTile::setData(std::shared_ptr<const std::string> data) {
49 pending = true;
50 ++correlationID;
51 worker.self().invoke(&RasterDEMTileWorker::parse, data, correlationID, encoding);
52 }
53
onParsed(std::unique_ptr<HillshadeBucket> result,const uint64_t resultCorrelationID)54 void RasterDEMTile::onParsed(std::unique_ptr<HillshadeBucket> result, const uint64_t resultCorrelationID) {
55 bucket = std::move(result);
56 loaded = true;
57 if (resultCorrelationID == correlationID) {
58 pending = false;
59 }
60 renderable = bucket ? true : false;
61 observer->onTileChanged(*this);
62 }
63
onError(std::exception_ptr err,const uint64_t resultCorrelationID)64 void RasterDEMTile::onError(std::exception_ptr err, const uint64_t resultCorrelationID) {
65 loaded = true;
66 if (resultCorrelationID == correlationID) {
67 pending = false;
68 }
69 observer->onTileError(*this, err);
70 }
71
upload(gl::Context & context)72 void RasterDEMTile::upload(gl::Context& context) {
73 if (bucket) {
74 bucket->upload(context);
75 }
76 }
77
78
getBucket(const style::Layer::Impl &) const79 Bucket* RasterDEMTile::getBucket(const style::Layer::Impl&) const {
80 return bucket.get();
81 }
82
getBucket() const83 HillshadeBucket* RasterDEMTile::getBucket() const {
84 return bucket.get();
85 }
86
backfillBorder(const RasterDEMTile & borderTile,const DEMTileNeighbors mask)87 void RasterDEMTile::backfillBorder(const RasterDEMTile& borderTile, const DEMTileNeighbors mask) {
88 int32_t dx = borderTile.id.canonical.x - id.canonical.x;
89 const int8_t dy = borderTile.id.canonical.y - id.canonical.y;
90 const uint32_t dim = pow(2, id.canonical.z);
91 if (dx == 0 && dy == 0) return;
92 if (std::abs(dy) > 1) return;
93 // neighbor is in another world wrap
94 if (std::abs(dx) > 1) {
95 if (std::abs(int(dx + dim)) == 1) {
96 dx += dim;
97 } else if (std::abs(int(dx - dim)) == 1) {
98 dx -= dim;
99 }
100 }
101 const HillshadeBucket* borderBucket = borderTile.getBucket();
102 if (borderBucket) {
103 const DEMData& borderDEM = borderBucket->getDEMData();
104 DEMData& tileDEM = bucket->getDEMData();
105
106 tileDEM.backfillBorder(borderDEM, dx, dy);
107 // update the bitmask to indicate that this tiles have been backfilled by flipping the relevant bit
108 this->neighboringTiles = this->neighboringTiles | mask;
109 // mark HillshadeBucket.prepared as false so it runs through the prepare render pass
110 // with the new texture data we just backfilled
111 bucket->setPrepared(false);
112 }
113 }
114
setMask(TileMask && mask)115 void RasterDEMTile::setMask(TileMask&& mask) {
116 if (bucket) {
117 bucket->setMask(std::move(mask));
118 }
119 }
120
setNecessity(TileNecessity necessity)121 void RasterDEMTile::setNecessity(TileNecessity necessity) {
122 loader.setNecessity(necessity);
123 }
124
125 } // namespace mbgl
126