diff options
author | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2020-05-25 17:26:10 +0300 |
---|---|---|
committer | Thiago Marcos P. Santos <thiago@mapbox.com> | 2020-05-26 20:37:08 +0300 |
commit | f5befeb2a4cd737562f27b6d7bb918cfd97d8bd8 (patch) | |
tree | 32af203f603958983325196c2df724dbdc7ee046 | |
parent | ee77b3ab678bb7cfc2f3ab6fe67900784a00ffaf (diff) | |
download | qtlocation-mapboxgl-f5befeb2a4cd737562f27b6d7bb918cfd97d8bd8.tar.gz |
[core] Enable `Renderer::collectPlacedSymbolData()` API for all map modes
Before, it was functional only for the `Tile` map mode.
-rw-r--r-- | include/mbgl/renderer/renderer.hpp | 5 | ||||
-rw-r--r-- | render-test/runner.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/render_orchestrator.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/text/placement.cpp | 101 | ||||
-rw-r--r-- | src/mbgl/text/placement.hpp | 19 | ||||
-rw-r--r-- | test/map/map.test.cpp | 8 |
6 files changed, 78 insertions, 59 deletions
diff --git a/include/mbgl/renderer/renderer.hpp b/include/mbgl/renderer/renderer.hpp index 1bd51f0f72..b72cc847c9 100644 --- a/include/mbgl/renderer/renderer.hpp +++ b/include/mbgl/renderer/renderer.hpp @@ -33,7 +33,8 @@ struct PlacedSymbolData { // Symbol icon was placed bool iconPlaced; // Symbol text or icon collision box intersects tile borders - bool intersectsTileBorder; + // (initialized only in tile mode) + optional<bool> intersectsTileBorder; // Viewport padding ({viewportPadding, viewportPadding} is a coordinate of the tile's top-left corner) float viewportPadding; // Layer id (leader of the symbol layout group) @@ -84,7 +85,7 @@ public: void dumpDebugLogs(); /** - * @brief In Tile map mode, enables or disables collecting of the placed symbols data, + * @brief Enables or disables collecting of the placed symbols data, * which can be obtained with `getPlacedSymbolsData()`. * * The placed symbols data collecting is disabled by default. diff --git a/render-test/runner.cpp b/render-test/runner.cpp index 3ccb0da0d7..31d8046180 100644 --- a/render-test/runner.cpp +++ b/render-test/runner.cpp @@ -832,7 +832,7 @@ void TestRunner::run(TestMetadata& metadata) { }; for (const auto& placedSymbol : placedSymbols) { - if (placedSymbol.intersectsTileBorder) { + if (placedSymbol.intersectsTileBorder && *placedSymbol.intersectsTileBorder) { if (placedSymbol.textCollisionBox) { findCutOffs( placedSymbol, *placedSymbol.textCollisionBox, placedSymbol.textPlaced, false /*isIcon*/); diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index 76b2044a17..f6c4cde9cd 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -380,7 +380,6 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree( } } // Symbol placement. - assert((updateParameters->mode == MapMode::Tile) || !placedSymbolDataCollected); bool symbolBucketsChanged = false; bool symbolBucketsAdded = false; std::set<std::string> usedSymbolLayers; @@ -412,6 +411,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree( symbolBucketsChanged |= renderTreeParameters->placementChanged; if (renderTreeParameters->placementChanged) { Mutable<Placement> placement = Placement::create(updateParameters, placementController.getPlacement()); + placement->collectPlacedSymbolData(placedSymbolDataCollected); placement->placeLayers(layersNeedPlacement); placementController.setPlacement(std::move(placement)); crossTileSymbolIndex.pruneUnusedLayers(usedSymbolLayers); diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index ab91291de7..1a2971e16e 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -606,7 +606,7 @@ JointPlacement Placement::placeSymbol(const SymbolInstance& symbolInstance, cons JointPlacement result( placeText || ctx.alwaysShowText, placeIcon || ctx.alwaysShowIcon, offscreen || bucket.justReloaded); placements.emplace(symbolInstance.crossTileID, result); - newSymbolPlaced(symbolInstance, ctx, result, ctx.placementType, textBoxes, iconBoxes); + recordSymbolPlacement(symbolInstance, ctx, result, ctx.placementType, textBoxes, iconBoxes); return result; } @@ -1199,8 +1199,41 @@ bool Placement::hasTransitions(TimePoint now) const { } const std::vector<PlacedSymbolData>& Placement::getPlacedSymbolsData() const { - const static std::vector<PlacedSymbolData> data; - return data; + return placedSymbolsData; +} + +bool Placement::recordSymbolPlacement(const SymbolInstance& symbol, + const PlacementContext& ctx, + const JointPlacement& placement, + style::SymbolPlacementType placementType, + const std::vector<ProjectedCollisionBox>& textCollisionBoxes, + const std::vector<ProjectedCollisionBox>& iconCollisionBoxes) { + if (!collectData || placementType != style::SymbolPlacementType::Point) return false; + + optional<mapbox::geometry::box<float>> textCollisionBox; + if (!textCollisionBoxes.empty()) { + assert(textCollisionBoxes.size() == 1u); + auto& box = textCollisionBoxes.front(); + assert(box.isBox()); + textCollisionBox = box.box(); + } + optional<mapbox::geometry::box<float>> iconCollisionBox; + if (!iconCollisionBoxes.empty()) { + assert(iconCollisionBoxes.size() == 1u); + auto& box = iconCollisionBoxes.front(); + assert(box.isBox()); + iconCollisionBox = box.box(); + } + PlacedSymbolData symbolData{symbol.key, + textCollisionBox, + iconCollisionBox, + placement.text, + placement.icon, + nullopt, + collisionIndex.getViewportPadding(), + ctx.getBucket().bucketLeaderID}; + placedSymbolsData.emplace_back(std::move(symbolData)); + return true; } const CollisionIndex& Placement::getCollisionIndex() const { @@ -1256,8 +1289,6 @@ public: private: void placeLayers(const RenderLayerReferences&) override; void placeSymbolBucket(const BucketPlacementData&, std::set<uint32_t>&) override; - void collectPlacedSymbolData(bool enable) override { collectData = enable; } - const std::vector<PlacedSymbolData>& getPlacedSymbolsData() const override { return placedSymbolsData; } optional<CollisionBoundaries> getAvoidEdges(const SymbolBucket&, const mat4&) override; bool canPlaceAtVariableAnchor(const CollisionBox& box, @@ -1266,23 +1297,21 @@ private: std::vector<style::TextVariableAnchorType>& anchors, const mat4& posMatrix, float textPixelRatio) override; - void newSymbolPlaced(const SymbolInstance&, - const PlacementContext&, - const JointPlacement&, - style::SymbolPlacementType, - const std::vector<ProjectedCollisionBox>&, - const std::vector<ProjectedCollisionBox>&) override; + bool recordSymbolPlacement(const SymbolInstance&, + const PlacementContext&, + const JointPlacement&, + style::SymbolPlacementType, + const std::vector<ProjectedCollisionBox>&, + const std::vector<ProjectedCollisionBox>&) override; bool shouldRetryPlacement(const JointPlacement&, const PlacementContext&); std::unordered_map<uint32_t, bool> locationCache; optional<CollisionBoundaries> tileBorders; std::set<uint32_t> seenCrossTileIDs; - std::vector<PlacedSymbolData> placedSymbolsData; std::vector<Intersection> intersections; bool populateIntersections = false; std::size_t currentIntersectionPriority{}; - bool collectData = false; }; void TilePlacement::placeLayers(const RenderLayerReferences& layers) { @@ -1496,38 +1525,22 @@ bool TilePlacement::canPlaceAtVariableAnchor(const CollisionBox& box, return (status.flags == IntersectStatus::None); } -void TilePlacement::newSymbolPlaced(const SymbolInstance& symbol, - const PlacementContext& ctx, - const JointPlacement& placement, - style::SymbolPlacementType placementType, - const std::vector<ProjectedCollisionBox>& textCollisionBoxes, - const std::vector<ProjectedCollisionBox>& iconCollisionBoxes) { - if (!collectData || placementType != style::SymbolPlacementType::Point || shouldRetryPlacement(placement, ctx)) - return; - - optional<mapbox::geometry::box<float>> textCollisionBox; - if (!textCollisionBoxes.empty()) { - assert(textCollisionBoxes.size() == 1u); - auto& box = textCollisionBoxes.front(); - assert(box.isBox()); - textCollisionBox = box.box(); - } - optional<mapbox::geometry::box<float>> iconCollisionBox; - if (!iconCollisionBoxes.empty()) { - assert(iconCollisionBoxes.size() == 1u); - auto& box = iconCollisionBoxes.front(); - assert(box.isBox()); - iconCollisionBox = box.box(); +bool TilePlacement::recordSymbolPlacement(const SymbolInstance& symbol, + const PlacementContext& ctx, + const JointPlacement& placement, + style::SymbolPlacementType placementType, + const std::vector<ProjectedCollisionBox>& textCollisionBoxes, + const std::vector<ProjectedCollisionBox>& iconCollisionBoxes) { + if (shouldRetryPlacement(placement, ctx) || + !Placement::recordSymbolPlacement( + symbol, ctx, placement, placementType, textCollisionBoxes, iconCollisionBoxes)) { + return false; } - PlacedSymbolData symbolData{symbol.key, - textCollisionBox, - iconCollisionBox, - placement.text, - placement.icon, - !placement.skipFade && populateIntersections, - collisionIndex.getViewportPadding(), - ctx.getBucket().bucketLeaderID}; - placedSymbolsData.emplace_back(std::move(symbolData)); + assert(!placedSymbolsData.empty()); + auto& addedData = placedSymbolsData.back(); + assert(!addedData.intersectsTileBorder); + addedData.intersectsTileBorder = !placement.skipFade && populateIntersections; + return true; } bool TilePlacement::shouldRetryPlacement(const JointPlacement& placement, const PlacementContext& ctx) { diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index 82a62718a4..864f195c80 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -123,8 +123,8 @@ public: virtual float symbolFadeChange(TimePoint now) const; virtual bool hasTransitions(TimePoint now) const; virtual bool transitionsEnabled() const; - virtual void collectPlacedSymbolData(bool /*enable*/) {} - virtual const std::vector<PlacedSymbolData>& getPlacedSymbolsData() const; + void collectPlacedSymbolData(bool enable) { collectData = enable; } + const std::vector<PlacedSymbolData>& getPlacedSymbolsData() const; const CollisionIndex& getCollisionIndex() const; TimePoint getCommitTime() const { return commitTime; } @@ -145,12 +145,13 @@ protected: JointPlacement placeSymbol(const SymbolInstance& symbolInstance, const PlacementContext&); void placeLayer(const RenderLayer&, std::set<uint32_t>&); virtual void commit(); - virtual void newSymbolPlaced(const SymbolInstance&, - const PlacementContext&, - const JointPlacement&, - style::SymbolPlacementType, - const std::vector<ProjectedCollisionBox>& /*textBoxes*/, - const std::vector<ProjectedCollisionBox>& /*iconBoxes*/) {} + // Returns `true` if data was recorded, otherwise returns `false`. + virtual bool recordSymbolPlacement(const SymbolInstance&, + const PlacementContext&, + const JointPlacement&, + style::SymbolPlacementType, + const std::vector<ProjectedCollisionBox>& textBoxes, + const std::vector<ProjectedCollisionBox>& iconBoxes); // Implentation specific hooks, which get called during a symbol bucket placement. virtual optional<CollisionBoundaries> getAvoidEdges(const SymbolBucket&, const mat4& /*posMatrix*/) { return nullopt; @@ -195,6 +196,8 @@ protected: CollisionGroups collisionGroups; mutable optional<Immutable<Placement>> prevPlacement; bool showCollisionBoxes = false; + std::vector<PlacedSymbolData> placedSymbolsData; + bool collectData = false; // Cache being used by placeSymbol() std::vector<ProjectedCollisionBox> textBoxes; diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 1d266b72e2..c221a80c4d 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -1556,7 +1556,7 @@ bool isInsideTile(const mapbox::geometry::box<float>& box, float padding, Size v } // namespace -TEST(Map, PlacedSymbolData) { +TEST(Map, PlacedSymbolDataTileMode) { MapTest<> test{std::move(MapOptions().withMapMode(MapMode::Tile))}; test.fileSource->tileResponse = makeResponse("vector.tile", true); @@ -1598,14 +1598,16 @@ TEST(Map, PlacedSymbolData) { EXPECT_NE(0u, symbolLayers.count(placedSymbol.layer)); if (placedSymbol.textPlaced && placedSymbol.textCollisionBox) { if (isInsideTile(*placedSymbol.textCollisionBox, placedSymbol.viewportPadding, viewportSize)) { - EXPECT_FALSE(placedSymbol.intersectsTileBorder); + ASSERT_TRUE(placedSymbol.intersectsTileBorder); + EXPECT_FALSE(*placedSymbol.intersectsTileBorder); ++placedTextInsideTile; } ++placedText; } if (placedSymbol.iconPlaced && placedSymbol.iconCollisionBox) { if (isInsideTile(*placedSymbol.iconCollisionBox, placedSymbol.viewportPadding, viewportSize)) { - EXPECT_FALSE(placedSymbol.intersectsTileBorder); + ASSERT_TRUE(placedSymbol.intersectsTileBorder); + EXPECT_FALSE(*placedSymbol.intersectsTileBorder); ++placedIconInsideTile; } ++placedIcon; |