summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-05-25 17:26:10 +0300
committerThiago Marcos P. Santos <thiago@mapbox.com>2020-05-26 20:37:08 +0300
commitf5befeb2a4cd737562f27b6d7bb918cfd97d8bd8 (patch)
tree32af203f603958983325196c2df724dbdc7ee046
parentee77b3ab678bb7cfc2f3ab6fe67900784a00ffaf (diff)
downloadqtlocation-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.hpp5
-rw-r--r--render-test/runner.cpp2
-rw-r--r--src/mbgl/renderer/render_orchestrator.cpp2
-rw-r--r--src/mbgl/text/placement.cpp101
-rw-r--r--src/mbgl/text/placement.hpp19
-rw-r--r--test/map/map.test.cpp8
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;