diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2018-11-13 17:39:26 +0200 |
---|---|---|
committer | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2018-11-19 14:06:21 +0200 |
commit | 77911f1cc955b1adeb143dd15f6fc0d77763440c (patch) | |
tree | e8a84100c7eae6ab23ffc1a4420db3ed6760dd01 /src/mbgl | |
parent | 20c471669c102d1740558c2c7d1ea77bb9ef8530 (diff) | |
download | qtlocation-mapboxgl-77911f1cc955b1adeb143dd15f6fc0d77763440c.tar.gz |
[core] Replace RenderSymbolLayer downcast with symbol interface
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/geometry/feature_index.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_layer_symbol_interface.hpp | 22 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/renderer/render_layer.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/render_layer.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 64 | ||||
-rw-r--r-- | src/mbgl/text/cross_tile_symbol_index.cpp | 11 | ||||
-rw-r--r-- | src/mbgl/text/cross_tile_symbol_index.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/text/placement.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/text/placement.hpp | 6 |
11 files changed, 108 insertions, 56 deletions
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp index 651e3b9c56..7dc46c4dfc 100644 --- a/src/mbgl/geometry/feature_index.cpp +++ b/src/mbgl/geometry/feature_index.cpp @@ -155,7 +155,7 @@ void FeatureIndex::addFeature( assert(geometryTileFeature); } - if (!renderLayer->is<RenderSymbolLayer>() && + if (!renderLayer->getSymbolInterface() && !renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, transformState, pixelsToTileUnits, posMatrix)) { continue; } diff --git a/src/mbgl/renderer/layers/render_layer_symbol_interface.hpp b/src/mbgl/renderer/layers/render_layer_symbol_interface.hpp new file mode 100644 index 0000000000..e5c16c6e7c --- /dev/null +++ b/src/mbgl/renderer/layers/render_layer_symbol_interface.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include <memory> +#include <vector> +#include <string> + +namespace mbgl { + +class RenderTile; +class SymbolBucket; + +class RenderLayerSymbolInterface { +public: + virtual const std::string& layerID() const = 0; + virtual const std::vector<std::reference_wrapper<RenderTile>>& getRenderTiles() const = 0; + virtual SymbolBucket* getSymbolBucket(const RenderTile&) const = 0; + +protected: + virtual ~RenderLayerSymbolInterface() = default; +}; + +} // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 6d2c090aef..2b3a7195c5 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -74,6 +74,22 @@ bool RenderSymbolLayer::hasCrossfade() const { return false; } +const std::string& RenderSymbolLayer::layerID() const { + return RenderLayer::getID(); +} + +const RenderLayerSymbolInterface* RenderSymbolLayer::getSymbolInterface() const { + return this; +} + +const std::vector<std::reference_wrapper<RenderTile>>& RenderSymbolLayer::getRenderTiles() const { + return renderTiles; +} + +SymbolBucket* RenderSymbolLayer::getSymbolBucket(const RenderTile& renderTile) const { + return renderTile.tile.getBucket<SymbolBucket>(*baseImpl); +} + void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index 7c52467e56..105754befa 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -2,6 +2,7 @@ #include <mbgl/text/glyph.hpp> #include <mbgl/renderer/render_layer.hpp> +#include <mbgl/renderer/layers/render_layer_symbol_interface.hpp> #include <mbgl/style/image_impl.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> #include <mbgl/style/layers/symbol_layer_properties.hpp> @@ -56,7 +57,7 @@ class BucketParameters; class SymbolLayout; class GeometryTileLayer; -class RenderSymbolLayer: public RenderLayer { +class RenderSymbolLayer: public RenderLayer, public RenderLayerSymbolInterface { public: RenderSymbolLayer(Immutable<style::SymbolLayer::Impl>); ~RenderSymbolLayer() final = default; @@ -80,6 +81,12 @@ public: GlyphDependencies&, ImageDependencies&) const override; + // RenderLayerSymbolInterface overrides + const RenderLayerSymbolInterface* getSymbolInterface() const final; + const std::string& layerID() const final; + const std::vector<std::reference_wrapper<RenderTile>>& getRenderTiles() const final; + SymbolBucket* getSymbolBucket(const RenderTile&) const final; + // Paint properties style::SymbolPaintProperties::Unevaluated unevaluated; style::SymbolPaintProperties::PossiblyEvaluated evaluated; diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index efd890eda8..3e9a7caf24 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -86,6 +86,10 @@ void RenderLayer::sortRenderTiles(const TransformState&) { std::sort(renderTiles.begin(), renderTiles.end(), [](const auto& a, const auto& b) { return a.get().id < b.get().id; }); } +const RenderLayerSymbolInterface* RenderLayer::getSymbolInterface() const { + return nullptr; +} + void RenderLayer::update() { // no-op } diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index b335a468b0..349b5d412a 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -17,6 +17,7 @@ class TransitionParameters; class PropertyEvaluationParameters; class PaintParameters; class RenderSource; +class RenderLayerSymbolInterface; class RenderTile; class TransformState; @@ -43,6 +44,9 @@ public: // Returns true if the layer has a pattern property and is actively crossfading. virtual bool hasCrossfade() const = 0; + // Returns instance of RenderLayerSymbolInterface if RenderLayer supports it. + virtual const RenderLayerSymbolInterface* getSymbolInterface() const; + // Check whether this layer is of the given subtype. template <class T> bool is() const; @@ -118,10 +122,6 @@ protected: RenderTiles filterRenderTiles(RenderTiles, FilterFunctionPtr) const; protected: - // renderTiles are exposed directly to CrossTileSymbolIndex and Placement so they - // can update opacities in the symbol buckets immediately before rendering - friend class CrossTileSymbolIndex; - friend class Placement; // Stores current set of tiles to be rendered for this layer. std::vector<std::reference_wrapper<RenderTile>> renderTiles; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 124c16cb64..420d90b327 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -322,46 +322,48 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { order.emplace_back(RenderItem { *layer, source }); } - bool symbolBucketsChanged = false; - if (parameters.mapMode != MapMode::Continuous) { - // TODO: Think about right way for symbol index to handle still rendering - crossTileSymbolIndex.reset(); - } - for (auto it = order.rbegin(); it != order.rend(); ++it) { - if (it->layer.is<RenderSymbolLayer>()) { - const float lng = parameters.state.getLatLng().longitude(); - if (crossTileSymbolIndex.addLayer(*it->layer.as<RenderSymbolLayer>(), lng)) symbolBucketsChanged = true; + { + if (parameters.mapMode != MapMode::Continuous) { + // TODO: Think about right way for symbol index to handle still rendering + crossTileSymbolIndex.reset(); } - } - bool placementChanged = false; - if (!placement->stillRecent(parameters.timePoint)) { - placementChanged = true; + std::vector<RenderItem> renderItemsWithSymbols; + std::copy_if(order.rbegin(), order.rend(), std::back_inserter(renderItemsWithSymbols), + [](const auto& item) { return item.layer.getSymbolInterface() != nullptr; }); - auto newPlacement = std::make_unique<Placement>(parameters.state, parameters.mapMode, updateParameters.crossSourceCollisions); + bool symbolBucketsChanged = false; + const bool placementChanged = !placement->stillRecent(parameters.timePoint); + std::unique_ptr<Placement> newPlacement; std::set<std::string> usedSymbolLayers; - for (auto it = order.rbegin(); it != order.rend(); ++it) { - if (it->layer.is<RenderSymbolLayer>()) { - usedSymbolLayers.insert(it->layer.getID()); - newPlacement->placeLayer(*it->layer.as<RenderSymbolLayer>(), parameters.projMatrix, parameters.debugOptions & MapDebugOptions::Collision); + + if (placementChanged) { + newPlacement = std::make_unique<Placement>(parameters.state, parameters.mapMode, updateParameters.crossSourceCollisions); + } + + for (const auto& item : renderItemsWithSymbols) { + if (crossTileSymbolIndex.addLayer(*item.layer.getSymbolInterface(), parameters.state.getLatLng().longitude())) symbolBucketsChanged = true; + + if (newPlacement) { + usedSymbolLayers.insert(item.layer.getID()); + newPlacement->placeLayer(*item.layer.getSymbolInterface(), parameters.projMatrix, parameters.debugOptions & MapDebugOptions::Collision); } } - newPlacement->commit(*placement, parameters.timePoint); - crossTileSymbolIndex.pruneUnusedLayers(usedSymbolLayers); - placement = std::move(newPlacement); - - updateFadingTiles(); - } else { - placement->setStale(); - } + if (newPlacement) { + newPlacement->commit(*placement, parameters.timePoint); + crossTileSymbolIndex.pruneUnusedLayers(usedSymbolLayers); + placement = std::move(newPlacement); + updateFadingTiles(); + } else { + placement->setStale(); + } - parameters.symbolFadeChange = placement->symbolFadeChange(parameters.timePoint); + parameters.symbolFadeChange = placement->symbolFadeChange(parameters.timePoint); - if (placementChanged || symbolBucketsChanged) { - for (auto it = order.rbegin(); it != order.rend(); ++it) { - if (it->layer.is<RenderSymbolLayer>()) { - placement->updateLayerOpacities(*it->layer.as<RenderSymbolLayer>()); + if (placementChanged || symbolBucketsChanged) { + for (const auto& item : renderItemsWithSymbols) { + placement->updateLayerOpacities(*item.layer.getSymbolInterface()); } } } diff --git a/src/mbgl/text/cross_tile_symbol_index.cpp b/src/mbgl/text/cross_tile_symbol_index.cpp index 98b9af1f94..0992433ccb 100644 --- a/src/mbgl/text/cross_tile_symbol_index.cpp +++ b/src/mbgl/text/cross_tile_symbol_index.cpp @@ -1,6 +1,7 @@ #include <mbgl/text/cross_tile_symbol_index.hpp> #include <mbgl/layout/symbol_instance.hpp> #include <mbgl/renderer/buckets/symbol_bucket.hpp> +#include <mbgl/renderer/layers/render_layer_symbol_interface.hpp> #include <mbgl/renderer/render_tile.hpp> #include <mbgl/tile/tile.hpp> @@ -164,27 +165,27 @@ bool CrossTileSymbolLayerIndex::removeStaleBuckets(const std::unordered_set<uint CrossTileSymbolIndex::CrossTileSymbolIndex() {} -bool CrossTileSymbolIndex::addLayer(RenderSymbolLayer& symbolLayer, float lng) { +bool CrossTileSymbolIndex::addLayer(const RenderLayerSymbolInterface& symbolInterface, float lng) { - auto& layerIndex = layerIndexes[symbolLayer.getID()]; + auto& layerIndex = layerIndexes[symbolInterface.layerID()]; bool symbolBucketsChanged = false; std::unordered_set<uint32_t> currentBucketIDs; layerIndex.handleWrapJump(lng); - for (RenderTile& renderTile : symbolLayer.renderTiles) { + for (const RenderTile& renderTile : symbolInterface.getRenderTiles()) { if (!renderTile.tile.isRenderable()) { continue; } - auto bucket = renderTile.tile.getBucket<SymbolBucket>(*symbolLayer.baseImpl); + auto bucket = symbolInterface.getSymbolBucket(renderTile); if (!bucket) { continue; } SymbolBucket& symbolBucket = *bucket; - if (symbolBucket.bucketLeaderID != symbolLayer.getID()) { + if (symbolBucket.bucketLeaderID != symbolInterface.layerID()) { // Only add this layer if it's the "group leader" for the bucket continue; } diff --git a/src/mbgl/text/cross_tile_symbol_index.hpp b/src/mbgl/text/cross_tile_symbol_index.hpp index 051573e1d2..528147f146 100644 --- a/src/mbgl/text/cross_tile_symbol_index.hpp +++ b/src/mbgl/text/cross_tile_symbol_index.hpp @@ -15,7 +15,7 @@ namespace mbgl { class SymbolInstance; -class RenderSymbolLayer; +class RenderLayerSymbolInterface; class SymbolBucket; class IndexedSymbolInstance { @@ -58,7 +58,7 @@ class CrossTileSymbolIndex { public: CrossTileSymbolIndex(); - bool addLayer(RenderSymbolLayer&, float lng); + bool addLayer(const RenderLayerSymbolInterface&, float lng); void pruneUnusedLayers(const std::set<std::string>&); void reset(); diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 5c6cdcde6c..367e421412 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -1,6 +1,6 @@ #include <mbgl/text/placement.hpp> #include <mbgl/renderer/render_layer.hpp> -#include <mbgl/renderer/layers/render_symbol_layer.hpp> +#include <mbgl/renderer/layers/render_layer_symbol_interface.hpp> #include <mbgl/renderer/render_tile.hpp> #include <mbgl/tile/geometry_tile.hpp> #include <mbgl/renderer/buckets/symbol_bucket.hpp> @@ -62,24 +62,24 @@ Placement::Placement(const TransformState& state_, MapMode mapMode_, const bool , collisionGroups(crossSourceCollisions) {} -void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatrix, bool showCollisionBoxes) { +void Placement::placeLayer(const RenderLayerSymbolInterface& symbolInterface, const mat4& projMatrix, bool showCollisionBoxes) { std::unordered_set<uint32_t> seenCrossTileIDs; - for (RenderTile& renderTile : symbolLayer.renderTiles) { + for (const RenderTile& renderTile : symbolInterface.getRenderTiles()) { if (!renderTile.tile.isRenderable()) { continue; } assert(renderTile.tile.kind == Tile::Kind::Geometry); GeometryTile& geometryTile = static_cast<GeometryTile&>(renderTile.tile); - auto bucket = renderTile.tile.getBucket<SymbolBucket>(*symbolLayer.baseImpl); + auto bucket = symbolInterface.getSymbolBucket(renderTile); if (!bucket) { continue; } SymbolBucket& symbolBucket = *bucket; - if (symbolBucket.bucketLeaderID != symbolLayer.getID()) { + if (symbolBucket.bucketLeaderID != symbolInterface.layerID()) { // Only place this layer if it's the "group leader" for the bucket continue; } @@ -276,20 +276,20 @@ void Placement::commit(const Placement& prevPlacement, TimePoint now) { fadeStartTime = placementChanged ? commitTime : prevPlacement.fadeStartTime; } -void Placement::updateLayerOpacities(RenderSymbolLayer& symbolLayer) { +void Placement::updateLayerOpacities(const RenderLayerSymbolInterface& symbolInterface) { std::set<uint32_t> seenCrossTileIDs; - for (RenderTile& renderTile : symbolLayer.renderTiles) { + for (const RenderTile& renderTile : symbolInterface.getRenderTiles()) { if (!renderTile.tile.isRenderable()) { continue; } - auto bucket = renderTile.tile.getBucket<SymbolBucket>(*symbolLayer.baseImpl); + auto bucket = symbolInterface.getSymbolBucket(renderTile); if (!bucket) { continue; } SymbolBucket& symbolBucket = *bucket; - if (symbolBucket.bucketLeaderID != symbolLayer.getID()) { + if (symbolBucket.bucketLeaderID != symbolInterface.layerID()) { // Only update opacities this layer if it's the "group leader" for the bucket continue; } diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index 8527d6df57..f34a8a25c2 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -9,7 +9,7 @@ namespace mbgl { -class RenderSymbolLayer; +class RenderLayerSymbolInterface; class SymbolBucket; class OpacityState { @@ -80,9 +80,9 @@ private: class Placement { public: Placement(const TransformState&, MapMode mapMode, const bool crossSourceCollisions); - void placeLayer(RenderSymbolLayer&, const mat4&, bool showCollisionBoxes); + void placeLayer(const RenderLayerSymbolInterface&, const mat4&, bool showCollisionBoxes); void commit(const Placement& prevPlacement, TimePoint); - void updateLayerOpacities(RenderSymbolLayer&); + void updateLayerOpacities(const RenderLayerSymbolInterface&); float symbolFadeChange(TimePoint now) const; bool hasTransitions(TimePoint now) const; |