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/renderer/sources | |
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/renderer/sources')
-rw-r--r-- | src/mbgl/renderer/sources/render_raster_dem_source.cpp | 165 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_raster_dem_source.hpp | 54 |
2 files changed, 219 insertions, 0 deletions
diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.cpp b/src/mbgl/renderer/sources/render_raster_dem_source.cpp new file mode 100644 index 0000000000..76716518d7 --- /dev/null +++ b/src/mbgl/renderer/sources/render_raster_dem_source.cpp @@ -0,0 +1,165 @@ +#include <mbgl/renderer/sources/render_raster_dem_source.hpp> +#include <mbgl/renderer/render_tile.hpp> +#include <mbgl/tile/raster_dem_tile.hpp> +#include <mbgl/algorithm/update_tile_masks.hpp> +#include <mbgl/geometry/dem_data.hpp> +#include <mbgl/renderer/buckets/hillshade_bucket.hpp> +#include <iostream> + +namespace mbgl { + +using namespace style; + +RenderRasterDEMSource::RenderRasterDEMSource(Immutable<style::RasterSource::Impl> impl_) + : RenderSource(impl_) { + tilePyramid.setObserver(this); +} + +const style::RasterSource::Impl& RenderRasterDEMSource::impl() const { + return static_cast<const style::RasterSource::Impl&>(*baseImpl); +} + +bool RenderRasterDEMSource::isLoaded() const { + return tilePyramid.isLoaded(); +} + +void RenderRasterDEMSource::update(Immutable<style::Source::Impl> baseImpl_, + const std::vector<Immutable<Layer::Impl>>& layers, + const bool needsRendering, + const bool needsRelayout, + const TileParameters& parameters) { + std::swap(baseImpl, baseImpl_); + + enabled = needsRendering; + + optional<Tileset> tileset = impl().getTileset(); + + if (!tileset) { + return; + } + + if (tileURLTemplates != tileset->tiles) { + tileURLTemplates = tileset->tiles; + + // TODO: this removes existing buckets, and will cause flickering. + // Should instead refresh tile data in place. + tilePyramid.tiles.clear(); + tilePyramid.renderTiles.clear(); + tilePyramid.cache.clear(); + } + + tilePyramid.update(layers, + needsRendering, + needsRelayout, + parameters, + SourceType::RasterDEM, + impl().getTileSize(), + tileset->zoomRange, + tileset->bounds, + [&] (const OverscaledTileID& tileID) { + return std::make_unique<RasterDEMTile>(tileID, parameters, *tileset); + }); +} + +void RenderRasterDEMSource::onTileChanged(Tile& tile){ + RasterDEMTile& demtile = static_cast<RasterDEMTile&>(tile); + + std::map<DEMTileNeighbors, DEMTileNeighbors> opposites = { + { DEMTileNeighbors::Left, DEMTileNeighbors::Right }, + { DEMTileNeighbors::Right, DEMTileNeighbors::Left }, + { DEMTileNeighbors::TopLeft, DEMTileNeighbors::BottomRight }, + { DEMTileNeighbors::TopCenter, DEMTileNeighbors::BottomCenter }, + { DEMTileNeighbors::TopRight, DEMTileNeighbors::BottomLeft }, + { DEMTileNeighbors::BottomRight, DEMTileNeighbors::TopLeft }, + { DEMTileNeighbors::BottomCenter, DEMTileNeighbors:: TopCenter }, + { DEMTileNeighbors::BottomLeft, DEMTileNeighbors::TopRight } + }; + + if (tile.isRenderable() && demtile.neighboringTiles != DEMTileNeighbors::Complete) { + const CanonicalTileID canonical = tile.id.canonical; + const uint32_t dim = std::pow(2, canonical.z); + const uint32_t px = (canonical.x - 1 + dim) % dim; + const int pxw = canonical.x == 0 ? tile.id.wrap - 1 : tile.id.wrap; + const uint32_t nx = (canonical.x + 1 + dim) % dim; + const int nxw = (canonical.x + 1 == dim) ? tile.id.wrap + 1 : tile.id.wrap; + + auto getNeighbor = [&] (DEMTileNeighbors mask){ + if (mask == DEMTileNeighbors::Left){ + return OverscaledTileID(tile.id.overscaledZ, pxw, canonical.z, px, canonical.y); + } else if (mask == DEMTileNeighbors::Right){ + return OverscaledTileID(tile.id.overscaledZ, nxw, canonical.z, nx, canonical.y); + } else if (mask == DEMTileNeighbors::TopLeft){ + return OverscaledTileID(tile.id.overscaledZ, pxw, canonical.z, px, canonical.y - 1); + } else if (mask == DEMTileNeighbors::TopCenter){ + return OverscaledTileID(tile.id.overscaledZ, tile.id.wrap, canonical.z, canonical.x, canonical.y - 1); + } else if (mask == DEMTileNeighbors::TopRight){ + return OverscaledTileID(tile.id.overscaledZ, nxw, canonical.z, nx, canonical.y - 1); + } else if (mask == DEMTileNeighbors::BottomLeft){ + return OverscaledTileID(tile.id.overscaledZ, pxw, canonical.z, px, canonical.y + 1); + } else if (mask == DEMTileNeighbors::BottomCenter){ + return OverscaledTileID(tile.id.overscaledZ, tile.id.wrap, canonical.z, canonical.x, canonical.y + 1); + } else if (mask == DEMTileNeighbors::BottomRight){ + return OverscaledTileID(tile.id.overscaledZ, nxw, canonical.z, nx, canonical.y + 1); + } else{ + throw std::runtime_error("mask is not a valid tile neighbor"); + } + }; + + for (uint8_t i = 0; i < 8; i++) { + DEMTileNeighbors mask = DEMTileNeighbors(std::pow(2,i)); + // only backfill if this neighbor has not been previously backfilled + if ((demtile.neighboringTiles & mask) != mask) { + OverscaledTileID neighborid = getNeighbor(mask); + Tile* renderableNeighbor = tilePyramid.getTile(neighborid); + if (renderableNeighbor != nullptr && renderableNeighbor->isRenderable()) { + RasterDEMTile& borderTile = static_cast<RasterDEMTile&>(*renderableNeighbor); + demtile.backfillBorder(borderTile, mask); + + // if the border tile has not been backfilled by a previous instance of the main + // tile, backfill its corresponding neighbor as well. + const DEMTileNeighbors& borderMask = opposites[mask]; + if ((borderTile.neighboringTiles & borderMask) != borderMask){ + borderTile.backfillBorder(demtile, borderMask); + } + } + } + } + } + RenderSource::onTileChanged(tile); +} + +void RenderRasterDEMSource::startRender(PaintParameters& parameters) { + algorithm::updateTileMasks(tilePyramid.getRenderTiles()); + tilePyramid.startRender(parameters); +} + +void RenderRasterDEMSource::finishRender(PaintParameters& parameters) { + tilePyramid.finishRender(parameters); +} + +std::vector<std::reference_wrapper<RenderTile>> RenderRasterDEMSource::getRenderTiles() { + return tilePyramid.getRenderTiles(); +} + +std::unordered_map<std::string, std::vector<Feature>> +RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&, + const TransformState&, + const std::vector<const RenderLayer*>&, + const RenderedQueryOptions&, + const CollisionIndex& ) const { + return std::unordered_map<std::string, std::vector<Feature>> {}; +} + +std::vector<Feature> RenderRasterDEMSource::querySourceFeatures(const SourceQueryOptions&) const { + return {}; +} + +void RenderRasterDEMSource::onLowMemory() { + tilePyramid.onLowMemory(); +} + +void RenderRasterDEMSource::dumpDebugLogs() const { + tilePyramid.dumpDebugLogs(); +} + +} // namespace mbgl diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.hpp b/src/mbgl/renderer/sources/render_raster_dem_source.hpp new file mode 100644 index 0000000000..b6b8bf977c --- /dev/null +++ b/src/mbgl/renderer/sources/render_raster_dem_source.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include <mbgl/renderer/render_source.hpp> +#include <mbgl/renderer/tile_pyramid.hpp> +#include <mbgl/style/sources/raster_source_impl.hpp> + +namespace mbgl { + +class RenderRasterDEMSource : public RenderSource { +public: + RenderRasterDEMSource(Immutable<style::RasterSource::Impl>); + + bool isLoaded() const final; + + void update(Immutable<style::Source::Impl>, + const std::vector<Immutable<style::Layer::Impl>>&, + bool needsRendering, + bool needsRelayout, + const TileParameters&) final; + + void startRender(PaintParameters&) final; + void finishRender(PaintParameters&) final; + + std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final; + + std::unordered_map<std::string, std::vector<Feature>> + queryRenderedFeatures(const ScreenLineString& geometry, + const TransformState& transformState, + const std::vector<const RenderLayer*>& layers, + const RenderedQueryOptions& options, + const CollisionIndex& collisionIndex) const final; + + std::vector<Feature> + querySourceFeatures(const SourceQueryOptions&) const final; + + void onLowMemory() final; + void dumpDebugLogs() const final; + +private: + const style::RasterSource::Impl& impl() const; + + TilePyramid tilePyramid; + optional<std::vector<std::string>> tileURLTemplates; + +protected: + void onTileChanged(Tile&) final; +}; + +template <> +inline bool RenderSource::is<RenderRasterDEMSource>() const { + return baseImpl->type == style::SourceType::RasterDEM; +} + +} // namespace mbgl |