summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmiao <zmiao.jamie@gmail.com>2019-08-16 12:29:06 +0300
committerzmiao <zmiao.jamie@gmail.com>2019-08-28 13:51:50 +0300
commit066304d83cf86c8a58c2d802a4fdc7740ad0afb4 (patch)
tree764502b7d43943b20ee2d852def9ebe56d558c6f
parent309f566800502f3314bc527c68ba6f41917d500e (diff)
downloadqtlocation-mapboxgl-066304d83cf86c8a58c2d802a4fdc7740ad0afb4.tar.gz
add initial fix
-rw-r--r--src/mbgl/layout/symbol_layout.cpp64
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp90
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp34
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp151
-rw-r--r--src/mbgl/style/layers/symbol_layer.cpp1
-rw-r--r--src/mbgl/text/placement.cpp71
-rw-r--r--test/gl/bucket.test.cpp3
7 files changed, 263 insertions, 151 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index fe169785ce..8dcc92cd60 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -807,30 +807,44 @@ size_t SymbolLayout::addSymbol(SymbolBucket::Buffer& buffer,
}
void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) {
-
+
if (!hasSymbolInstances()) {
return;
}
- for (const SymbolInstance &symbolInstance : symbolInstances) {
- auto populateCollisionBox = [&](const auto& feature) {
- SymbolBucket::CollisionBuffer& collisionBuffer = feature.alongLine ?
- static_cast<SymbolBucket::CollisionBuffer&>(bucket.getOrCreateCollisionCircleBuffer()) :
- static_cast<SymbolBucket::CollisionBuffer&>(bucket.getOrCreateCollisionBox());
- for (const CollisionBox &box : feature.boxes) {
+ for (const SymbolInstance& symbolInstance : symbolInstances) {
+ auto populateCollisionBox = [&](const auto& feature, bool isText) {
+ SymbolBucket::CollisionBuffer& collisionBuffer =
+ feature.alongLine ? (isText ? static_cast<SymbolBucket::CollisionBuffer&>(
+ bucket.getOrCreateTextCollisionCircleBuffer())
+ : static_cast<SymbolBucket::CollisionBuffer&>(
+ bucket.getOrCreateIconCollisionCircleBuffer()))
+ : (isText ? static_cast<SymbolBucket::CollisionBuffer&>(
+ bucket.getOrCreateTextCollisionBox())
+ : static_cast<SymbolBucket::CollisionBuffer&>(
+ bucket.getOrCreateIconCollisionBox()));
+
+ for (const CollisionBox& box : feature.boxes) {
auto& anchor = box.anchor;
- Point<float> tl{box.x1, box.y1};
- Point<float> tr{box.x2, box.y1};
- Point<float> bl{box.x1, box.y2};
- Point<float> br{box.x2, box.y2};
+ Point<float> tl{ box.x1, box.y1 };
+ Point<float> tr{ box.x2, box.y1 };
+ Point<float> bl{ box.x1, box.y2 };
+ Point<float> br{ box.x2, box.y2 };
static constexpr std::size_t vertexLength = 4;
const std::size_t indexLength = feature.alongLine ? 6 : 8;
- if (collisionBuffer.segments.empty() || collisionBuffer.segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
- collisionBuffer.segments.emplace_back(collisionBuffer.vertices.elements(),
- feature.alongLine ? bucket.collisionCircle->triangles.elements() : bucket.collisionBox->lines.elements());
+ if (collisionBuffer.segments.empty() ||
+ collisionBuffer.segments.back().vertexLength + vertexLength >
+ std::numeric_limits<uint16_t>::max()) {
+ collisionBuffer.segments.emplace_back(
+ collisionBuffer.vertices.elements(),
+ feature.alongLine
+ ? (isText ? bucket.textCollisionCircle->triangles.elements()
+ : bucket.iconCollisionCircle->triangles.elements())
+ : (isText ? bucket.textCollisionBox->lines.elements()
+ : bucket.iconCollisionBox->lines.elements()));
}
auto& segment = collisionBuffer.segments.back();
@@ -850,27 +864,29 @@ void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) {
collisionBuffer.dynamicVertices.emplace_back(dynamicVertex);
if (feature.alongLine) {
- bucket.collisionCircle->triangles.emplace_back(index, index + 1, index + 2);
- bucket.collisionCircle->triangles.emplace_back(index, index + 2, index + 3);
+ auto& collisionCircle = (isText ? bucket.textCollisionCircle : bucket.iconCollisionCircle);
+ collisionCircle->triangles.emplace_back(index, index + 1, index + 2);
+ collisionCircle->triangles.emplace_back(index, index + 2, index + 3);
} else {
- bucket.collisionBox->lines.emplace_back(index + 0, index + 1);
- bucket.collisionBox->lines.emplace_back(index + 1, index + 2);
- bucket.collisionBox->lines.emplace_back(index + 2, index + 3);
- bucket.collisionBox->lines.emplace_back(index + 3, index + 0);
+ auto& collisionBox = (isText ? bucket.textCollisionBox : bucket.iconCollisionBox);
+ collisionBox->lines.emplace_back(index + 0, index + 1);
+ collisionBox->lines.emplace_back(index + 1, index + 2);
+ collisionBox->lines.emplace_back(index + 2, index + 3);
+ collisionBox->lines.emplace_back(index + 3, index + 0);
}
segment.vertexLength += vertexLength;
segment.indexLength += indexLength;
}
};
- populateCollisionBox(symbolInstance.textCollisionFeature);
+ populateCollisionBox(symbolInstance.textCollisionFeature, true);
if (symbolInstance.verticalTextCollisionFeature) {
- populateCollisionBox(*symbolInstance.verticalTextCollisionFeature);
+ populateCollisionBox(*symbolInstance.verticalTextCollisionFeature, true);
}
if (symbolInstance.verticalIconCollisionFeature) {
- populateCollisionBox(*symbolInstance.verticalIconCollisionFeature);
+ populateCollisionBox(*symbolInstance.verticalIconCollisionFeature, false);
}
- populateCollisionBox(symbolInstance.iconCollisionFeature);
+ populateCollisionBox(symbolInstance.iconCollisionFeature, false);
}
}
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp
index a46c25a13b..90006f67f8 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.cpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp
@@ -118,30 +118,76 @@ void SymbolBucket::upload(gfx::UploadPass& uploadPass) {
updateIconBuffer(sdfIcon);
}
- if (hasCollisionBoxData()) {
+ if (hasIconCollisionBoxData()) {
if (!staticUploaded) {
- collisionBox->indexBuffer = uploadPass.createIndexBuffer(std::move(collisionBox->lines));
- collisionBox->vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox->vertices));
+ iconCollisionBox->indexBuffer =
+ uploadPass.createIndexBuffer(std::move(iconCollisionBox->lines));
+ iconCollisionBox->vertexBuffer =
+ uploadPass.createVertexBuffer(std::move(iconCollisionBox->vertices));
}
if (!placementChangesUploaded) {
- if (!collisionBox->dynamicVertexBuffer) {
- collisionBox->dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox->dynamicVertices), gfx::BufferUsageType::StreamDraw);
+ if (!iconCollisionBox->dynamicVertexBuffer) {
+ iconCollisionBox->dynamicVertexBuffer = uploadPass.createVertexBuffer(
+ std::move(iconCollisionBox->dynamicVertices), gfx::BufferUsageType::StreamDraw);
} else {
- uploadPass.updateVertexBuffer(*collisionBox->dynamicVertexBuffer, std::move(collisionBox->dynamicVertices));
+ uploadPass.updateVertexBuffer(*iconCollisionBox->dynamicVertexBuffer,
+ std::move(iconCollisionBox->dynamicVertices));
}
}
}
- if (hasCollisionCircleData()) {
+ if (hasTextCollisionBoxData()) {
if (!staticUploaded) {
- collisionCircle->indexBuffer = uploadPass.createIndexBuffer(std::move(collisionCircle->triangles));
- collisionCircle->vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle->vertices));
+ textCollisionBox->indexBuffer =
+ uploadPass.createIndexBuffer(std::move(textCollisionBox->lines));
+ textCollisionBox->vertexBuffer =
+ uploadPass.createVertexBuffer(std::move(textCollisionBox->vertices));
}
if (!placementChangesUploaded) {
- if (!collisionCircle->dynamicVertexBuffer) {
- collisionCircle->dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle->dynamicVertices), gfx::BufferUsageType::StreamDraw);
+ if (!textCollisionBox->dynamicVertexBuffer) {
+ textCollisionBox->dynamicVertexBuffer = uploadPass.createVertexBuffer(
+ std::move(textCollisionBox->dynamicVertices), gfx::BufferUsageType::StreamDraw);
} else {
- uploadPass.updateVertexBuffer(*collisionCircle->dynamicVertexBuffer, std::move(collisionCircle->dynamicVertices));
+ uploadPass.updateVertexBuffer(*textCollisionBox->dynamicVertexBuffer,
+ std::move(textCollisionBox->dynamicVertices));
+ }
+ }
+ }
+
+ if (hasIconCollisionCircleData()) {
+ if (!staticUploaded) {
+ iconCollisionCircle->indexBuffer =
+ uploadPass.createIndexBuffer(std::move(iconCollisionCircle->triangles));
+ iconCollisionCircle->vertexBuffer =
+ uploadPass.createVertexBuffer(std::move(iconCollisionCircle->vertices));
+ }
+ if (!placementChangesUploaded) {
+ if (!iconCollisionCircle->dynamicVertexBuffer) {
+ iconCollisionCircle->dynamicVertexBuffer =
+ uploadPass.createVertexBuffer(std::move(iconCollisionCircle->dynamicVertices),
+ gfx::BufferUsageType::StreamDraw);
+ } else {
+ uploadPass.updateVertexBuffer(*iconCollisionCircle->dynamicVertexBuffer,
+ std::move(iconCollisionCircle->dynamicVertices));
+ }
+ }
+ }
+
+ if (hasTextCollisionCircleData()) {
+ if (!staticUploaded) {
+ textCollisionCircle->indexBuffer =
+ uploadPass.createIndexBuffer(std::move(textCollisionCircle->triangles));
+ textCollisionCircle->vertexBuffer =
+ uploadPass.createVertexBuffer(std::move(textCollisionCircle->vertices));
+ }
+ if (!placementChangesUploaded) {
+ if (!textCollisionCircle->dynamicVertexBuffer) {
+ textCollisionCircle->dynamicVertexBuffer =
+ uploadPass.createVertexBuffer(std::move(textCollisionCircle->dynamicVertices),
+ gfx::BufferUsageType::StreamDraw);
+ } else {
+ uploadPass.updateVertexBuffer(*textCollisionCircle->dynamicVertexBuffer,
+ std::move(textCollisionCircle->dynamicVertices));
}
}
}
@@ -154,7 +200,7 @@ void SymbolBucket::upload(gfx::UploadPass& uploadPass) {
}
bool SymbolBucket::hasData() const {
- return hasTextData() || hasIconData() || hasSdfIconData() || hasCollisionBoxData();
+ return hasTextData() || hasIconData() || hasSdfIconData() || hasIconCollisionBoxData() || hasTextCollisionBoxData();
}
bool SymbolBucket::hasTextData() const {
@@ -168,15 +214,23 @@ bool SymbolBucket::hasIconData() const {
bool SymbolBucket::hasSdfIconData() const {
return !sdfIcon.segments.empty();
}
-
-bool SymbolBucket::hasCollisionBoxData() const {
- return collisionBox && !collisionBox->segments.empty();
+
+bool SymbolBucket::hasIconCollisionBoxData() const {
+ return iconCollisionBox && !iconCollisionBox->segments.empty();
}
-bool SymbolBucket::hasCollisionCircleData() const {
- return collisionCircle && !collisionCircle->segments.empty();
+bool SymbolBucket::hasIconCollisionCircleData() const {
+ return iconCollisionCircle && !iconCollisionCircle->segments.empty();
+}
+
+bool SymbolBucket::hasTextCollisionBoxData() const {
+ return textCollisionBox && !textCollisionBox->segments.empty();
}
+bool SymbolBucket::hasTextCollisionCircleData() const {
+ return textCollisionCircle && !textCollisionCircle->segments.empty();
+}
+
void addPlacedSymbol(gfx::IndexVector<gfx::Triangles>& triangles, const PlacedSymbol& placedSymbol) {
auto endIndex = placedSymbol.vertexStartIndex + placedSymbol.glyphOffsets.size() * 4;
for (auto vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) {
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index d813707c2f..020190b81f 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -72,8 +72,10 @@ public:
bool hasTextData() const;
bool hasIconData() const;
bool hasSdfIconData() const;
- bool hasCollisionBoxData() const;
- bool hasCollisionCircleData() const;
+ bool hasIconCollisionBoxData() const;
+ bool hasIconCollisionCircleData() const;
+ bool hasTextCollisionBoxData() const;
+ bool hasTextCollisionCircleData() const;
bool hasFormatSectionOverrides() const;
@@ -138,22 +140,34 @@ public:
gfx::IndexVector<gfx::Lines> lines;
optional<gfx::IndexBuffer> indexBuffer;
};
- std::unique_ptr<CollisionBoxBuffer> collisionBox;
+ std::unique_ptr<CollisionBoxBuffer> iconCollisionBox;
+ std::unique_ptr<CollisionBoxBuffer> textCollisionBox;
- CollisionBoxBuffer& getOrCreateCollisionBox() {
- if (!collisionBox) collisionBox = std::make_unique<CollisionBoxBuffer>();
- return *collisionBox;
+ CollisionBoxBuffer& getOrCreateIconCollisionBox() {
+ if (!iconCollisionBox) iconCollisionBox = std::make_unique<CollisionBoxBuffer>();
+ return *iconCollisionBox;
+ }
+
+ CollisionBoxBuffer& getOrCreateTextCollisionBox() {
+ if (!textCollisionBox) textCollisionBox = std::make_unique<CollisionBoxBuffer>();
+ return *textCollisionBox;
}
struct CollisionCircleBuffer : public CollisionBuffer {
gfx::IndexVector<gfx::Triangles> triangles;
optional<gfx::IndexBuffer> indexBuffer;
};
- std::unique_ptr<CollisionCircleBuffer> collisionCircle;
+ std::unique_ptr<CollisionCircleBuffer> iconCollisionCircle;
+ std::unique_ptr<CollisionCircleBuffer> textCollisionCircle;
+
+ CollisionCircleBuffer& getOrCreateIconCollisionCircleBuffer() {
+ if (!iconCollisionCircle) iconCollisionCircle = std::make_unique<CollisionCircleBuffer>();
+ return *iconCollisionCircle;
+ }
- CollisionCircleBuffer& getOrCreateCollisionCircleBuffer() {
- if (!collisionCircle) collisionCircle = std::make_unique<CollisionCircleBuffer>();
- return *collisionCircle;
+ CollisionCircleBuffer& getOrCreateTextCollisionCircleBuffer() {
+ if (!textCollisionCircle) textCollisionCircle = std::make_unique<CollisionCircleBuffer>();
+ return *textCollisionCircle;
}
const float tilePixelRatio;
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp
index d0c038222a..47dd484cf3 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp
@@ -392,78 +392,97 @@ void RenderSymbolLayer::render(PaintParameters& parameters) {
}
}
- if (bucket.hasCollisionBoxData()) {
- static const style::Properties<>::PossiblyEvaluated properties {};
- static const CollisionBoxProgram::Binders paintAttributeData(properties, 0);
-
- auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
- const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ);
- std::array<float,2> extrudeScale =
- {{
- parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
- parameters.pixelsToGLUnits[1] / (pixelRatio * scale)
- }};
+ static const style::Properties<>::PossiblyEvaluated properties {};
+ static const CollisionBoxProgram::Binders paintAttributeData(properties, 0);
+
+ auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
+ const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ);
+ std::array<float,2> extrudeScale =
+ {{
+ parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
+ parameters.pixelsToGLUnits[1] / (pixelRatio * scale)
+ }};
+ const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData->layerProperties);
+ const auto& layout = *bucket.layout;
+
+ if (bucket.hasIconCollisionBoxData()) {
+ const auto values = iconPropertyValues(evaluated, layout);
parameters.programs.getSymbolLayerPrograms().collisionBox.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Lines { 1.0f },
- gfx::DepthMode::disabled(),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- CollisionBoxProgram::LayoutUniformValues {
- uniforms::matrix::Value( tile.matrix ),
- uniforms::extrude_scale::Value( extrudeScale ),
- uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() )
- },
- *bucket.collisionBox->vertexBuffer,
- *bucket.collisionBox->dynamicVertexBuffer,
- *bucket.collisionBox->indexBuffer,
- bucket.collisionBox->segments,
- paintAttributeData,
- properties,
- CollisionBoxProgram::TextureBindings{},
- parameters.state.getZoom(),
- getID()
- );
+ parameters.context, *parameters.renderPass, gfx::Lines{ 1.0f },
+ gfx::DepthMode::disabled(), gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(),
+ CollisionBoxProgram::LayoutUniformValues{
+ uniforms::matrix::Value(tile.translatedMatrix(
+ values.translate, values.translateAnchor, parameters.state)),
+ uniforms::extrude_scale::Value(extrudeScale),
+ uniforms::camera_to_center_distance::Value(
+ parameters.state.getCameraToCenterDistance()) },
+ *bucket.iconCollisionBox->vertexBuffer,
+ *bucket.iconCollisionBox->dynamicVertexBuffer,
+ *bucket.iconCollisionBox->indexBuffer, bucket.iconCollisionBox->segments,
+ paintAttributeData, properties, CollisionBoxProgram::TextureBindings{},
+ parameters.state.getZoom(), getID());
}
- if (bucket.hasCollisionCircleData()) {
- static const style::Properties<>::PossiblyEvaluated properties {};
- static const CollisionBoxProgram::Binders paintAttributeData(properties, 0);
+ if (bucket.hasTextCollisionBoxData()) {
+ auto values = textPropertyValues(evaluated, layout);
+ parameters.programs.getSymbolLayerPrograms().collisionBox.draw(
+ parameters.context, *parameters.renderPass, gfx::Lines{ 1.0f },
+ gfx::DepthMode::disabled(), gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(),
+ CollisionBoxProgram::LayoutUniformValues{
+ uniforms::matrix::Value(tile.translatedMatrix(
+ values.translate, values.translateAnchor, parameters.state)),
+ uniforms::extrude_scale::Value(extrudeScale),
+ uniforms::camera_to_center_distance::Value(
+ parameters.state.getCameraToCenterDistance()) },
+ *bucket.textCollisionBox->vertexBuffer,
+ *bucket.textCollisionBox->dynamicVertexBuffer,
+ *bucket.textCollisionBox->indexBuffer, bucket.textCollisionBox->segments,
+ paintAttributeData, properties, CollisionBoxProgram::TextureBindings{},
+ parameters.state.getZoom(), getID());
+ }
- auto pixelRatio = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
- const float scale = std::pow(2, parameters.state.getZoom() - tile.getOverscaledTileID().overscaledZ);
- std::array<float,2> extrudeScale =
- {{
- parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
- parameters.pixelsToGLUnits[1] / (pixelRatio * scale)
- }};
+ if (bucket.hasIconCollisionCircleData()) {
+ auto values = iconPropertyValues(evaluated, layout);
+ parameters.programs.getSymbolLayerPrograms().collisionCircle.draw(
+ parameters.context, *parameters.renderPass, gfx::Triangles(),
+ gfx::DepthMode::disabled(), gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(),
+ CollisionCircleProgram::LayoutUniformValues{
+ uniforms::matrix::Value(tile.translatedMatrix(
+ values.translate, values.translateAnchor, parameters.state)),
+ uniforms::extrude_scale::Value(extrudeScale),
+ uniforms::overscale_factor::Value(
+ float(tile.getOverscaledTileID().overscaleFactor())),
+ uniforms::camera_to_center_distance::Value(
+ parameters.state.getCameraToCenterDistance()) },
+ *bucket.iconCollisionCircle->vertexBuffer,
+ *bucket.iconCollisionCircle->dynamicVertexBuffer,
+ *bucket.iconCollisionCircle->indexBuffer, bucket.iconCollisionCircle->segments,
+ paintAttributeData, properties, CollisionCircleProgram::TextureBindings{},
+ parameters.state.getZoom(), getID());
+ }
+ if (bucket.hasTextCollisionCircleData()) {
+ auto values = textPropertyValues(evaluated, layout);
parameters.programs.getSymbolLayerPrograms().collisionCircle.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- gfx::DepthMode::disabled(),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- CollisionCircleProgram::LayoutUniformValues {
- uniforms::matrix::Value( tile.matrix ),
- uniforms::extrude_scale::Value( extrudeScale ),
- uniforms::overscale_factor::Value( float(tile.getOverscaledTileID().overscaleFactor()) ),
- uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() )
- },
- *bucket.collisionCircle->vertexBuffer,
- *bucket.collisionCircle->dynamicVertexBuffer,
- *bucket.collisionCircle->indexBuffer,
- bucket.collisionCircle->segments,
- paintAttributeData,
- properties,
- CollisionCircleProgram::TextureBindings{},
- parameters.state.getZoom(),
- getID()
- );
+ parameters.context, *parameters.renderPass, gfx::Triangles(),
+ gfx::DepthMode::disabled(), gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(),
+ CollisionCircleProgram::LayoutUniformValues{
+ uniforms::matrix::Value(tile.translatedMatrix(
+ values.translate, values.translateAnchor, parameters.state)),
+ uniforms::extrude_scale::Value(extrudeScale),
+ uniforms::overscale_factor::Value(
+ float(tile.getOverscaledTileID().overscaleFactor())),
+ uniforms::camera_to_center_distance::Value(
+ parameters.state.getCameraToCenterDistance()) },
+ *bucket.textCollisionCircle->vertexBuffer,
+ *bucket.textCollisionCircle->dynamicVertexBuffer,
+ *bucket.textCollisionCircle->indexBuffer, bucket.textCollisionCircle->segments,
+ paintAttributeData, properties, CollisionCircleProgram::TextureBindings{},
+ parameters.state.getZoom(), getID());
}
}
diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp
index 4b335ead3c..d3c27ae264 100644
--- a/src/mbgl/style/layers/symbol_layer.cpp
+++ b/src/mbgl/style/layers/symbol_layer.cpp
@@ -9,6 +9,7 @@
#include <mbgl/style/conversion/transition_options.hpp>
#include <mbgl/style/conversion/json.hpp>
#include <mbgl/style/conversion_impl.hpp>
+#include <mbgl/style/expression/dsl.hpp>
#include <mapbox/eternal.hpp>
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index 9bc87911de..9c6fbea210 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -159,7 +159,8 @@ void Placement::placeBucket(
const bool rotateWithMap = layout.get<style::TextRotationAlignment>() == style::AlignmentType::Map;
const bool pitchWithMap = layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map;
const bool hasIconTextFit = layout.get<style::IconTextFit>() != style::IconTextFitType::None;
- const bool hasCollisionCircleData = bucket.hasCollisionCircleData();
+ const bool hasIconCollisionCircleData = bucket.hasIconCollisionCircleData();
+ const bool hasTextCollisionCircleData = bucket.hasTextCollisionCircleData();
const bool zOrderByViewportY = layout.get<style::SymbolZOrder>() == style::SymbolZOrderType::ViewportY;
std::vector<ProjectedCollisionBox> textBoxes;
@@ -418,13 +419,12 @@ void Placement::placeBucket(
}
}
- if (hasCollisionCircleData) {
- if (symbolInstance.iconCollisionFeature.alongLine && !iconBoxes.empty()) {
- collisionCircles[&symbolInstance.iconCollisionFeature] = iconBoxes;
- }
- if (symbolInstance.textCollisionFeature.alongLine && !textBoxes.empty()) {
- collisionCircles[&symbolInstance.textCollisionFeature] = textBoxes;
- }
+
+ if (hasIconCollisionCircleData && symbolInstance.iconCollisionFeature.alongLine && !iconBoxes.empty()) {
+ collisionCircles[&symbolInstance.iconCollisionFeature] = iconBoxes;
+ }
+ if (hasTextCollisionCircleData && symbolInstance.textCollisionFeature.alongLine && !textBoxes.empty()) {
+ collisionCircles[&symbolInstance.textCollisionFeature] = textBoxes;
}
assert(symbolInstance.crossTileID != 0);
@@ -696,8 +696,10 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
if (bucket.hasTextData()) bucket.text.opacityVertices.clear();
if (bucket.hasIconData()) bucket.icon.opacityVertices.clear();
if (bucket.hasSdfIconData()) bucket.sdfIcon.opacityVertices.clear();
- if (bucket.hasCollisionBoxData()) bucket.collisionBox->dynamicVertices.clear();
- if (bucket.hasCollisionCircleData()) bucket.collisionCircle->dynamicVertices.clear();
+ if (bucket.hasIconCollisionBoxData()) bucket.iconCollisionBox->dynamicVertices.clear();
+ if (bucket.hasIconCollisionCircleData()) bucket.iconCollisionCircle->dynamicVertices.clear();
+ if (bucket.hasTextCollisionBoxData()) bucket.textCollisionBox->dynamicVertices.clear();
+ if (bucket.hasTextCollisionCircleData()) bucket.textCollisionCircle->dynamicVertices.clear();
JointOpacityState duplicateOpacityState(false, false, true);
@@ -788,15 +790,15 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
}
}
- auto updateCollisionBox = [&](const auto& feature, const bool placed, const Point<float>& shift) {
+ auto updateIconCollisionBox = [&](const auto& feature, const bool placed, const Point<float>& shift) {
if (feature.alongLine) {
return;
}
const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false, shift);
- bucket.collisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
+ bucket.iconCollisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
};
- auto updateCollisionTextBox = [this, &bucket, &symbolInstance, &state, variablePlacement, rotateWithMap, pitchWithMap](const auto& feature, const bool placed) {
+ auto updateTextCollisionBox = [this, &bucket, &symbolInstance, &state, variablePlacement, rotateWithMap, pitchWithMap](const auto& feature, const bool placed) {
Point<float> shift{0.0f, 0.0f};
if (feature.alongLine) {
return shift;
@@ -826,11 +828,11 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
}
}
const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !used, shift);
- bucket.collisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
+ bucket.textCollisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
return shift;
};
- auto updateCollisionCircles = [&](const auto& feature, const bool placed) {
+ auto updateCollisionCircles = [&](const auto& feature, const bool placed, bool isText) {
if (!feature.alongLine) {
return;
}
@@ -838,31 +840,36 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
if (circles != collisionCircles.end()) {
for (const auto& circle : circles->second) {
const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !circle.isCircle(), {});
- bucket.collisionCircle->dynamicVertices.extend(4, dynamicVertex);
+ isText ? bucket.textCollisionCircle->dynamicVertices.extend(4, dynamicVertex):
+ bucket.iconCollisionCircle->dynamicVertices.extend(4, dynamicVertex);
}
} else {
// This feature was not placed, because it was not loaded or from a fading tile. Apply default values.
static const auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false /*not used*/, {});
- bucket.collisionCircle->dynamicVertices.extend(4 * feature.boxes.size(), dynamicVertex);
+ isText ? bucket.textCollisionCircle->dynamicVertices.extend(4, dynamicVertex):
+ bucket.iconCollisionCircle->dynamicVertices.extend(4, dynamicVertex);
}
};
-
- if (bucket.hasCollisionBoxData()) {
- const auto& textShift = updateCollisionTextBox(symbolInstance.textCollisionFeature, opacityState.text.placed);
- if (bucket.allowVerticalPlacement) {
- Point<float> verticalTextShift{0.0f, 0.0f};
- if (symbolInstance.verticalTextCollisionFeature) {
- verticalTextShift = updateCollisionTextBox(*symbolInstance.verticalTextCollisionFeature, opacityState.text.placed);
- }
- if (symbolInstance.verticalIconCollisionFeature) {
- updateCollisionBox(*symbolInstance.verticalIconCollisionFeature, opacityState.text.placed, hasIconTextFit ? verticalTextShift : Point<float>{0.0f, 0.0f});
- }
+ Point<float> textShift{0.0f, 0.0f};
+ Point<float> verticalTextShift{0.0f, 0.0f};
+ if (bucket.hasTextCollisionBoxData()) {
+ textShift = updateTextCollisionBox(symbolInstance.textCollisionFeature, opacityState.text.placed);
+ if (bucket.allowVerticalPlacement && symbolInstance.verticalTextCollisionFeature) {
+ verticalTextShift = updateTextCollisionBox(*symbolInstance.verticalTextCollisionFeature, opacityState.text.placed);
+ }
+ }
+ if (bucket.hasIconCollisionBoxData()) {
+ updateIconCollisionBox(symbolInstance.iconCollisionFeature, opacityState.icon.placed, hasIconTextFit ? textShift : Point<float>{0.0f, 0.0f});
+ if (bucket.allowVerticalPlacement && symbolInstance.verticalIconCollisionFeature) {
+ updateIconCollisionBox(*symbolInstance.verticalIconCollisionFeature, opacityState.text.placed, hasIconTextFit ? verticalTextShift : Point<float>{0.0f, 0.0f});
}
- updateCollisionBox(symbolInstance.iconCollisionFeature, opacityState.icon.placed, hasIconTextFit ? textShift : Point<float>{0.0f, 0.0f});
}
- if (bucket.hasCollisionCircleData()) {
- updateCollisionCircles(symbolInstance.textCollisionFeature, opacityState.text.placed);
- updateCollisionCircles(symbolInstance.iconCollisionFeature, opacityState.icon.placed);
+
+ if (bucket.hasIconCollisionCircleData()) {
+ updateCollisionCircles(symbolInstance.iconCollisionFeature, opacityState.icon.placed, false);
+ }
+ if (bucket.hasTextCollisionCircleData()) {
+ updateCollisionCircles(symbolInstance.textCollisionFeature, opacityState.text.placed, true);
}
}
diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp
index f30606ee42..10c3596390 100644
--- a/test/gl/bucket.test.cpp
+++ b/test/gl/bucket.test.cpp
@@ -125,7 +125,8 @@ TEST(Buckets, SymbolBucket) {
ASSERT_FALSE(bucket.hasIconData());
ASSERT_FALSE(bucket.hasSdfIconData());
ASSERT_FALSE(bucket.hasTextData());
- ASSERT_FALSE(bucket.hasCollisionBoxData());
+ ASSERT_FALSE(bucket.hasIconCollisionBoxData());
+ ASSERT_FALSE(bucket.hasTextCollisionBoxData());
ASSERT_FALSE(bucket.hasData());
ASSERT_FALSE(bucket.needsUpload());