From 5c7dfd948ffd52f2b60dcfe052176da788f17893 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 13 Jun 2016 10:59:33 -0700 Subject: [PATCH] =?UTF-8?q?[core]=20*Tile=20=E2=86=94=20*TileData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tile is now the main base class; RasterTile, VectorTile, etc are its subclasses. GeometryTileData and its subclasses form the piece that's passed to the worker. --- benchmark/parse/filter.cpp | 2 +- src/mbgl/algorithm/update_renderables.hpp | 34 +- src/mbgl/annotation/annotation_manager.cpp | 24 +- src/mbgl/annotation/annotation_manager.hpp | 8 +- src/mbgl/annotation/annotation_tile.cpp | 18 +- src/mbgl/annotation/annotation_tile.hpp | 8 +- src/mbgl/annotation/shape_annotation_impl.cpp | 4 +- src/mbgl/annotation/shape_annotation_impl.hpp | 4 +- src/mbgl/geometry/feature_index.cpp | 10 +- src/mbgl/geometry/feature_index.hpp | 6 +- src/mbgl/renderer/circle_bucket.hpp | 2 +- src/mbgl/renderer/debug_bucket.hpp | 2 +- src/mbgl/renderer/fill_bucket.hpp | 2 +- src/mbgl/renderer/line_bucket.hpp | 2 +- src/mbgl/renderer/painter.hpp | 4 +- src/mbgl/renderer/painter_debug.cpp | 28 +- src/mbgl/renderer/render_tile.hpp | 6 +- src/mbgl/renderer/symbol_bucket.cpp | 2 +- src/mbgl/renderer/symbol_bucket.hpp | 2 +- src/mbgl/style/bucket_parameters.cpp | 2 +- src/mbgl/style/filter_evaluator.hpp | 2 +- src/mbgl/style/layer_impl.hpp | 2 +- src/mbgl/style/parser.cpp | 2 +- src/mbgl/style/source.cpp | 84 ++-- src/mbgl/style/source.hpp | 18 +- src/mbgl/style/style.cpp | 6 +- src/mbgl/text/check_max_angle.hpp | 2 +- src/mbgl/text/collision_feature.hpp | 2 +- src/mbgl/text/get_anchors.hpp | 2 +- src/mbgl/text/quads.cpp | 2 +- src/mbgl/text/quads.hpp | 2 +- src/mbgl/tile/geojson_tile.cpp | 32 +- src/mbgl/tile/geojson_tile.hpp | 13 +- src/mbgl/tile/geometry_tile.cpp | 352 +++++++++-------- src/mbgl/tile/geometry_tile.hpp | 133 +++---- src/mbgl/tile/geometry_tile_data.cpp | 364 +++++++++--------- src/mbgl/tile/geometry_tile_data.hpp | 140 +++---- .../{raster_tile_data.cpp => raster_tile.cpp} | 26 +- .../{raster_tile_data.hpp => raster_tile.hpp} | 10 +- src/mbgl/tile/tile.cpp | 37 ++ src/mbgl/tile/{tile_data.hpp => tile.hpp} | 18 +- src/mbgl/tile/tile_cache.cpp | 26 +- src/mbgl/tile/tile_cache.hpp | 8 +- src/mbgl/tile/tile_data.cpp | 37 -- src/mbgl/tile/tile_data_observer.hpp | 18 - src/mbgl/tile/tile_observer.hpp | 18 + src/mbgl/tile/tile_source.hpp | 2 +- src/mbgl/tile/tile_source_impl.hpp | 12 +- src/mbgl/tile/tile_worker.cpp | 10 +- src/mbgl/tile/tile_worker.hpp | 8 +- src/mbgl/tile/vector_tile.cpp | 34 +- src/mbgl/tile/vector_tile.hpp | 14 +- src/mbgl/util/intersection_tests.hpp | 2 +- src/mbgl/util/worker.cpp | 10 +- src/mbgl/util/worker.hpp | 2 +- test/style/filter.cpp | 2 +- test/test.gypi | 2 +- ...ometry_tile.cpp => geometry_tile_data.cpp} | 10 +- 58 files changed, 814 insertions(+), 820 deletions(-) rename src/mbgl/tile/{raster_tile_data.cpp => raster_tile.cpp} (69%) rename src/mbgl/tile/{raster_tile_data.hpp => raster_tile.hpp} (85%) create mode 100644 src/mbgl/tile/tile.cpp rename src/mbgl/tile/{tile_data.hpp => tile.hpp} (85%) delete mode 100644 src/mbgl/tile/tile_data.cpp delete mode 100644 src/mbgl/tile/tile_data_observer.hpp create mode 100644 src/mbgl/tile/tile_observer.hpp rename test/tile/{geometry_tile.cpp => geometry_tile_data.cpp} (88%) diff --git a/benchmark/parse/filter.cpp b/benchmark/parse/filter.cpp index 9e47bcaca..7450fc780 100644 --- a/benchmark/parse/filter.cpp +++ b/benchmark/parse/filter.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include diff --git a/src/mbgl/algorithm/update_renderables.hpp b/src/mbgl/algorithm/update_renderables.hpp index 5ef8e5fbc..eebabbd21 100644 --- a/src/mbgl/algorithm/update_renderables.hpp +++ b/src/mbgl/algorithm/update_renderables.hpp @@ -7,15 +7,15 @@ namespace mbgl { namespace algorithm { -template -void updateRenderables(GetTileDataFn getTileData, - CreateTileDataFn createTileData, - RetainTileDataFn retainTileData, +void updateRenderables(GetTileFn getTile, + CreateTileFn createTile, + RetainTileFn retainTile, RenderTileFn renderTile, const IdealTileIDs& idealTileIDs, const SourceInfo& info, @@ -31,29 +31,29 @@ void updateRenderables(GetTileDataFn getTileData, assert(dataTileZoom >= idealRenderTileID.canonical.z); const OverscaledTileID idealDataTileID(dataTileZoom, idealRenderTileID.canonical); - auto data = getTileData(idealDataTileID); + auto data = getTile(idealDataTileID); if (!data) { - data = createTileData(idealDataTileID); + data = createTile(idealDataTileID); assert(data); } // if (source has the tile and bucket is loaded) { if (data->isRenderable()) { - retainTileData(*data, true); + retainTile(*data, true); renderTile(idealRenderTileID, *data); } else { bool triedPrevious = data->hasTriedOptional(); // The tile isn't loaded yet, but retain it anyway because it's an ideal tile. - retainTileData(*data, true); + retainTile(*data, true); covered = true; overscaledZ = dataTileZoom + 1; if (overscaledZ > info.maxZoom) { // We're looking for an overzoomed child tile. const auto childDataTileID = idealDataTileID.scaledTo(overscaledZ); - data = getTileData(childDataTileID); + data = getTile(childDataTileID); if (data && data->isRenderable()) { - retainTileData(*data, false); + retainTile(*data, false); renderTile(idealRenderTileID, *data); } else { covered = false; @@ -62,9 +62,9 @@ void updateRenderables(GetTileDataFn getTileData, // Check all four actual child tiles. for (const auto& childTileID : idealDataTileID.canonical.children()) { const OverscaledTileID childDataTileID(overscaledZ, childTileID); - data = getTileData(childDataTileID); + data = getTile(childDataTileID); if (data && data->isRenderable()) { - retainTileData(*data, false); + retainTile(*data, false); renderTile(childDataTileID.unwrapTo(idealRenderTileID.wrap), *data); } else { // At least one child tile doesn't exist, so we are going to look for @@ -89,14 +89,14 @@ void updateRenderables(GetTileDataFn getTileData, checked.emplace(parentRenderTileID); } - data = getTileData(parentDataTileID); + data = getTile(parentDataTileID); if (!data && triedPrevious) { - data = createTileData(parentDataTileID); + data = createTile(parentDataTileID); } if (data) { triedPrevious = data->hasTriedOptional(); - retainTileData(*data, false); + retainTile(*data, false); if (data->isRenderable()) { renderTile(parentRenderTileID, *data); diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index 5b87b41f6..c6fb4546d 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -80,13 +80,13 @@ AnnotationIDs AnnotationManager::getPointAnnotationsInBounds(const LatLngBounds& return result; } -std::unique_ptr AnnotationManager::getTile(const CanonicalTileID& tileID) { +std::unique_ptr AnnotationManager::getTileData(const CanonicalTileID& tileID) { if (symbolAnnotations.empty() && shapeAnnotations.empty()) return nullptr; - auto tile = std::make_unique(); + auto tileData = std::make_unique(); - AnnotationTileLayer& pointLayer = *tile->layers.emplace( + AnnotationTileLayer& pointLayer = *tileData->layers.emplace( PointLayerID, std::make_unique(PointLayerID)).first->second; @@ -98,10 +98,10 @@ std::unique_ptr AnnotationManager::getTile(const CanonicalTileID })); for (const auto& shape : shapeAnnotations) { - shape.second->updateTile(tileID, *tile); + shape.second->updateTileData(tileID, *tileData); } - return tile; + return tileData; } void AnnotationManager::updateStyle(Style& style) { @@ -134,18 +134,18 @@ void AnnotationManager::updateStyle(Style& style) { obsoleteShapeAnnotationLayers.clear(); - for (auto& data : monitors) { - data->setData(getTile(data->id.canonical), {}, {}); + for (auto& tile : tiles) { + tile->setData(getTileData(tile->id.canonical), {}, {}); } } -void AnnotationManager::addTileData(AnnotationTileData& data) { - monitors.insert(&data); - data.setData(getTile(data.id.canonical), {}, {}); +void AnnotationManager::addTile(AnnotationTile& tile) { + tiles.insert(&tile); + tile.setData(getTileData(tile.id.canonical), {}, {}); } -void AnnotationManager::removeTileData(AnnotationTileData& data) { - monitors.erase(&data); +void AnnotationManager::removeTile(AnnotationTile& tile) { + tiles.erase(&tile); } void AnnotationManager::addIcon(const std::string& name, std::shared_ptr sprite) { diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index 228536612..73b6a00a4 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -41,8 +41,8 @@ public: void updateStyle(style::Style&); - void addTileData(AnnotationTileData&); - void removeTileData(AnnotationTileData&); + void addTile(AnnotationTile&); + void removeTile(AnnotationTile&); static const std::string SourceID; static const std::string PointLayerID; @@ -53,7 +53,7 @@ private: void add(const AnnotationID&, const FillAnnotation&, const uint8_t); void add(const AnnotationID&, const StyleSourcedAnnotation&, const uint8_t); - std::unique_ptr getTile(const CanonicalTileID&); + std::unique_ptr getTileData(const CanonicalTileID&); AnnotationID nextID = 0; @@ -65,7 +65,7 @@ private: SymbolAnnotationMap symbolAnnotations; ShapeAnnotationMap shapeAnnotations; std::vector obsoleteShapeAnnotationLayers; - std::set monitors; + std::set tiles; SpriteStore spriteStore; SpriteAtlas spriteAtlas; diff --git a/src/mbgl/annotation/annotation_tile.cpp b/src/mbgl/annotation/annotation_tile.cpp index 48415c4f3..92234f500 100644 --- a/src/mbgl/annotation/annotation_tile.cpp +++ b/src/mbgl/annotation/annotation_tile.cpp @@ -8,19 +8,19 @@ namespace mbgl { -AnnotationTileData::AnnotationTileData(const OverscaledTileID& overscaledTileID, - std::string sourceID, - const style::UpdateParameters& parameters) - : GeometryTileData(overscaledTileID, sourceID, parameters.style, parameters.mode), +AnnotationTile::AnnotationTile(const OverscaledTileID& overscaledTileID, + std::string sourceID, + const style::UpdateParameters& parameters) + : GeometryTile(overscaledTileID, sourceID, parameters.style, parameters.mode), annotationManager(parameters.annotationManager) { - annotationManager.addTileData(*this); + annotationManager.addTile(*this); } -AnnotationTileData::~AnnotationTileData() { - annotationManager.removeTileData(*this); +AnnotationTile::~AnnotationTile() { + annotationManager.removeTile(*this); } -void AnnotationTileData::setNecessity(Necessity) {} +void AnnotationTile::setNecessity(Necessity) {} AnnotationTileFeature::AnnotationTileFeature(FeatureType type_, GeometryCollection geometries_, std::unordered_map properties_) @@ -39,7 +39,7 @@ optional AnnotationTileFeature::getValue(const std::string& key) const { AnnotationTileLayer::AnnotationTileLayer(const std::string &name_) : name(name_) {} -util::ptr AnnotationTile::getLayer(const std::string& name) const { +util::ptr AnnotationTileData::getLayer(const std::string& name) const { auto it = layers.find(name); if (it != layers.end()) { return it->second; diff --git a/src/mbgl/annotation/annotation_tile.hpp b/src/mbgl/annotation/annotation_tile.hpp index 004625366..1a0ae1b7e 100644 --- a/src/mbgl/annotation/annotation_tile.hpp +++ b/src/mbgl/annotation/annotation_tile.hpp @@ -11,12 +11,12 @@ namespace style { class UpdateParameters; } -class AnnotationTileData : public GeometryTileData { +class AnnotationTile : public GeometryTile { public: - AnnotationTileData(const OverscaledTileID&, + AnnotationTile(const OverscaledTileID&, std::string sourceID, const style::UpdateParameters&); - ~AnnotationTileData(); + ~AnnotationTile(); void setNecessity(Necessity) final; @@ -52,7 +52,7 @@ private: std::string name; }; -class AnnotationTile : public GeometryTile { +class AnnotationTileData : public GeometryTileData { public: util::ptr getLayer(const std::string&) const override; diff --git a/src/mbgl/annotation/shape_annotation_impl.cpp b/src/mbgl/annotation/shape_annotation_impl.cpp index be6e12558..c9d13e648 100644 --- a/src/mbgl/annotation/shape_annotation_impl.cpp +++ b/src/mbgl/annotation/shape_annotation_impl.cpp @@ -85,7 +85,7 @@ private: } }; -void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTile& tile) { +void ShapeAnnotationImpl::updateTileData(const CanonicalTileID& tileID, AnnotationTileData& data) { static const double baseTolerance = 4; if (!shapeTiler) { @@ -108,7 +108,7 @@ void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTi if (!shapeTile) return; - AnnotationTileLayer& layer = *tile.layers.emplace(layerID, + AnnotationTileLayer& layer = *data.layers.emplace(layerID, std::make_unique(layerID)).first->second; for (auto& shapeFeature : shapeTile.features) { diff --git a/src/mbgl/annotation/shape_annotation_impl.hpp b/src/mbgl/annotation/shape_annotation_impl.hpp index e6ba9a4bd..60762f248 100644 --- a/src/mbgl/annotation/shape_annotation_impl.hpp +++ b/src/mbgl/annotation/shape_annotation_impl.hpp @@ -9,7 +9,7 @@ namespace mbgl { -class AnnotationTile; +class AnnotationTileData; class CanonicalTileID; namespace style { @@ -24,7 +24,7 @@ public: virtual void updateStyle(style::Style&) const = 0; virtual const ShapeAnnotationGeometry& geometry() const = 0; - void updateTile(const CanonicalTileID&, AnnotationTile&); + void updateTileData(const CanonicalTileID&, AnnotationTileData&); const AnnotationID id; const uint8_t maxZoom; diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp index 8c1034491..6d6521917 100644 --- a/src/mbgl/geometry/feature_index.cpp +++ b/src/mbgl/geometry/feature_index.cpp @@ -57,7 +57,7 @@ void FeatureIndex::query( const double tileSize, const double scale, const optional>& filterLayerIDs, - const GeometryTile& geometryTile, + const GeometryTileData& geometryTileData, const CanonicalTileID& tileID, const style::Style& style) const { @@ -75,7 +75,7 @@ void FeatureIndex::query( if (indexedFeature.sortIndex == previousSortIndex) continue; previousSortIndex = indexedFeature.sortIndex; - addFeature(result, indexedFeature, queryGeometry, filterLayerIDs, geometryTile, tileID, style, bearing, pixelsToTileUnits); + addFeature(result, indexedFeature, queryGeometry, filterLayerIDs, geometryTileData, tileID, style, bearing, pixelsToTileUnits); } // query symbol features @@ -83,7 +83,7 @@ void FeatureIndex::query( std::vector symbolFeatures = collisionTile->queryRenderedSymbols(box, scale); std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols); for (const auto& symbolFeature : symbolFeatures) { - addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTile, tileID, style, bearing, pixelsToTileUnits); + addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTileData, tileID, style, bearing, pixelsToTileUnits); } } @@ -92,7 +92,7 @@ void FeatureIndex::addFeature( const IndexedSubfeature& indexedFeature, const GeometryCollection& queryGeometry, const optional>& filterLayerIDs, - const GeometryTile& geometryTile, + const GeometryTileData& geometryTileData, const CanonicalTileID& tileID, const style::Style& style, const float bearing, @@ -103,7 +103,7 @@ void FeatureIndex::addFeature( return; } - auto sourceLayer = geometryTile.getLayer(indexedFeature.sourceLayerName); + auto sourceLayer = geometryTileData.getLayer(indexedFeature.sourceLayerName); assert(sourceLayer); auto geometryTileFeature = sourceLayer->getFeature(indexedFeature.index); diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp index c944a9813..2825cce69 100644 --- a/src/mbgl/geometry/feature_index.hpp +++ b/src/mbgl/geometry/feature_index.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include @@ -40,7 +40,7 @@ public: const double tileSize, const double scale, const optional>& layerIDs, - const GeometryTile&, + const GeometryTileData&, const CanonicalTileID&, const style::Style&) const; @@ -61,7 +61,7 @@ private: const IndexedSubfeature&, const GeometryCollection& queryGeometry, const optional>& filterLayerIDs, - const GeometryTile&, + const GeometryTileData&, const CanonicalTileID&, const style::Style&, const float bearing, diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index fa34aa088..041207a6c 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp index d69014bb8..737b58112 100644 --- a/src/mbgl/renderer/debug_bucket.hpp +++ b/src/mbgl/renderer/debug_bucket.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -8,6 +7,7 @@ namespace mbgl { +class OverscaledTileID; class PlainShader; namespace gl { diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index 35d70d169..3387ab374 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index d746f29c7..db5e74cd3 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index cfffb9092..7fe040562 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -32,7 +32,7 @@ class SpriteAtlas; class GlyphAtlas; class LineAtlas; struct FrameData; -class TileData; +class Tile; class DebugBucket; class FillBucket; @@ -100,7 +100,7 @@ public: void renderClipMasks(); - void renderDebugText(TileData&, const mat4&); + void renderDebugText(Tile&, const mat4&); void renderFill(FillBucket&, const style::FillLayer&, const UnwrappedTileID&, const mat4&); void renderLine(LineBucket&, const style::LineLayer&, const UnwrappedTileID&, const mat4&); void renderCircle(CircleBucket&, const style::CircleLayer&, const UnwrappedTileID&, const mat4&); diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp index 5071b209c..92fb3e586 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -16,7 +16,7 @@ void Painter::renderTileDebug(const RenderTile& tile) { if (frame.debugOptions != MapDebugOptions::NoDebug) { setClipping(tile.clip); if (frame.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) { - renderDebugText(tile.data, tile.matrix); + renderDebugText(tile.tile, tile.matrix); } if (frame.debugOptions & MapDebugOptions::TileBorders) { renderDebugFrame(tile.matrix); @@ -24,19 +24,19 @@ void Painter::renderTileDebug(const RenderTile& tile) { } } -void Painter::renderDebugText(TileData& tileData, const mat4 &matrix) { +void Painter::renderDebugText(Tile& tile, const mat4 &matrix) { MBGL_DEBUG_GROUP("debug text"); config.depthTest = GL_FALSE; - if (!tileData.debugBucket || tileData.debugBucket->renderable != tileData.isRenderable() || - tileData.debugBucket->complete != tileData.isComplete() || - !(tileData.debugBucket->modified == tileData.modified) || - !(tileData.debugBucket->expires == tileData.expires) || - tileData.debugBucket->debugMode != frame.debugOptions) { - tileData.debugBucket = std::make_unique( - tileData.id, tileData.isRenderable(), tileData.isComplete(), tileData.modified, - tileData.expires, frame.debugOptions); + if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() || + tile.debugBucket->complete != tile.isComplete() || + !(tile.debugBucket->modified == tile.modified) || + !(tile.debugBucket->expires == tile.expires) || + tile.debugBucket->debugMode != frame.debugOptions) { + tile.debugBucket = std::make_unique( + tile.id, tile.isRenderable(), tile.isComplete(), tile.modified, + tile.expires, frame.debugOptions); } config.program = plainShader->getID(); @@ -45,18 +45,18 @@ void Painter::renderDebugText(TileData& tileData, const mat4 &matrix) { // Draw white outline plainShader->u_color = {{ 1.0f, 1.0f, 1.0f, 1.0f }}; config.lineWidth = 4.0f * frame.pixelRatio; - tileData.debugBucket->drawLines(*plainShader, store); + tile.debugBucket->drawLines(*plainShader, store); #ifndef GL_ES_VERSION_2_0 // Draw line "end caps" MBGL_CHECK_ERROR(glPointSize(2)); - tileData.debugBucket->drawPoints(*plainShader, store); + tile.debugBucket->drawPoints(*plainShader, store); #endif // Draw black text. plainShader->u_color = {{ 0.0f, 0.0f, 0.0f, 1.0f }}; config.lineWidth = 2.0f * frame.pixelRatio; - tileData.debugBucket->drawLines(*plainShader, store); + tile.debugBucket->drawLines(*plainShader, store); config.depthFunc.reset(); config.depthTest = GL_TRUE; diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp index e2405b535..cb18504c8 100644 --- a/src/mbgl/renderer/render_tile.hpp +++ b/src/mbgl/renderer/render_tile.hpp @@ -7,11 +7,11 @@ namespace mbgl { -class TileData; +class Tile; class RenderTile { public: - RenderTile(const UnwrappedTileID& id_, TileData& data_) : id(id_), data(data_) { + RenderTile(const UnwrappedTileID& id_, Tile& tile_) : id(id_), tile(tile_) { } RenderTile(const RenderTile&) = delete; @@ -20,7 +20,7 @@ public: RenderTile& operator=(RenderTile&&) = default; const UnwrappedTileID id; - TileData& data; + Tile& tile; ClipID clip; mat4 matrix; }; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index ff2c80c14..e12522cb4 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index 314d44bde..47f3c5257 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/src/mbgl/style/bucket_parameters.cpp b/src/mbgl/style/bucket_parameters.cpp index f3367d57e..1a928dcec 100644 --- a/src/mbgl/style/bucket_parameters.cpp +++ b/src/mbgl/style/bucket_parameters.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include namespace mbgl { namespace style { diff --git a/src/mbgl/style/filter_evaluator.hpp b/src/mbgl/style/filter_evaluator.hpp index e03beaa4d..12da37924 100644 --- a/src/mbgl/style/filter_evaluator.hpp +++ b/src/mbgl/style/filter_evaluator.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp index dcd5d9906..34fc6b273 100644 --- a/src/mbgl/style/layer_impl.hpp +++ b/src/mbgl/style/layer_impl.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp index fb82a2084..8e632ac6a 100644 --- a/src/mbgl/style/parser.cpp +++ b/src/mbgl/style/parser.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp index 412bb9afc..cd87eb658 100644 --- a/src/mbgl/style/source.cpp +++ b/src/mbgl/style/source.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include @@ -62,7 +62,7 @@ Source::~Source() = default; bool Source::isLoaded() const { if (!loaded) return false; - for (const auto& pair : tileDataMap) { + for (const auto& pair : tiles) { if (!pair.second->isComplete()) { return false; } @@ -155,7 +155,7 @@ void Source::load(FileSource& fileSource) { if (reloadTiles) { // Tile information changed because we got new GeoJSON data, or a new tile URL. - tileDataMap.clear(); + tiles.clear(); renderTiles.clear(); cache.clear(); } @@ -185,17 +185,17 @@ const std::map& Source::getRenderTiles() const { return renderTiles; } -std::unique_ptr Source::createTile(const OverscaledTileID& overscaledTileID, +std::unique_ptr Source::createTile(const OverscaledTileID& overscaledTileID, const UpdateParameters& parameters) { // If we don't find working tile data, we're just going to load it. if (type == SourceType::Raster) { - return std::make_unique(overscaledTileID, parameters, *tileset); + return std::make_unique(overscaledTileID, parameters, *tileset); } else if (type == SourceType::Vector) { - return std::make_unique(overscaledTileID, id, parameters, *tileset); + return std::make_unique(overscaledTileID, id, parameters, *tileset); } else if (type == SourceType::Annotations) { - return std::make_unique(overscaledTileID, id, parameters); + return std::make_unique(overscaledTileID, id, parameters); } else if (type == SourceType::GeoJSON) { - return std::make_unique(overscaledTileID, id, parameters, geojsonvt.get()); + return std::make_unique(overscaledTileID, id, parameters, geojsonvt.get()); } else { Log::Warning(Event::Style, "Source type '%s' is not implemented", SourceTypeClass(type).c_str()); @@ -203,9 +203,9 @@ std::unique_ptr Source::createTile(const OverscaledTileID& overscaledT } } -TileData* Source::getTileData(const OverscaledTileID& overscaledTileID) const { - auto it = tileDataMap.find(overscaledTileID); - if (it != tileDataMap.end()) { +Tile* Source::getTile(const OverscaledTileID& overscaledTileID) const { + auto it = tiles.find(overscaledTileID); + if (it != tiles.end()) { return it->second.get(); } else { return nullptr; @@ -241,16 +241,16 @@ bool Source::update(const UpdateParameters& parameters) { // we're actively using, e.g. as a replacement for tile that aren't loaded yet. std::set retain; - auto retainTileDataFn = [&retain](TileData& tileData, bool required) -> void { - retain.emplace(tileData.id); - tileData.setNecessity(required ? TileData::Necessity::Required - : TileData::Necessity::Optional); + auto retainTileFn = [&retain](Tile& tile, bool required) -> void { + retain.emplace(tile.id); + tile.setNecessity(required ? Tile::Necessity::Required + : Tile::Necessity::Optional); }; - auto getTileDataFn = [this](const OverscaledTileID& dataTileID) -> TileData* { - return getTileData(dataTileID); + auto getTileFn = [this](const OverscaledTileID& dataTileID) -> Tile* { + return getTile(dataTileID); }; - auto createTileDataFn = [this, ¶meters](const OverscaledTileID& dataTileID) -> TileData* { - std::unique_ptr data = cache.get(dataTileID); + auto createTileFn = [this, ¶meters](const OverscaledTileID& dataTileID) -> Tile* { + std::unique_ptr data = cache.get(dataTileID); if (!data) { data = createTile(dataTileID, parameters); if (data) { @@ -258,17 +258,17 @@ bool Source::update(const UpdateParameters& parameters) { } } if (data) { - return tileDataMap.emplace(dataTileID, std::move(data)).first->second.get(); + return tiles.emplace(dataTileID, std::move(data)).first->second.get(); } else { return nullptr; } }; - auto renderTileFn = [this](const UnwrappedTileID& renderTileID, TileData& tileData) { - renderTiles.emplace(renderTileID, RenderTile{ renderTileID, tileData }); + auto renderTileFn = [this](const UnwrappedTileID& renderTileID, Tile& tile) { + renderTiles.emplace(renderTileID, RenderTile{ renderTileID, tile }); }; renderTiles.clear(); - algorithm::updateRenderables(getTileDataFn, createTileDataFn, retainTileDataFn, renderTileFn, + algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, renderTileFn, idealTiles, *tileset, dataTileZoom); if (type != SourceType::Raster && type != SourceType::Annotations && cache.getSize() == 0) { @@ -281,15 +281,15 @@ bool Source::update(const UpdateParameters& parameters) { } // Remove stale data tiles from the active set of tiles. - // This goes through the (sorted!) tileDataMap and retain set in lockstep and removes items from - // tileDataMap that don't have the corresponding key in the retain set. - auto dataIt = tileDataMap.begin(); + // This goes through the (sorted!) tiles and retain set in lockstep and removes items from + // tiles that don't have the corresponding key in the retain set. + auto dataIt = tiles.begin(); auto retainIt = retain.begin(); - while (dataIt != tileDataMap.end()) { + while (dataIt != tiles.end()) { if (retainIt == retain.end() || dataIt->first < *retainIt) { - dataIt->second->setNecessity(TileData::Necessity::Optional); + dataIt->second->setNecessity(Tile::Necessity::Optional); cache.add(dataIt->first, std::move(dataIt->second)); - tileDataMap.erase(dataIt++); + tiles.erase(dataIt++); } else { if (!(*retainIt < dataIt->first)) { ++dataIt; @@ -301,14 +301,14 @@ bool Source::update(const UpdateParameters& parameters) { const PlacementConfig newConfig{ parameters.transformState.getAngle(), parameters.transformState.getPitch(), parameters.debugOptions & MapDebugOptions::Collision }; - for (auto& pair : tileDataMap) { - auto tileData = pair.second.get(); - if (parameters.shouldReparsePartialTiles && tileData->isIncomplete()) { - if (!tileData->parsePending()) { + for (auto& pair : tiles) { + auto tile = pair.second.get(); + if (parameters.shouldReparsePartialTiles && tile->isIncomplete()) { + if (!tile->parsePending()) { allTilesUpdated = false; } } else { - tileData->redoPlacement(newConfig); + tile->redoPlacement(newConfig); } } @@ -356,7 +356,7 @@ std::unordered_map> Source::queryRenderedFeatu tileSpaceQueryGeometry.push_back(coordinateToTilePoint(tile.id, c)); } - tile.data.queryRenderedFeatures(result, + tile.tile.queryRenderedFeatures(result, tileSpaceQueryGeometry, parameters.transformState, parameters.layerIDs); @@ -377,12 +377,12 @@ void Source::setObserver(SourceObserver* observer_) { observer = observer_; } -void Source::onTileLoaded(TileData& tileData, bool isNewTile) { - observer->onTileLoaded(*this, tileData.id, isNewTile); +void Source::onTileLoaded(Tile& tile, bool isNewTile) { + observer->onTileLoaded(*this, tile.id, isNewTile); } -void Source::onTileError(TileData& tileData, std::exception_ptr error) { - observer->onTileError(*this, tileData.id, error); +void Source::onTileError(Tile& tile, std::exception_ptr error) { + observer->onTileError(*this, tile.id, error); } void Source::onNeedsRepaint() { @@ -393,9 +393,9 @@ void Source::dumpDebugLogs() const { Log::Info(Event::General, "Source::id: %s", id.c_str()); Log::Info(Event::General, "Source::loaded: %d", loaded); - for (const auto& pair : tileDataMap) { - auto& tileData = pair.second; - tileData->dumpDebugLogs(); + for (const auto& pair : tiles) { + auto& tile = pair.second; + tile->dumpDebugLogs(); } } diff --git a/src/mbgl/style/source.hpp b/src/mbgl/style/source.hpp index b74828838..453f52a8b 100644 --- a/src/mbgl/style/source.hpp +++ b/src/mbgl/style/source.hpp @@ -1,8 +1,8 @@ #pragma once #include -#include -#include +#include +#include #include #include @@ -38,7 +38,7 @@ class UpdateParameters; class QueryParameters; class SourceObserver; -class Source : public TileDataObserver, private util::noncopyable { +class Source : public TileObserver, private util::noncopyable { public: Source(SourceType, const std::string& id, @@ -71,7 +71,7 @@ public: const std::map& getRenderTiles() const; - TileData* getTileData(const OverscaledTileID&) const; + Tile* getTile(const OverscaledTileID&) const; std::unordered_map> queryRenderedFeatures(const QueryParameters&) const; @@ -89,12 +89,12 @@ public: bool enabled = false; private: - // TileDataObserver implementation. - void onTileLoaded(TileData&, bool isNewTile) override; - void onTileError(TileData&, std::exception_ptr) override; + // TileObserver implementation. + void onTileLoaded(Tile&, bool isNewTile) override; + void onTileError(Tile&, std::exception_ptr) override; void onNeedsRepaint() override; - std::unique_ptr createTile(const OverscaledTileID&, const UpdateParameters&); + std::unique_ptr createTile(const OverscaledTileID&, const UpdateParameters&); private: std::unique_ptr tileset; @@ -104,8 +104,8 @@ private: // Stores the time when this source was most recently updated. TimePoint updated = TimePoint::min(); + std::map> tiles; std::map renderTiles; - std::map> tileDataMap; TileCache cache; std::unique_ptr req; diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 6b228d32d..2fe4810a5 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -291,7 +291,7 @@ RenderData Style::getRenderData() const { for (auto& pair : source->getRenderTiles()) { auto& tile = pair.second; - if (!tile.data.isRenderable()) { + if (!tile.tile.isRenderable()) { continue; } @@ -304,7 +304,7 @@ RenderData Style::getRenderData() const { // already a bucket from this layer that is a parent of this tile. Tiles are ordered // by zoom level when we obtain them from getTiles(). for (auto it = result.order.rbegin(); it != result.order.rend() && (&it->layer == layer.get()); ++it) { - if (tile.data.id.isChildOf(it->tile->data.id)) { + if (tile.tile.id.isChildOf(it->tile->tile.id)) { skip = true; break; } @@ -314,7 +314,7 @@ RenderData Style::getRenderData() const { } } - auto bucket = tile.data.getBucket(*layer); + auto bucket = tile.tile.getBucket(*layer); if (bucket) { result.order.emplace_back(*layer, &tile, bucket); } diff --git a/src/mbgl/text/check_max_angle.hpp b/src/mbgl/text/check_max_angle.hpp index 5e1ff6f04..008e70b5d 100644 --- a/src/mbgl/text/check_max_angle.hpp +++ b/src/mbgl/text/check_max_angle.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace mbgl { diff --git a/src/mbgl/text/collision_feature.hpp b/src/mbgl/text/collision_feature.hpp index 0fcc083a1..204da8f2e 100644 --- a/src/mbgl/text/collision_feature.hpp +++ b/src/mbgl/text/collision_feature.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/mbgl/text/get_anchors.hpp b/src/mbgl/text/get_anchors.hpp index 9a0a5a650..b61f8fe0d 100644 --- a/src/mbgl/text/get_anchors.hpp +++ b/src/mbgl/text/get_anchors.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include namespace mbgl { diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index 2a05082b0..1c94cb811 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index e78fe308e..9bc4f3ebb 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include diff --git a/src/mbgl/tile/geojson_tile.cpp b/src/mbgl/tile/geojson_tile.cpp index 4bea00bb4..b702400d4 100644 --- a/src/mbgl/tile/geojson_tile.cpp +++ b/src/mbgl/tile/geojson_tile.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -36,9 +36,9 @@ private: const Features features; }; -class GeoJSONTile : public GeometryTile { +class GeoJSONTileData : public GeometryTileData { public: - GeoJSONTile(std::shared_ptr); + GeoJSONTileData(std::shared_ptr); util::ptr getLayer(const std::string&) const override; private: @@ -46,7 +46,7 @@ private: }; // Converts the geojsonvt::Tile to a a GeoJSONTile. They have a differing internal structure. -std::unique_ptr convertTile(const mapbox::geojsonvt::Tile& tile) { +std::unique_ptr convertTile(const mapbox::geojsonvt::Tile& tile) { std::shared_ptr layer; if (tile) { @@ -103,24 +103,20 @@ std::unique_ptr convertTile(const mapbox::geojsonvt::Tile& tile) { layer = std::make_unique(std::move(features)); } - return std::make_unique(layer); + return std::make_unique(layer); } -GeoJSONTileData::GeoJSONTileData(const OverscaledTileID& overscaledTileID, - std::string sourceID, - const style::UpdateParameters& parameters, - mapbox::geojsonvt::GeoJSONVT* geojsonvt) - : GeometryTileData(overscaledTileID, sourceID, parameters.style, parameters.mode) { +GeoJSONTile::GeoJSONTile(const OverscaledTileID& overscaledTileID, + std::string sourceID, + const style::UpdateParameters& parameters, + mapbox::geojsonvt::GeoJSONVT* geojsonvt) + : GeometryTile(overscaledTileID, sourceID, parameters.style, parameters.mode) { if (geojsonvt) { - auto tile = convertTile( - geojsonvt->getTile(id.canonical.z, id.canonical.x, id.canonical.y)); - setData(std::move(tile), {}, {}); + setData(convertTile(geojsonvt->getTile(id.canonical.z, id.canonical.x, id.canonical.y)), {}, {}); } } -GeoJSONTileData::~GeoJSONTileData() = default; - -void GeoJSONTileData::setNecessity(Necessity) {} +void GeoJSONTile::setNecessity(Necessity) {} GeoJSONTileFeature::GeoJSONTileFeature(FeatureType type_, GeometryCollection&& geometries_, @@ -155,10 +151,10 @@ util::ptr GeoJSONTileLayer::getFeature(std::size_t i) return features[i]; } -GeoJSONTile::GeoJSONTile(std::shared_ptr layer_) : layer(std::move(layer_)) { +GeoJSONTileData::GeoJSONTileData(std::shared_ptr layer_) : layer(std::move(layer_)) { } -util::ptr GeoJSONTile::getLayer(const std::string&) const { +util::ptr GeoJSONTileData::getLayer(const std::string&) const { // We're ignoring the layer name because GeoJSON tiles only have one layer. return layer; } diff --git a/src/mbgl/tile/geojson_tile.hpp b/src/mbgl/tile/geojson_tile.hpp index 613ef2d96..9cdc705d3 100644 --- a/src/mbgl/tile/geojson_tile.hpp +++ b/src/mbgl/tile/geojson_tile.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace mapbox { namespace geojsonvt { @@ -14,13 +14,12 @@ namespace style { class UpdateParameters; } -class GeoJSONTileData : public GeometryTileData { +class GeoJSONTile : public GeometryTile { public: - GeoJSONTileData(const OverscaledTileID&, - std::string sourceID, - const style::UpdateParameters&, - mapbox::geojsonvt::GeoJSONVT*); - ~GeoJSONTileData(); + GeoJSONTile(const OverscaledTileID&, + std::string sourceID, + const style::UpdateParameters&, + mapbox::geojsonvt::GeoJSONVT*); void setNecessity(Necessity) final; }; diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index f4589b405..cded44865 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -1,210 +1,206 @@ #include -#include - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace mbgl { -static double signedArea(const GeometryCoordinates& ring) { - double sum = 0; - - for (std::size_t i = 0, len = ring.size(), j = len - 1; i < len; j = i++) { - const GeometryCoordinate& p1 = ring[i]; - const GeometryCoordinate& p2 = ring[j]; - sum += (p2.x - p1.x) * (p1.y + p2.y); - } - - return sum; +GeometryTile::GeometryTile(const OverscaledTileID& id_, + std::string sourceID, + style::Style& style_, + const MapMode mode_) + : Tile(id_), + style(style_), + worker(style_.workers), + tileWorker(id_, + sourceID, + *style_.spriteStore, + *style_.glyphAtlas, + *style_.glyphStore, + obsolete, + mode_) { } -static ClipperLib::Path toClipperPath(const GeometryCoordinates& ring) { - ClipperLib::Path result; - result.reserve(ring.size()); - for (const auto& p : ring) { - result.emplace_back(p.x, p.y); - } - return result; +void GeometryTile::setError(std::exception_ptr err) { + observer->onTileError(*this, err); } -static GeometryCoordinates fromClipperPath(const ClipperLib::Path& path) { - GeometryCoordinates result; - result.reserve(path.size()); - for (const auto& p : path) { - using Coordinate = GeometryCoordinates::coordinate_type; - assert(p.x >= std::numeric_limits::min()); - assert(p.x <= std::numeric_limits::max()); - assert(p.y >= std::numeric_limits::min()); - assert(p.y <= std::numeric_limits::max()); - result.emplace_back(Coordinate(p.x), Coordinate(p.y)); - } - return result; -} +void GeometryTile::setData(std::unique_ptr data_, + optional modified_, + optional expires_) { + modified = modified_; + expires = expires_; -static void processPolynodeBranch(ClipperLib::PolyNode* polynode, GeometryCollection& rings) { - // Exterior ring. - rings.push_back(fromClipperPath(polynode->Contour)); - assert(signedArea(rings.back()) > 0); - - // Interior rings. - for (auto * ring : polynode->Childs) { - rings.push_back(fromClipperPath(ring->Contour)); - assert(signedArea(rings.back()) < 0); + if (!data_) { + // This is a 404 response. We're treating these as empty tiles. + workRequest.reset(); + availableData = DataAvailability::All; + buckets.clear(); + redoPlacement(); + observer->onTileLoaded(*this, true); + return; } - // PolyNodes may be nested in the case of a polygon inside a hole. - for (auto * ring : polynode->Childs) { - for (auto * subRing : ring->Childs) { - processPolynodeBranch(subRing, rings); + // Mark the tile as pending again if it was complete before to prevent signaling a complete + // state despite pending parse operations. + if (availableData == DataAvailability::All) { + availableData = DataAvailability::Some; + } + + // Kick off a fresh parse of this tile. This happens when the tile is new, or + // when tile data changed. Replacing the workdRequest will cancel a pending work + // request in case there is one. + workRequest.reset(); + workRequest = worker.parseGeometryTile(tileWorker, style.getLayers(), std::move(data_), targetConfig, [this, config = targetConfig] (TileParseResult result) { + workRequest.reset(); + + if (result.is()) { + auto& resultBuckets = result.get(); + availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; + + // Persist the configuration we just placed so that we can later check whether we need to + // place again in case the configuration has changed. + placedConfig = config; + + // Move over all buckets we received in this parse request, potentially overwriting + // existing buckets in case we got a refresh parse. + buckets = std::move(resultBuckets.buckets); + + if (isComplete()) { + featureIndex = std::move(resultBuckets.featureIndex); + data = std::move(resultBuckets.tileData); + } + + redoPlacement(); + observer->onTileLoaded(*this, true); + } else { + availableData = DataAvailability::All; + observer->onTileError(*this, result.get()); } - } + }); } -GeometryCollection fixupPolygons(const GeometryCollection& rings) { - ClipperLib::Clipper clipper; - clipper.StrictlySimple(true); - - for (const auto& ring : rings) { - clipper.AddPath(toClipperPath(ring), ClipperLib::ptSubject, true); - } - - ClipperLib::PolyTree polygons; - clipper.Execute(ClipperLib::ctUnion, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); - clipper.Clear(); - - GeometryCollection result; - for (auto * polynode : polygons.Childs) { - processPolynodeBranch(polynode, result); - } - return result; +GeometryTile::~GeometryTile() { + cancel(); } -std::vector classifyRings(const GeometryCollection& rings) { - std::vector polygons; - - std::size_t len = rings.size(); - - if (len <= 1) { - polygons.push_back(rings); - return polygons; +bool GeometryTile::parsePending() { + if (workRequest) { + // There's already parsing or placement going on. + return false; } - GeometryCollection polygon; - int8_t ccw = 0; + workRequest.reset(); + workRequest = worker.parsePendingGeometryTileLayers(tileWorker, targetConfig, [this, config = targetConfig] (TileParseResult result) { + workRequest.reset(); - for (std::size_t i = 0; i < len; i++) { - double area = signedArea(rings[i]); + if (result.is()) { + auto& resultBuckets = result.get(); + availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; - if (area == 0) - continue; + // Move over all buckets we received in this parse request, potentially overwriting + // existing buckets in case we got a refresh parse. + for (auto& bucket : resultBuckets.buckets) { + buckets[bucket.first] = std::move(bucket.second); + } - if (ccw == 0) - ccw = (area < 0 ? -1 : 1); + // Persist the configuration we just placed so that we can later check whether we need to + // place again in case the configuration has changed. + placedConfig = config; - if (ccw == (area < 0 ? -1 : 1) && !polygon.empty()) { - polygons.push_back(polygon); - polygon.clear(); + if (isComplete()) { + featureIndex = std::move(resultBuckets.featureIndex); + data = std::move(resultBuckets.tileData); + } + + redoPlacement(); + observer->onTileLoaded(*this, false); + } else { + availableData = DataAvailability::All; + observer->onTileError(*this, result.get()); + } + }); + + return true; +} + +Bucket* GeometryTile::getBucket(const style::Layer& layer) { + const auto it = buckets.find(layer.baseImpl->bucketName()); + if (it == buckets.end()) { + return nullptr; + } + + assert(it->second); + return it->second.get(); +} + +void GeometryTile::redoPlacement(const PlacementConfig newConfig) { + targetConfig = newConfig; + redoPlacement(); +} + +void GeometryTile::redoPlacement() { + // Don't start a new placement request when the current one hasn't completed yet, or when + // we are parsing buckets. + if (workRequest || targetConfig == placedConfig) { + return; + } + + workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, config = targetConfig](std::unique_ptr collisionTile) { + workRequest.reset(); + + // Persist the configuration we just placed so that we can later check whether we need to + // place again in case the configuration has changed. + placedConfig = config; + + for (auto& bucket : buckets) { + bucket.second->swapRenderData(); } - polygon.push_back(rings[i]); - } + if (featureIndex) { + featureIndex->setCollisionTile(std::move(collisionTile)); + } - if (!polygon.empty()) - polygons.push_back(polygon); - - return polygons; + // The target configuration could have changed since we started placement. In this case, + // we're starting another placement run. + if (placedConfig != targetConfig) { + redoPlacement(); + } else { + observer->onNeedsRepaint(); + } + }); } -void limitHoles(GeometryCollection& polygon, uint32_t maxHoles) { - if (polygon.size() > 1 + maxHoles) { - std::nth_element(polygon.begin() + 1, - polygon.begin() + 1 + maxHoles, - polygon.end(), - [] (const auto& a, const auto& b) { - return signedArea(a) > signedArea(b); - }); - polygon.resize(1 + maxHoles); - } +void GeometryTile::queryRenderedFeatures( + std::unordered_map>& result, + const GeometryCoordinates& queryGeometry, + const TransformState& transformState, + const optional>& layerIDs) { + + if (!featureIndex || !data) return; + + featureIndex->query(result, + { queryGeometry }, + transformState.getAngle(), + util::tileSize * id.overscaleFactor(), + std::pow(2, transformState.getZoom() - id.overscaledZ), + layerIDs, + *data, + id.canonical, + style); } -static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) { - const double size = util::EXTENT * std::pow(2, tileID.z); - const double x0 = util::EXTENT * tileID.x; - const double y0 = util::EXTENT * tileID.y; - - auto tileCoordinatesToLatLng = [&] (const Point& p) { - double y2 = 180 - (p.y + y0) * 360 / size; - return Point( - (p.x + x0) * 360 / size - 180, - 360.0 / M_PI * std::atan(std::exp(y2 * M_PI / 180)) - 90.0 - ); - }; - - GeometryCollection geometries = geometryTileFeature.getGeometries(); - - switch (geometryTileFeature.getType()) { - case FeatureType::Unknown: { - assert(false); - return Point(NAN, NAN); - } - - case FeatureType::Point: { - MultiPoint multiPoint; - for (const auto& p : geometries.at(0)) { - multiPoint.push_back(tileCoordinatesToLatLng(p)); - } - if (multiPoint.size() == 1) { - return multiPoint[0]; - } else { - return multiPoint; - } - } - - case FeatureType::LineString: { - MultiLineString multiLineString; - for (const auto& g : geometries) { - LineString lineString; - for (const auto& p : g) { - lineString.push_back(tileCoordinatesToLatLng(p)); - } - multiLineString.push_back(std::move(lineString)); - } - if (multiLineString.size() == 1) { - return multiLineString[0]; - } else { - return multiLineString; - } - } - - case FeatureType::Polygon: { - MultiPolygon multiPolygon; - for (const auto& pg : classifyRings(geometries)) { - Polygon polygon; - for (const auto& r : pg) { - LinearRing linearRing; - for (const auto& p : r) { - linearRing.push_back(tileCoordinatesToLatLng(p)); - } - polygon.push_back(std::move(linearRing)); - } - multiPolygon.push_back(std::move(polygon)); - } - if (multiPolygon.size() == 1) { - return multiPolygon[0]; - } else { - return multiPolygon; - } - } - } - - // Unreachable, but placate GCC. - return Point(); -} - -Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) { - Feature feature { convertGeometry(geometryTileFeature, tileID) }; - feature.properties = geometryTileFeature.getProperties(); - feature.id = geometryTileFeature.getID(); - return feature; +void GeometryTile::cancel() { + obsolete = true; + workRequest.reset(); } } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index 80d6d6031..4c5d08ee4 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -1,83 +1,78 @@ #pragma once -#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include namespace mbgl { -enum class FeatureType : uint8_t { - Unknown = 0, - Point = 1, - LineString = 2, - Polygon = 3 -}; +class AsyncRequest; +class GeometryTileData; +class FeatureIndex; -class CanonicalTileID; +namespace style { +class Style; +} -// Normalized vector tile coordinates. -// Each geometry coordinate represents a point in a bidimensional space, -// varying from -V...0...+V, where V is the maximum extent applicable. -using GeometryCoordinate = Point; - -class GeometryCoordinates : public std::vector { +class GeometryTile : public Tile { public: - using coordinate_type = int16_t; - using std::vector::vector; + GeometryTile(const OverscaledTileID&, + std::string sourceID, + style::Style&, + const MapMode); + + ~GeometryTile(); + + void setError(std::exception_ptr err); + + void setData(std::unique_ptr, + optional modified_, + optional expires_); + + Bucket* getBucket(const style::Layer&) override; + + bool parsePending() override; + + void redoPlacement(PlacementConfig) override; + + void queryRenderedFeatures( + std::unordered_map>& result, + const GeometryCoordinates& queryGeometry, + const TransformState&, + const optional>& layerIDs) override; + + void cancel() override; + +private: + void redoPlacement(); + + style::Style& style; + Worker& worker; + TileWorker tileWorker; + + std::unique_ptr workRequest; + + // Contains all the Bucket objects for the tile. Buckets are render + // objects and they get added by tile parsing operations. + std::unordered_map> buckets; + + std::unique_ptr featureIndex; + std::unique_ptr data; + + // Stores the placement configuration of the text that is currently placed on the screen. + PlacementConfig placedConfig; + + // Stores the placement configuration of how the text should be placed. This isn't necessarily + // the one that is being displayed. + PlacementConfig targetConfig; + + // Used to signal the worker that it should abandon parsing this tile as soon as possible. + util::Atomic obsolete { false }; }; -class GeometryCollection : public std::vector { -public: - using coordinate_type = int16_t; - using std::vector::vector; -}; - -class GeometryTileFeature : private util::noncopyable { -public: - virtual ~GeometryTileFeature() = default; - virtual FeatureType getType() const = 0; - virtual optional getValue(const std::string& key) const = 0; - virtual Feature::property_map getProperties() const { return Feature::property_map(); } - virtual optional getID() const { return {}; } - virtual GeometryCollection getGeometries() const = 0; -}; - -class GeometryTileLayer : private util::noncopyable { -public: - virtual ~GeometryTileLayer() = default; - virtual std::size_t featureCount() const = 0; - virtual util::ptr getFeature(std::size_t) const = 0; - virtual std::string getName() const = 0; -}; - -class GeometryTile : private util::noncopyable { -public: - virtual ~GeometryTile() = default; - virtual util::ptr getLayer(const std::string&) const = 0; -}; - -// classifies an array of rings into polygons with outer rings and holes -std::vector classifyRings(const GeometryCollection&); - -// Truncate polygon to the largest `maxHoles` inner rings by area. -void limitHoles(GeometryCollection&, uint32_t maxHoles); - -// convert from GeometryTileFeature to Feature (eventually we should eliminate GeometryTileFeature) -Feature convertFeature(const GeometryTileFeature&, const CanonicalTileID&); - -// Fix up possibly-non-V2-compliant polygon geometry using angus clipper. -// The result is guaranteed to have correctly wound, strictly simple rings. -GeometryCollection fixupPolygons(const GeometryCollection&); - } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp index 39a379a8e..6e700aa63 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -1,206 +1,210 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include + +#include namespace mbgl { -GeometryTileData::GeometryTileData(const OverscaledTileID& id_, - std::string sourceID, - style::Style& style_, - const MapMode mode_) - : TileData(id_), - style(style_), - worker(style_.workers), - tileWorker(id_, - sourceID, - *style_.spriteStore, - *style_.glyphAtlas, - *style_.glyphStore, - obsolete, - mode_) { -} +static double signedArea(const GeometryCoordinates& ring) { + double sum = 0; -void GeometryTileData::setError(std::exception_ptr err) { - observer->onTileError(*this, err); -} - -void GeometryTileData::setData(std::unique_ptr tile, - optional modified_, - optional expires_) { - modified = modified_; - expires = expires_; - - if (!tile) { - // This is a 404 response. We're treating these as empty tiles. - workRequest.reset(); - availableData = DataAvailability::All; - buckets.clear(); - redoPlacement(); - observer->onTileLoaded(*this, true); - return; + for (std::size_t i = 0, len = ring.size(), j = len - 1; i < len; j = i++) { + const GeometryCoordinate& p1 = ring[i]; + const GeometryCoordinate& p2 = ring[j]; + sum += (p2.x - p1.x) * (p1.y + p2.y); } - // Mark the tile as pending again if it was complete before to prevent signaling a complete - // state despite pending parse operations. - if (availableData == DataAvailability::All) { - availableData = DataAvailability::Some; + return sum; +} + +static ClipperLib::Path toClipperPath(const GeometryCoordinates& ring) { + ClipperLib::Path result; + result.reserve(ring.size()); + for (const auto& p : ring) { + result.emplace_back(p.x, p.y); + } + return result; +} + +static GeometryCoordinates fromClipperPath(const ClipperLib::Path& path) { + GeometryCoordinates result; + result.reserve(path.size()); + for (const auto& p : path) { + using Coordinate = GeometryCoordinates::coordinate_type; + assert(p.x >= std::numeric_limits::min()); + assert(p.x <= std::numeric_limits::max()); + assert(p.y >= std::numeric_limits::min()); + assert(p.y <= std::numeric_limits::max()); + result.emplace_back(Coordinate(p.x), Coordinate(p.y)); + } + return result; +} + +static void processPolynodeBranch(ClipperLib::PolyNode* polynode, GeometryCollection& rings) { + // Exterior ring. + rings.push_back(fromClipperPath(polynode->Contour)); + assert(signedArea(rings.back()) > 0); + + // Interior rings. + for (auto * ring : polynode->Childs) { + rings.push_back(fromClipperPath(ring->Contour)); + assert(signedArea(rings.back()) < 0); } - // Kick off a fresh parse of this tile. This happens when the tile is new, or - // when tile data changed. Replacing the workdRequest will cancel a pending work - // request in case there is one. - workRequest.reset(); - workRequest = worker.parseGeometryTile(tileWorker, style.getLayers(), std::move(tile), targetConfig, [this, config = targetConfig] (TileParseResult result) { - workRequest.reset(); + // PolyNodes may be nested in the case of a polygon inside a hole. + for (auto * ring : polynode->Childs) { + for (auto * subRing : ring->Childs) { + processPolynodeBranch(subRing, rings); + } + } +} - if (result.is()) { - auto& resultBuckets = result.get(); - availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; +GeometryCollection fixupPolygons(const GeometryCollection& rings) { + ClipperLib::Clipper clipper; + clipper.StrictlySimple(true); - // Persist the configuration we just placed so that we can later check whether we need to - // place again in case the configuration has changed. - placedConfig = config; + for (const auto& ring : rings) { + clipper.AddPath(toClipperPath(ring), ClipperLib::ptSubject, true); + } - // Move over all buckets we received in this parse request, potentially overwriting - // existing buckets in case we got a refresh parse. - buckets = std::move(resultBuckets.buckets); + ClipperLib::PolyTree polygons; + clipper.Execute(ClipperLib::ctUnion, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); + clipper.Clear(); - if (isComplete()) { - featureIndex = std::move(resultBuckets.featureIndex); - geometryTile = std::move(resultBuckets.geometryTile); + GeometryCollection result; + for (auto * polynode : polygons.Childs) { + processPolynodeBranch(polynode, result); + } + return result; +} + +std::vector classifyRings(const GeometryCollection& rings) { + std::vector polygons; + + std::size_t len = rings.size(); + + if (len <= 1) { + polygons.push_back(rings); + return polygons; + } + + GeometryCollection polygon; + int8_t ccw = 0; + + for (std::size_t i = 0; i < len; i++) { + double area = signedArea(rings[i]); + + if (area == 0) + continue; + + if (ccw == 0) + ccw = (area < 0 ? -1 : 1); + + if (ccw == (area < 0 ? -1 : 1) && !polygon.empty()) { + polygons.push_back(polygon); + polygon.clear(); + } + + polygon.push_back(rings[i]); + } + + if (!polygon.empty()) + polygons.push_back(polygon); + + return polygons; +} + +void limitHoles(GeometryCollection& polygon, uint32_t maxHoles) { + if (polygon.size() > 1 + maxHoles) { + std::nth_element(polygon.begin() + 1, + polygon.begin() + 1 + maxHoles, + polygon.end(), + [] (const auto& a, const auto& b) { + return signedArea(a) > signedArea(b); + }); + polygon.resize(1 + maxHoles); + } +} + +static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) { + const double size = util::EXTENT * std::pow(2, tileID.z); + const double x0 = util::EXTENT * tileID.x; + const double y0 = util::EXTENT * tileID.y; + + auto tileCoordinatesToLatLng = [&] (const Point& p) { + double y2 = 180 - (p.y + y0) * 360 / size; + return Point( + (p.x + x0) * 360 / size - 180, + 360.0 / M_PI * std::atan(std::exp(y2 * M_PI / 180)) - 90.0 + ); + }; + + GeometryCollection geometries = geometryTileFeature.getGeometries(); + + switch (geometryTileFeature.getType()) { + case FeatureType::Unknown: { + assert(false); + return Point(NAN, NAN); + } + + case FeatureType::Point: { + MultiPoint multiPoint; + for (const auto& p : geometries.at(0)) { + multiPoint.push_back(tileCoordinatesToLatLng(p)); } - - redoPlacement(); - observer->onTileLoaded(*this, true); - } else { - availableData = DataAvailability::All; - observer->onTileError(*this, result.get()); - } - }); -} - -GeometryTileData::~GeometryTileData() { - cancel(); -} - -bool GeometryTileData::parsePending() { - if (workRequest) { - // There's already parsing or placement going on. - return false; - } - - workRequest.reset(); - workRequest = worker.parsePendingGeometryTileLayers(tileWorker, targetConfig, [this, config = targetConfig] (TileParseResult result) { - workRequest.reset(); - - if (result.is()) { - auto& resultBuckets = result.get(); - availableData = resultBuckets.complete ? DataAvailability::All : DataAvailability::Some; - - // Move over all buckets we received in this parse request, potentially overwriting - // existing buckets in case we got a refresh parse. - for (auto& bucket : resultBuckets.buckets) { - buckets[bucket.first] = std::move(bucket.second); + if (multiPoint.size() == 1) { + return multiPoint[0]; + } else { + return multiPoint; } + } - // Persist the configuration we just placed so that we can later check whether we need to - // place again in case the configuration has changed. - placedConfig = config; - - if (isComplete()) { - featureIndex = std::move(resultBuckets.featureIndex); - geometryTile = std::move(resultBuckets.geometryTile); + case FeatureType::LineString: { + MultiLineString multiLineString; + for (const auto& g : geometries) { + LineString lineString; + for (const auto& p : g) { + lineString.push_back(tileCoordinatesToLatLng(p)); + } + multiLineString.push_back(std::move(lineString)); + } + if (multiLineString.size() == 1) { + return multiLineString[0]; + } else { + return multiLineString; } - - redoPlacement(); - observer->onTileLoaded(*this, false); - } else { - availableData = DataAvailability::All; - observer->onTileError(*this, result.get()); } - }); - return true; -} - -Bucket* GeometryTileData::getBucket(const style::Layer& layer) { - const auto it = buckets.find(layer.baseImpl->bucketName()); - if (it == buckets.end()) { - return nullptr; + case FeatureType::Polygon: { + MultiPolygon multiPolygon; + for (const auto& pg : classifyRings(geometries)) { + Polygon polygon; + for (const auto& r : pg) { + LinearRing linearRing; + for (const auto& p : r) { + linearRing.push_back(tileCoordinatesToLatLng(p)); + } + polygon.push_back(std::move(linearRing)); + } + multiPolygon.push_back(std::move(polygon)); + } + if (multiPolygon.size() == 1) { + return multiPolygon[0]; + } else { + return multiPolygon; + } + } } - assert(it->second); - return it->second.get(); + // Unreachable, but placate GCC. + return Point(); } -void GeometryTileData::redoPlacement(const PlacementConfig newConfig) { - targetConfig = newConfig; - redoPlacement(); -} - -void GeometryTileData::redoPlacement() { - // Don't start a new placement request when the current one hasn't completed yet, or when - // we are parsing buckets. - if (workRequest || targetConfig == placedConfig) { - return; - } - - workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, config = targetConfig](std::unique_ptr collisionTile) { - workRequest.reset(); - - // Persist the configuration we just placed so that we can later check whether we need to - // place again in case the configuration has changed. - placedConfig = config; - - for (auto& bucket : buckets) { - bucket.second->swapRenderData(); - } - - if (featureIndex) { - featureIndex->setCollisionTile(std::move(collisionTile)); - } - - // The target configuration could have changed since we started placement. In this case, - // we're starting another placement run. - if (placedConfig != targetConfig) { - redoPlacement(); - } else { - observer->onNeedsRepaint(); - } - }); -} - -void GeometryTileData::queryRenderedFeatures( - std::unordered_map>& result, - const GeometryCoordinates& queryGeometry, - const TransformState& transformState, - const optional>& layerIDs) { - - if (!featureIndex || !geometryTile) return; - - featureIndex->query(result, - { queryGeometry }, - transformState.getAngle(), - util::tileSize * id.overscaleFactor(), - std::pow(2, transformState.getZoom() - id.overscaledZ), - layerIDs, - *geometryTile, - id.canonical, - style); -} - -void GeometryTileData::cancel() { - obsolete = true; - workRequest.reset(); +Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) { + Feature feature { convertGeometry(geometryTileFeature, tileID) }; + feature.properties = geometryTileFeature.getProperties(); + feature.id = geometryTileFeature.getID(); + return feature; } } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp index 6c7ff2f3d..753ba6b8a 100644 --- a/src/mbgl/tile/geometry_tile_data.hpp +++ b/src/mbgl/tile/geometry_tile_data.hpp @@ -1,79 +1,83 @@ #pragma once -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include -#include +#include +#include +#include #include +#include namespace mbgl { -class AsyncRequest; -class GeometryTile; -class GeometryTileSource; -class FeatureIndex; - -namespace style { -class Style; -} - -class GeometryTileData : public TileData { -public: - GeometryTileData(const OverscaledTileID&, - std::string sourceID, - style::Style&, - const MapMode); - - ~GeometryTileData(); - - void setError(std::exception_ptr err); - - void setData(std::unique_ptr tile, - optional modified_, - optional expires_); - - Bucket* getBucket(const style::Layer&) override; - - bool parsePending() override; - - void redoPlacement(PlacementConfig) override; - - void queryRenderedFeatures( - std::unordered_map>& result, - const GeometryCoordinates& queryGeometry, - const TransformState&, - const optional>& layerIDs) override; - - void cancel() override; - -private: - void redoPlacement(); - - style::Style& style; - Worker& worker; - TileWorker tileWorker; - - std::unique_ptr workRequest; - - // Contains all the Bucket objects for the tile. Buckets are render - // objects and they get added by tile parsing operations. - std::unordered_map> buckets; - - std::unique_ptr featureIndex; - std::unique_ptr geometryTile; - - // Stores the placement configuration of the text that is currently placed on the screen. - PlacementConfig placedConfig; - - // Stores the placement configuration of how the text should be placed. This isn't necessarily - // the one that is being displayed. - PlacementConfig targetConfig; - - // Used to signal the worker that it should abandon parsing this tile as soon as possible. - util::Atomic obsolete { false }; +enum class FeatureType : uint8_t { + Unknown = 0, + Point = 1, + LineString = 2, + Polygon = 3 }; +class CanonicalTileID; + +// Normalized vector tile coordinates. +// Each geometry coordinate represents a point in a bidimensional space, +// varying from -V...0...+V, where V is the maximum extent applicable. +using GeometryCoordinate = Point; + +class GeometryCoordinates : public std::vector { +public: + using coordinate_type = int16_t; + using std::vector::vector; +}; + +class GeometryCollection : public std::vector { +public: + using coordinate_type = int16_t; + using std::vector::vector; +}; + +class GeometryTileFeature : private util::noncopyable { +public: + virtual ~GeometryTileFeature() = default; + virtual FeatureType getType() const = 0; + virtual optional getValue(const std::string& key) const = 0; + virtual Feature::property_map getProperties() const { return Feature::property_map(); } + virtual optional getID() const { return {}; } + virtual GeometryCollection getGeometries() const = 0; +}; + +class GeometryTileLayer : private util::noncopyable { +public: + virtual ~GeometryTileLayer() = default; + virtual std::size_t featureCount() const = 0; + virtual util::ptr getFeature(std::size_t) const = 0; + virtual std::string getName() const = 0; +}; + +class GeometryTileData : private util::noncopyable { +public: + virtual ~GeometryTileData() = default; + virtual util::ptr getLayer(const std::string&) const = 0; +}; + +// classifies an array of rings into polygons with outer rings and holes +std::vector classifyRings(const GeometryCollection&); + +// Truncate polygon to the largest `maxHoles` inner rings by area. +void limitHoles(GeometryCollection&, uint32_t maxHoles); + +// convert from GeometryTileFeature to Feature (eventually we should eliminate GeometryTileFeature) +Feature convertFeature(const GeometryTileFeature&, const CanonicalTileID&); + +// Fix up possibly-non-V2-compliant polygon geometry using angus clipper. +// The result is guaranteed to have correctly wound, strictly simple rings. +GeometryCollection fixupPolygons(const GeometryCollection&); + } // namespace mbgl diff --git a/src/mbgl/tile/raster_tile_data.cpp b/src/mbgl/tile/raster_tile.cpp similarity index 69% rename from src/mbgl/tile/raster_tile_data.cpp rename to src/mbgl/tile/raster_tile.cpp index 7737f1fb7..c3838bc59 100644 --- a/src/mbgl/tile/raster_tile_data.cpp +++ b/src/mbgl/tile/raster_tile.cpp @@ -1,8 +1,8 @@ -#include +#include +#include +#include #include #include -#include -#include #include #include #include @@ -11,20 +11,20 @@ using namespace mbgl; -RasterTileData::RasterTileData(const OverscaledTileID& id_, - const style::UpdateParameters& parameters, - const Tileset& tileset) - : TileData(id_), +RasterTile::RasterTile(const OverscaledTileID& id_, + const style::UpdateParameters& parameters, + const Tileset& tileset) + : Tile(id_), texturePool(parameters.texturePool), worker(parameters.worker), tileSource(*this, id_, parameters, tileset) { } -void RasterTileData::setError(std::exception_ptr err) { +void RasterTile::setError(std::exception_ptr err) { observer->onTileError(*this, err); } -void RasterTileData::setData(std::shared_ptr data, +void RasterTile::setData(std::shared_ptr data, optional modified_, optional expires_) { modified = modified_; @@ -55,14 +55,14 @@ void RasterTileData::setData(std::shared_ptr data, }); } -Bucket* RasterTileData::getBucket(const style::Layer&) { +Bucket* RasterTile::getBucket(const style::Layer&) { return bucket.get(); } -void RasterTileData::setNecessity(Necessity necessity) { - tileSource.setNecessity(static_cast::Necessity>(necessity)); +void RasterTile::setNecessity(Necessity necessity) { + tileSource.setNecessity(static_cast::Necessity>(necessity)); } -void RasterTileData::cancel() { +void RasterTile::cancel() { workRequest.reset(); } diff --git a/src/mbgl/tile/raster_tile_data.hpp b/src/mbgl/tile/raster_tile.hpp similarity index 85% rename from src/mbgl/tile/raster_tile_data.hpp rename to src/mbgl/tile/raster_tile.hpp index 7c224ad81..eebfbe6b9 100644 --- a/src/mbgl/tile/raster_tile_data.hpp +++ b/src/mbgl/tile/raster_tile.hpp @@ -1,8 +1,8 @@ #pragma once -#include -#include +#include #include +#include namespace mbgl { @@ -16,9 +16,9 @@ class Layer; class UpdateParameters; } -class RasterTileData : public TileData { +class RasterTile : public Tile { public: - RasterTileData(const OverscaledTileID&, + RasterTile(const OverscaledTileID&, const style::UpdateParameters&, const Tileset&); @@ -37,7 +37,7 @@ private: gl::TexturePool& texturePool; Worker& worker; - TileSource tileSource; + TileSource tileSource; std::unique_ptr workRequest; // Contains the Bucket object for the tile. Buckets are render diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp new file mode 100644 index 000000000..846cda26c --- /dev/null +++ b/src/mbgl/tile/tile.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +namespace mbgl { + +static TileObserver nullObserver; + +Tile::Tile(const OverscaledTileID& id_) + : id(id_), observer(&nullObserver) { +} + +Tile::~Tile() = default; + +void Tile::setObserver(TileObserver* observer_) { + observer = observer_; +} + +void Tile::setTriedOptional() { + triedOptional = true; + observer->onNeedsRepaint(); +} + +void Tile::dumpDebugLogs() const { + Log::Info(Event::General, "Tile::id: %s", util::toString(id).c_str()); + Log::Info(Event::General, "Tile::renderable: %s", isRenderable() ? "yes" : "no"); + Log::Info(Event::General, "Tile::complete: %s", isComplete() ? "yes" : "no"); +} + +void Tile::queryRenderedFeatures( + std::unordered_map>&, + const GeometryCoordinates&, + const TransformState&, + const optional>&) {} + +} // namespace mbgl diff --git a/src/mbgl/tile/tile_data.hpp b/src/mbgl/tile/tile.hpp similarity index 85% rename from src/mbgl/tile/tile_data.hpp rename to src/mbgl/tile/tile.hpp index 4eee82ef4..058e41a02 100644 --- a/src/mbgl/tile/tile_data.hpp +++ b/src/mbgl/tile/tile.hpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -19,18 +19,18 @@ namespace mbgl { class Worker; class DebugBucket; class TransformState; -class TileDataObserver; +class TileObserver; namespace style { class Layer; } -class TileData : private util::noncopyable { +class Tile : private util::noncopyable { public: - TileData(const OverscaledTileID&); - virtual ~TileData(); + Tile(const OverscaledTileID&); + virtual ~Tile(); - void setObserver(TileDataObserver* observer); + void setObserver(TileObserver* observer); enum class Necessity : bool { Optional = false, @@ -91,18 +91,18 @@ protected: // Still waiting for data to load or parse. None, - // TileData is partially parsed, some buckets are still waiting for dependencies + // Tile is partially parsed, some buckets are still waiting for dependencies // to arrive, but it is good for rendering. Partial tiles can also be re-parsed, // but might remain in the same state if dependencies are still missing. Some, - // TileData is fully parsed, and all buckets are available if they exist. + // Tile is fully parsed, and all buckets are available if they exist. All, }; DataAvailability availableData = DataAvailability::None; - TileDataObserver* observer = nullptr; + TileObserver* observer = nullptr; }; } // namespace mbgl diff --git a/src/mbgl/tile/tile_cache.cpp b/src/mbgl/tile/tile_cache.cpp index 619d813fd..3fafb1259 100644 --- a/src/mbgl/tile/tile_cache.cpp +++ b/src/mbgl/tile/tile_cache.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include @@ -17,21 +17,21 @@ void TileCache::setSize(size_t size_) { assert(orderedKeys.size() <= size); } -void TileCache::add(const OverscaledTileID& key, std::unique_ptr data) { - if (!data->isRenderable() || !size) { +void TileCache::add(const OverscaledTileID& key, std::unique_ptr tile) { + if (!tile->isRenderable() || !size) { return; } - // insert new or query existing data - if (tiles.emplace(key, std::move(data)).second) { - // remove existing data key + // insert new or query existing tile + if (tiles.emplace(key, std::move(tile)).second) { + // remove existing tile key orderedKeys.remove(key); } - // (re-)insert data key as newest + // (re-)insert tile key as newest orderedKeys.push_back(key); - // purge oldest key/data if necessary + // purge oldest key/tile if necessary if (orderedKeys.size() > size) { get(orderedKeys.front()); } @@ -39,19 +39,19 @@ void TileCache::add(const OverscaledTileID& key, std::unique_ptr data) assert(orderedKeys.size() <= size); } -std::unique_ptr TileCache::get(const OverscaledTileID& key) { +std::unique_ptr TileCache::get(const OverscaledTileID& key) { - std::unique_ptr data; + std::unique_ptr tile; auto it = tiles.find(key); if (it != tiles.end()) { - data = std::move(it->second); + tile = std::move(it->second); tiles.erase(it); orderedKeys.remove(key); - assert(data->isRenderable()); + assert(tile->isRenderable()); } - return data; + return tile; } bool TileCache::has(const OverscaledTileID& key) { diff --git a/src/mbgl/tile/tile_cache.hpp b/src/mbgl/tile/tile_cache.hpp index edaa6bd68..80fe98a20 100644 --- a/src/mbgl/tile/tile_cache.hpp +++ b/src/mbgl/tile/tile_cache.hpp @@ -8,7 +8,7 @@ namespace mbgl { -class TileData; +class Tile; class TileCache { public: @@ -16,13 +16,13 @@ public: void setSize(size_t); size_t getSize() const { return size; }; - void add(const OverscaledTileID& key, std::unique_ptr data); - std::unique_ptr get(const OverscaledTileID& key); + void add(const OverscaledTileID& key, std::unique_ptr data); + std::unique_ptr get(const OverscaledTileID& key); bool has(const OverscaledTileID& key); void clear(); private: - std::map> tiles; + std::map> tiles; std::list orderedKeys; size_t size; diff --git a/src/mbgl/tile/tile_data.cpp b/src/mbgl/tile/tile_data.cpp deleted file mode 100644 index 7046d2e7d..000000000 --- a/src/mbgl/tile/tile_data.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include - -namespace mbgl { - -static TileDataObserver nullObserver; - -TileData::TileData(const OverscaledTileID& id_) - : id(id_), observer(&nullObserver) { -} - -TileData::~TileData() = default; - -void TileData::setObserver(TileDataObserver* observer_) { - observer = observer_; -} - -void TileData::setTriedOptional() { - triedOptional = true; - observer->onNeedsRepaint(); -} - -void TileData::dumpDebugLogs() const { - Log::Info(Event::General, "TileData::id: %s", util::toString(id).c_str()); - Log::Info(Event::General, "TileData::renderable: %s", isRenderable() ? "yes" : "no"); - Log::Info(Event::General, "TileData::complete: %s", isComplete() ? "yes" : "no"); -} - -void TileData::queryRenderedFeatures( - std::unordered_map>&, - const GeometryCoordinates&, - const TransformState&, - const optional>&) {} - -} // namespace mbgl diff --git a/src/mbgl/tile/tile_data_observer.hpp b/src/mbgl/tile/tile_data_observer.hpp deleted file mode 100644 index b950fc0b7..000000000 --- a/src/mbgl/tile/tile_data_observer.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -namespace mbgl { - -class TileData; - -class TileDataObserver { -public: - virtual ~TileDataObserver() = default; - - virtual void onTileLoaded(TileData&, bool /*isNewTile*/) {} - virtual void onTileError(TileData&, std::exception_ptr) {} - virtual void onNeedsRepaint() {} -}; - -} // namespace mbgl diff --git a/src/mbgl/tile/tile_observer.hpp b/src/mbgl/tile/tile_observer.hpp new file mode 100644 index 000000000..96ded11fb --- /dev/null +++ b/src/mbgl/tile/tile_observer.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace mbgl { + +class Tile; + +class TileObserver { +public: + virtual ~TileObserver() = default; + + virtual void onTileLoaded(Tile&, bool /*isNewTile*/) {} + virtual void onTileError(Tile&, std::exception_ptr) {} + virtual void onNeedsRepaint() {} +}; + +} // namespace mbgl diff --git a/src/mbgl/tile/tile_source.hpp b/src/mbgl/tile/tile_source.hpp index f1a0a1c92..b4aff4492 100644 --- a/src/mbgl/tile/tile_source.hpp +++ b/src/mbgl/tile/tile_source.hpp @@ -58,7 +58,7 @@ private: void loadedData(const Response&); void loadRequired(); - T& tileData; + T& tile; Necessity necessity; Resource resource; FileSource& fileSource; diff --git a/src/mbgl/tile/tile_source_impl.hpp b/src/mbgl/tile/tile_source_impl.hpp index 625a0e202..51591aa53 100644 --- a/src/mbgl/tile/tile_source_impl.hpp +++ b/src/mbgl/tile/tile_source_impl.hpp @@ -10,11 +10,11 @@ namespace mbgl { template -TileSource::TileSource(T& tileData_, +TileSource::TileSource(T& tile_, const OverscaledTileID& id, const style::UpdateParameters& parameters, const Tileset& tileset) - : tileData(tileData_), + : tile(tile_), necessity(Necessity::Optional), resource(Resource::tile( tileset.tiles.at(0), @@ -51,7 +51,7 @@ void TileSource::loadOptional() { request = fileSource.request(resource, [this](Response res) { request.reset(); - tileData.setTriedOptional(); + tile.setTriedOptional(); if (res.error && res.error->reason == Response::Error::Reason::NotFound) { // When the optional request could not be satisfied, don't treat it as an error. @@ -86,16 +86,16 @@ void TileSource::makeOptional() { template void TileSource::loadedData(const Response& res) { if (res.error && res.error->reason != Response::Error::Reason::NotFound) { - tileData.setError(std::make_exception_ptr(std::runtime_error(res.error->message))); + tile.setError(std::make_exception_ptr(std::runtime_error(res.error->message))); } else if (res.notModified) { resource.priorExpires = res.expires; - // Do not notify the TileData object; when we get this message, it already has the current + // Do not notify the tile; when we get this message, it already has the current // version of the data. } else { resource.priorModified = res.modified; resource.priorExpires = res.expires; resource.priorEtag = res.etag; - tileData.setData(res.noContent ? nullptr : res.data, res.modified, res.expires); + tile.setData(res.noContent ? nullptr : res.data, res.modified, res.expires); } } diff --git a/src/mbgl/tile/tile_worker.cpp b/src/mbgl/tile/tile_worker.cpp index 1890aa7c4..358cfd3ca 100644 --- a/src/mbgl/tile/tile_worker.cpp +++ b/src/mbgl/tile/tile_worker.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -40,14 +40,14 @@ TileWorker::~TileWorker() { } TileParseResult TileWorker::parseAllLayers(std::vector> layers_, - std::unique_ptr geometryTile_, + std::unique_ptr tileData_, PlacementConfig config) { // We're doing a fresh parse of the tile, because the underlying data has changed. pending.clear(); placementPending.clear(); partialParse = false; featureIndex = std::make_unique(); - geometryTile = std::move(geometryTile_); + tileData = std::move(tileData_); // Store the layers for use in redoPlacement. layers = std::move(layers_); @@ -98,7 +98,7 @@ TileParseResult TileWorker::prepareResult(const PlacementConfig& config) { if (result.complete) { featureIndex->setCollisionTile(placeLayers(config)); result.featureIndex = std::move(featureIndex); - result.geometryTile = std::move(geometryTile); + result.tileData = std::move(tileData); } return std::move(result); @@ -147,7 +147,7 @@ void TileWorker::parseLayer(const Layer* layer) { return; } - auto geometryLayer = geometryTile->getLayer(layer->baseImpl->sourceLayer); + auto geometryLayer = tileData->getLayer(layer->baseImpl->sourceLayer); if (!geometryLayer) { // The layer specified in the bucket does not exist. Do nothing. if (debug::tileParseWarnings) { diff --git a/src/mbgl/tile/tile_worker.hpp b/src/mbgl/tile/tile_worker.hpp index 631a8c929..b32545968 100644 --- a/src/mbgl/tile/tile_worker.hpp +++ b/src/mbgl/tile/tile_worker.hpp @@ -18,7 +18,7 @@ namespace mbgl { class CollisionTile; -class GeometryTile; +class GeometryTileData; class SpriteStore; class GlyphAtlas; class GlyphStore; @@ -36,7 +36,7 @@ public: bool complete = false; std::unordered_map> buckets; std::unique_ptr featureIndex; - std::unique_ptr geometryTile; + std::unique_ptr tileData; }; using TileParseResult = variant< @@ -55,7 +55,7 @@ public: ~TileWorker(); TileParseResult parseAllLayers(std::vector>, - std::unique_ptr geometryTile, + std::unique_ptr tileData, PlacementConfig); TileParseResult parsePendingLayers(PlacementConfig); @@ -83,7 +83,7 @@ private: std::vector> layers; std::unique_ptr featureIndex; - std::unique_ptr geometryTile; + std::unique_ptr tileData; // Contains buckets that we couldn't parse so far due to missing resources. // They will be attempted on subsequent parses. diff --git a/src/mbgl/tile/vector_tile.cpp b/src/mbgl/tile/vector_tile.cpp index dc4ed04d7..cd61b52c8 100644 --- a/src/mbgl/tile/vector_tile.cpp +++ b/src/mbgl/tile/vector_tile.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include @@ -44,7 +44,7 @@ public: std::string getName() const override; private: - friend class VectorTile; + friend class VectorTileData; friend class VectorTileFeature; std::string name; @@ -56,9 +56,9 @@ private: std::vector features; }; -class VectorTile : public GeometryTile { +class VectorTileData : public GeometryTileData { public: - VectorTile(std::shared_ptr data); + VectorTileData(std::shared_ptr data); util::ptr getLayer(const std::string&) const override; @@ -68,22 +68,22 @@ private: mutable std::map> layers; }; -VectorTileData::VectorTileData(const OverscaledTileID& id_, - std::string sourceID, - const style::UpdateParameters& parameters, - const Tileset& tileset) - : GeometryTileData(id_, sourceID, parameters.style, parameters.mode), +VectorTile::VectorTile(const OverscaledTileID& id_, + std::string sourceID, + const style::UpdateParameters& parameters, + const Tileset& tileset) + : GeometryTile(id_, sourceID, parameters.style, parameters.mode), tileSource(*this, id_, parameters, tileset) { } -void VectorTileData::setNecessity(Necessity necessity) { - tileSource.setNecessity(static_cast::Necessity>(necessity)); +void VectorTile::setNecessity(Necessity necessity) { + tileSource.setNecessity(static_cast::Necessity>(necessity)); } -void VectorTileData::setData(std::shared_ptr data, - optional modified, - optional expires) { - GeometryTileData::setData(data ? std::make_unique(data) : nullptr, modified, expires); +void VectorTile::setData(std::shared_ptr data_, + optional modified_, + optional expires_) { + GeometryTile::setData(data_ ? std::make_unique(data_) : nullptr, modified_, expires_); } Value parseValue(protozero::pbf_reader data) { @@ -236,11 +236,11 @@ GeometryCollection VectorTileFeature::getGeometries() const { return fixupPolygons(lines); } -VectorTile::VectorTile(std::shared_ptr data_) +VectorTileData::VectorTileData(std::shared_ptr data_) : data(std::move(data_)) { } -util::ptr VectorTile::getLayer(const std::string& name) const { +util::ptr VectorTileData::getLayer(const std::string& name) const { if (!parsed) { parsed = true; protozero::pbf_reader tile_pbf(*data); diff --git a/src/mbgl/tile/vector_tile.hpp b/src/mbgl/tile/vector_tile.hpp index 4815f9276..a7e808af4 100644 --- a/src/mbgl/tile/vector_tile.hpp +++ b/src/mbgl/tile/vector_tile.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include namespace mbgl { @@ -11,12 +11,12 @@ namespace style { class UpdateParameters; } -class VectorTileData : public GeometryTileData { +class VectorTile : public GeometryTile { public: - VectorTileData(const OverscaledTileID&, - std::string sourceID, - const style::UpdateParameters&, - const Tileset&); + VectorTile(const OverscaledTileID&, + std::string sourceID, + const style::UpdateParameters&, + const Tileset&); void setNecessity(Necessity) final; void setData(std::shared_ptr data, @@ -24,7 +24,7 @@ public: optional expires); private: - TileSource tileSource; + TileSource tileSource; }; } // namespace mbgl diff --git a/src/mbgl/util/intersection_tests.hpp b/src/mbgl/util/intersection_tests.hpp index a3ffe65cb..6922c6afb 100644 --- a/src/mbgl/util/intersection_tests.hpp +++ b/src/mbgl/util/intersection_tests.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace mbgl { namespace util { diff --git a/src/mbgl/util/worker.cpp b/src/mbgl/util/worker.cpp index 2bc545c70..50ecb93c0 100644 --- a/src/mbgl/util/worker.cpp +++ b/src/mbgl/util/worker.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -31,11 +31,11 @@ public: void parseGeometryTile(TileWorker* worker, std::vector> layers, - std::unique_ptr tile, + std::unique_ptr tileData, PlacementConfig config, std::function callback) { try { - callback(worker->parseAllLayers(std::move(layers), std::move(tile), config)); + callback(worker->parseAllLayers(std::move(layers), std::move(tileData), config)); } catch (...) { callback(std::current_exception()); } @@ -80,12 +80,12 @@ Worker::parseRasterTile(std::unique_ptr bucket, std::unique_ptr Worker::parseGeometryTile(TileWorker& worker, std::vector> layers, - std::unique_ptr tile, + std::unique_ptr tileData, PlacementConfig config, std::function callback) { current = (current + 1) % threads.size(); return threads[current]->invokeWithCallback(&Worker::Impl::parseGeometryTile, callback, &worker, - std::move(layers), std::move(tile), config); + std::move(layers), std::move(tileData), config); } std::unique_ptr diff --git a/src/mbgl/util/worker.hpp b/src/mbgl/util/worker.hpp index 678dfaedb..5ab86d1b9 100644 --- a/src/mbgl/util/worker.hpp +++ b/src/mbgl/util/worker.hpp @@ -41,7 +41,7 @@ public: Request parseGeometryTile(TileWorker&, std::vector>, - std::unique_ptr, + std::unique_ptr, PlacementConfig, std::function callback); diff --git a/test/style/filter.cpp b/test/style/filter.cpp index c013c36cd..f8f56d931 100644 --- a/test/style/filter.cpp +++ b/test/style/filter.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include diff --git a/test/test.gypi b/test/test.gypi index d93ecd1f3..d7023874f 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -56,7 +56,7 @@ 'math/minmax.cpp', 'math/clamp.cpp', - 'tile/geometry_tile.cpp', + 'tile/geometry_tile_data.cpp', 'tile/tile_id.cpp', 'storage/offline.cpp', diff --git a/test/tile/geometry_tile.cpp b/test/tile/geometry_tile_data.cpp similarity index 88% rename from test/tile/geometry_tile.cpp rename to test/tile/geometry_tile_data.cpp index 998a7183a..6e118d6fd 100644 --- a/test/tile/geometry_tile.cpp +++ b/test/tile/geometry_tile_data.cpp @@ -1,9 +1,9 @@ #include -#include +#include using namespace mbgl; -TEST(GeometryTile, classifyRings1) { +TEST(GeometryTileData, classifyRings1) { std::vector polygons = classifyRings({ { {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} } }); @@ -14,7 +14,7 @@ TEST(GeometryTile, classifyRings1) { ASSERT_EQ(polygons[0].size(), 1u); } -TEST(GeometryTile, classifyRings2) { +TEST(GeometryTileData, classifyRings2) { std::vector polygons = classifyRings({ { {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} }, { {10, 10}, {20, 10}, {20, 20}, {10, 10} } @@ -26,7 +26,7 @@ TEST(GeometryTile, classifyRings2) { ASSERT_EQ(polygons[0].size(), 2u); } -TEST(GeometryTile, limitHoles1) { +TEST(GeometryTileData, limitHoles1) { GeometryCollection polygon = { { {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} }, { {30, 30}, {32, 30}, {32, 32}, {30, 30} }, @@ -43,7 +43,7 @@ TEST(GeometryTile, limitHoles1) { ASSERT_EQ(polygon[1][0].x, 10); } -TEST(GeometryTile, limitHoles2) { +TEST(GeometryTileData, limitHoles2) { GeometryCollection polygon = { { {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} }, { {10, 10}, {20, 10}, {20, 20}, {10, 10} },