From e5713f31a64b0ae0237a22aa3b4e44bc245e05c5 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 9 Apr 2014 11:38:42 -0700 Subject: [PATCH] move to raster buckets & tile parser handling raster decoding --- include/llmr/map/tile_parser.hpp | 6 ++- include/llmr/renderer/painter.hpp | 3 +- include/llmr/renderer/raster_bucket.hpp | 20 ++++++++ include/llmr/style/bucket_description.hpp | 4 +- src/map/source.cpp | 15 +++--- src/map/tile_data.cpp | 10 +--- src/map/tile_parser.cpp | 56 +++++++++++++++-------- src/renderer/painter.cpp | 7 ++- src/renderer/raster_bucket.cpp | 14 ++++++ 9 files changed, 95 insertions(+), 40 deletions(-) create mode 100644 include/llmr/renderer/raster_bucket.hpp create mode 100644 src/renderer/raster_bucket.cpp diff --git a/include/llmr/map/tile_parser.hpp b/include/llmr/map/tile_parser.hpp index b99f9aaf9..ee623f1ff 100644 --- a/include/llmr/map/tile_parser.hpp +++ b/include/llmr/map/tile_parser.hpp @@ -8,7 +8,7 @@ namespace llmr { class TileParser { public: - TileParser(const std::string& data, TileData& tile, const Style& style, GlyphAtlas& glyphAtlas); + TileParser(const std::string& data, TileData& tile, const Style& style, GlyphAtlas& glyphAtlas, bool is_raster = false); private: bool obsolete() const; @@ -19,10 +19,12 @@ private: std::unique_ptr createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); std::unique_ptr createPointBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); std::unique_ptr createTextBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc); + std::unique_ptr createRasterBucket(const BucketDescription& bucket_desc); template void addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const BucketDescription& bucket_desc); private: - const VectorTile data; + const VectorTile vector_data; + const std::string raster_data; TileData& tile; const Style& style; GlyphAtlas& glyphAtlas; diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index fd3c84d3f..c5abbd01d 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -28,6 +28,7 @@ class FillBucket; class LineBucket; class PointBucket; class TextBucket; +class RasterBucket; class Painter : private util::noncopyable { public: @@ -42,6 +43,7 @@ public: void renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderPoint(PointBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& id); + void renderRaster(const std::string& layer_name, const std::shared_ptr& tile_data); void resize(int width, int height); @@ -52,7 +54,6 @@ public: bool needsAnimation() const; private: void setupShaders(); - void renderRaster(const std::string& layer_name, const std::shared_ptr& tile_data); void renderLayers(const std::shared_ptr& tile, const std::vector& layers); void renderLayer(const std::shared_ptr& tile_data, const LayerDescription& layer_desc); void renderDebug(const std::shared_ptr& tile); diff --git a/include/llmr/renderer/raster_bucket.hpp b/include/llmr/renderer/raster_bucket.hpp new file mode 100644 index 000000000..88bb3bd84 --- /dev/null +++ b/include/llmr/renderer/raster_bucket.hpp @@ -0,0 +1,20 @@ +#ifndef LLMR_RENDERER_RASTERBUCKET +#define LLMR_RENDERER_RASTERBUCKET + +#include +#include + +namespace llmr { + +class BucketDescription; + +class RasterBucket : public Bucket { +public: + RasterBucket(const BucketDescription& bucket_desc); + + virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id); +}; + +} + +#endif diff --git a/include/llmr/style/bucket_description.hpp b/include/llmr/style/bucket_description.hpp index 498e935f2..e7cde3db8 100644 --- a/include/llmr/style/bucket_description.hpp +++ b/include/llmr/style/bucket_description.hpp @@ -14,7 +14,8 @@ enum class BucketType { Fill = 1, Line = 2, Point = 3, - Text = 4 + Text = 4, + Raster = 5 }; enum class CapType { @@ -42,6 +43,7 @@ inline BucketType bucketType(const std::string& type) { else if (type == "line") return BucketType::Line; else if (type == "point") return BucketType::Point; else if (type == "text") return BucketType::Text; + else if (type == "raster") return BucketType::Raster; else return BucketType::None; } diff --git a/src/map/source.cpp b/src/map/source.cpp index 2f692b8f0..1a1b224e8 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -52,12 +52,15 @@ void Source::render(bool is_baselayer) { for (const Tile& tile : tiles) { if (tile.data && tile.data->state == TileData::State::parsed) { - if (type == Type::raster && *tile.data->raster && !tile.data->raster->textured) { - tile.data->raster->setTexturepool(&texturepool); - tile.data->raster->beginFadeInAnimation(); - } - if (type == Type::raster && tile.data->raster->needsAnimation()) { - tile.data->raster->updateAnimations(); + if (type == Type::raster) { + std::shared_ptr raster = tile.data->raster; + if (raster && !raster->textured) { + raster->setTexturepool(&texturepool); + raster->beginFadeInAnimation(); + } + if (raster && raster->needsAnimation()) { + raster->updateAnimations(); + } } painter.render(tile); } diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 7e615c70e..fabd8634a 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -70,19 +70,11 @@ bool TileData::parse() { return false; } - if (is_raster) { - // raster tiles don't need parsed, just decoded - raster = std::make_shared(); - raster->load(data); - state = State::parsed; - return true; - } - try { // Parsing creates state that is encapsulated in TileParser. While parsing, // the TileParser object writes results into this objects. All other state // is going to be discarded afterwards. - TileParser parser(data, *this, style, glyphAtlas); + TileParser parser(data, *this, style, glyphAtlas, is_raster); } catch (const std::exception& ex) { fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what()); cancel(); diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp index c21b6b961..9e75fe3f7 100644 --- a/src/map/tile_parser.cpp +++ b/src/map/tile_parser.cpp @@ -5,19 +5,22 @@ #include #include #include +#include +#include #include using namespace llmr; -TileParser::TileParser(const std::string& data, TileData& tile, const Style& style, GlyphAtlas& glyphAtlas) - : data(pbf((const uint8_t *)data.data(), data.size())), +TileParser::TileParser(const std::string& data, TileData& tile, const Style& style, GlyphAtlas& glyphAtlas, bool is_raster) + : vector_data(is_raster ? pbf(0, 0) : pbf((const uint8_t *)data.data(), data.size())), + raster_data(is_raster ? data : ""), tile(tile), style(style), glyphAtlas(glyphAtlas), - placement(tile.id.z) { - parseGlyphs(); + placement(is_raster ? 0 : tile.id.z) { + if (!is_raster) parseGlyphs(); parseStyleLayers(style.layers); } @@ -26,7 +29,7 @@ bool TileParser::obsolete() const { } void TileParser::parseGlyphs() { - for (const std::pair pair : data.faces) { + for (const std::pair pair : vector_data.faces) { const std::string &name = pair.first; const VectorTileFace &face = pair.second; @@ -77,22 +80,30 @@ void TileParser::parseStyleLayers(const std::vector& layers) { } std::unique_ptr TileParser::createBucket(const BucketDescription& bucket_desc) { - auto layer_it = data.layers.find(bucket_desc.source_layer); - if (layer_it != data.layers.end()) { - const VectorTileLayer& layer = layer_it->second; - if (bucket_desc.type == BucketType::Fill) { - return createFillBucket(layer, bucket_desc); - } else if (bucket_desc.type == BucketType::Line) { - return createLineBucket(layer, bucket_desc); - } else if (bucket_desc.type == BucketType::Point) { - return createPointBucket(layer, bucket_desc); - } else if (bucket_desc.type == BucketType::Text) { - return createTextBucket(layer, bucket_desc); - } else { - throw std::runtime_error("unknown bucket type"); + if (bucket_desc.type == BucketType::Raster) { + if (raster_data.length()) { + tile.raster = std::make_shared(); + tile.raster->load(raster_data); } + return createRasterBucket(bucket_desc); } else { - // The layer specified in the bucket does not exist. Do nothing. + auto layer_it = vector_data.layers.find(bucket_desc.source_layer); + if (layer_it != vector_data.layers.end()) { + const VectorTileLayer& layer = layer_it->second; + if (bucket_desc.type == BucketType::Fill) { + return createFillBucket(layer, bucket_desc); + } else if (bucket_desc.type == BucketType::Line) { + return createLineBucket(layer, bucket_desc); + } else if (bucket_desc.type == BucketType::Point) { + return createPointBucket(layer, bucket_desc); + } else if (bucket_desc.type == BucketType::Text) { + return createTextBucket(layer, bucket_desc); + } else { + throw std::runtime_error("unknown bucket type"); + } + } else { + // The layer specified in the bucket does not exist. Do nothing. + } } return nullptr; @@ -166,3 +177,10 @@ std::unique_ptr TileParser::createTextBucket(const VectorTileLayer& laye return std::move(bucket); } + +std::unique_ptr TileParser::createRasterBucket(const BucketDescription& bucket_desc) { + std::unique_ptr bucket = std::make_unique(bucket_desc); + // Raster buckets are just empty dummies so that they behave + // similarly to vector buckets in styling configurations. + return obsolete() ? nullptr : std::move(bucket); +} diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 994016aaa..453dcba41 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -209,8 +210,10 @@ void Painter::renderLayer(const std::shared_ptr& tile_data, const Laye } else { // This is a singular layer. Try to find the bucket associated with // this layer and render it. - if (layer_desc.name == "satellite" && tile_data && tile_data->raster) { // FIXME - renderRaster(layer_desc.name, tile_data); + if (style.buckets[layer_desc.bucket_name].type == BucketType::Raster) { + if (tile_data && tile_data->raster) { + renderRaster(layer_desc.name, tile_data); + } } else { auto bucket_it = tile_data->buckets.find(layer_desc.bucket_name); if (bucket_it != tile_data->buckets.end()) { diff --git a/src/renderer/raster_bucket.cpp b/src/renderer/raster_bucket.cpp new file mode 100644 index 000000000..54f7dc639 --- /dev/null +++ b/src/renderer/raster_bucket.cpp @@ -0,0 +1,14 @@ +#include +#include + +using namespace llmr; + +RasterBucket::RasterBucket(const BucketDescription& bucket_desc) { +} + +void RasterBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) { + // The painter renders rasters directly. This function is a no-op + // and exists just to satisfy the abstract superclass requirements. + // That way, we can avoid having raster buckets pass around + // references to tile data and/or rasters directly. +}