summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
authorzmiao <miao.zhao@mapbox.com>2019-08-30 08:24:03 +0300
committerGitHub <noreply@github.com>2019-08-30 08:24:03 +0300
commit6ef2710e5cfb5ee4258583a20d55320e90faa8a5 (patch)
tree1c840291ea93ec38c2745348678879f10217bf7c /src/mbgl/renderer
parent29b11a503766efb469036b38f010400cea57967e (diff)
downloadqtlocation-mapboxgl-6ef2710e5cfb5ee4258583a20d55320e90faa8a5.tar.gz
[core] fix collisionBox alignment when Icon/text translation is enabled (#15467)
* add initial fix * fix bug for collision circle * refind code structure * fix indentation * update test * refind code structure * Add changelog * Add comment for boolean
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp58
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp34
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp130
3 files changed, 130 insertions, 92 deletions
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp
index a46c25a13b..ff201e9c2c 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.cpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp
@@ -113,37 +113,50 @@ void SymbolBucket::upload(gfx::UploadPass& uploadPass) {
if (hasIconData()) {
updateIconBuffer(icon);
}
-
if (hasSdfIconData()) {
updateIconBuffer(sdfIcon);
}
- if (hasCollisionBoxData()) {
+ const auto updateCollisionBox = [&](CollisionBoxBuffer& collisionBox) {
if (!staticUploaded) {
- collisionBox->indexBuffer = uploadPass.createIndexBuffer(std::move(collisionBox->lines));
- collisionBox->vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox->vertices));
+ collisionBox.indexBuffer = uploadPass.createIndexBuffer(std::move(collisionBox.lines));
+ collisionBox.vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox.vertices));
}
if (!placementChangesUploaded) {
- if (!collisionBox->dynamicVertexBuffer) {
- collisionBox->dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox->dynamicVertices), gfx::BufferUsageType::StreamDraw);
+ if (!collisionBox.dynamicVertexBuffer) {
+ collisionBox.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionBox.dynamicVertices), gfx::BufferUsageType::StreamDraw);
} else {
- uploadPass.updateVertexBuffer(*collisionBox->dynamicVertexBuffer, std::move(collisionBox->dynamicVertices));
+ uploadPass.updateVertexBuffer(*collisionBox.dynamicVertexBuffer, std::move(collisionBox.dynamicVertices));
}
}
+ };
+ if (hasIconCollisionBoxData()) {
+ updateCollisionBox(*iconCollisionBox);
+ }
+
+ if (hasTextCollisionBoxData()) {
+ updateCollisionBox(*textCollisionBox);
}
- if (hasCollisionCircleData()) {
+ const auto updateCollisionCircle = [&](CollisionCircleBuffer& collisionCircle) {
if (!staticUploaded) {
- collisionCircle->indexBuffer = uploadPass.createIndexBuffer(std::move(collisionCircle->triangles));
- collisionCircle->vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle->vertices));
+ collisionCircle.indexBuffer = uploadPass.createIndexBuffer(std::move(collisionCircle.triangles));
+ collisionCircle.vertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle.vertices));
}
if (!placementChangesUploaded) {
- if (!collisionCircle->dynamicVertexBuffer) {
- collisionCircle->dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle->dynamicVertices), gfx::BufferUsageType::StreamDraw);
+ if (!collisionCircle.dynamicVertexBuffer) {
+ collisionCircle.dynamicVertexBuffer = uploadPass.createVertexBuffer(std::move(collisionCircle.dynamicVertices), gfx::BufferUsageType::StreamDraw);
} else {
- uploadPass.updateVertexBuffer(*collisionCircle->dynamicVertexBuffer, std::move(collisionCircle->dynamicVertices));
+ uploadPass.updateVertexBuffer(*collisionCircle.dynamicVertexBuffer, std::move(collisionCircle.dynamicVertices));
}
}
+ };
+ if (hasIconCollisionCircleData()) {
+ updateCollisionCircle(*iconCollisionCircle);
+ }
+
+ if (hasTextCollisionCircleData()) {
+ updateCollisionCircle(*textCollisionCircle);
}
uploaded = true;
@@ -154,7 +167,8 @@ void SymbolBucket::upload(gfx::UploadPass& uploadPass) {
}
bool SymbolBucket::hasData() const {
- return hasTextData() || hasIconData() || hasSdfIconData() || hasCollisionBoxData();
+ return hasTextData() || hasIconData() || hasSdfIconData() || hasIconCollisionBoxData() ||
+ hasTextCollisionBoxData() || hasIconCollisionCircleData() || hasTextCollisionCircleData();
}
bool SymbolBucket::hasTextData() const {
@@ -169,12 +183,20 @@ 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::hasIconCollisionCircleData() const {
+ return iconCollisionCircle && !iconCollisionCircle->segments.empty();
+}
+
+bool SymbolBucket::hasTextCollisionBoxData() const {
+ return textCollisionBox && !textCollisionBox->segments.empty();
}
-bool SymbolBucket::hasCollisionCircleData() const {
- return collisionCircle && !collisionCircle->segments.empty();
+bool SymbolBucket::hasTextCollisionCircleData() const {
+ return textCollisionCircle && !textCollisionCircle->segments.empty();
}
void addPlacedSymbol(gfx::IndexVector<gfx::Triangles>& triangles, const PlacedSymbol& placedSymbol) {
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..06eacc041b 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp
@@ -392,46 +392,11 @@ void RenderSymbolLayer::render(PaintParameters& parameters) {
}
}
- if (bucket.hasCollisionBoxData()) {
- static const style::Properties<>::PossiblyEvaluated properties {};
- static const CollisionBoxProgram::Binders paintAttributeData(properties, 0);
+ const auto drawCollisonData = [&](const bool isText, const bool hasCollisionBox, const bool hasCollisionCircle) {
+ if (!hasCollisionBox && !hasCollisionCircle) return;
- 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)
- }};
- 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()
- );
- }
-
- if (bucket.hasCollisionCircleData()) {
- static const style::Properties<>::PossiblyEvaluated properties {};
+ 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 =
@@ -439,32 +404,69 @@ void RenderSymbolLayer::render(PaintParameters& parameters) {
parameters.pixelsToGLUnits[0] / (pixelRatio * scale),
parameters.pixelsToGLUnits[1] / (pixelRatio * scale)
}};
-
- 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()
- );
- }
+ const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData->layerProperties);
+ const auto& layout = *bucket.layout;
+ const auto values = isText ? textPropertyValues(evaluated, layout): iconPropertyValues(evaluated, layout);
+ const bool needTranslate = values.translate[0] != 0 || values.translate[1] != 0;
+
+ if (hasCollisionBox) {
+ const auto& collisionBox = isText ? bucket.textCollisionBox : bucket.iconCollisionBox;
+ 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((needTranslate
+ ? tile.translatedMatrix(values.translate, values.translateAnchor, parameters.state)
+ : tile.matrix)),
+ uniforms::extrude_scale::Value(extrudeScale),
+ uniforms::camera_to_center_distance::Value(parameters.state.getCameraToCenterDistance())
+ },
+ *collisionBox->vertexBuffer,
+ *collisionBox->dynamicVertexBuffer,
+ *collisionBox->indexBuffer,
+ collisionBox->segments,
+ paintAttributeData,
+ properties,
+ CollisionBoxProgram::TextureBindings{},
+ parameters.state.getZoom(),
+ getID());
+ }
+ if (hasCollisionCircle) {
+ const auto& collisionCircle = isText ? bucket.textCollisionCircle : bucket.iconCollisionCircle;
+ 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((needTranslate
+ ? tile.translatedMatrix(values.translate, values.translateAnchor, parameters.state)
+ : tile.matrix)),
+ uniforms::extrude_scale::Value(extrudeScale),
+ uniforms::overscale_factor::Value(float(tile.getOverscaledTileID().overscaleFactor())),
+ uniforms::camera_to_center_distance::Value(parameters.state.getCameraToCenterDistance())
+ },
+ *collisionCircle->vertexBuffer,
+ *collisionCircle->dynamicVertexBuffer,
+ *collisionCircle->indexBuffer,
+ collisionCircle->segments,
+ paintAttributeData,
+ properties,
+ CollisionCircleProgram::TextureBindings{},
+ parameters.state.getZoom(),
+ getID());
+ }
+ };
+ drawCollisonData(false /*isText*/, bucket.hasIconCollisionBoxData(), bucket.hasIconCollisionCircleData());
+ drawCollisonData(true /*isText*/, bucket.hasTextCollisionBoxData(), bucket.hasTextCollisionCircleData());
}
if (sortFeaturesByKey) {