diff options
author | zmiao <zmiao.jamie@gmail.com> | 2019-08-16 12:29:06 +0300 |
---|---|---|
committer | zmiao <zmiao.jamie@gmail.com> | 2019-08-28 13:51:50 +0300 |
commit | 066304d83cf86c8a58c2d802a4fdc7740ad0afb4 (patch) | |
tree | 764502b7d43943b20ee2d852def9ebe56d558c6f | |
parent | 309f566800502f3314bc527c68ba6f41917d500e (diff) | |
download | qtlocation-mapboxgl-066304d83cf86c8a58c2d802a4fdc7740ad0afb4.tar.gz |
add initial fix
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 64 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.cpp | 90 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.hpp | 34 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.cpp | 151 | ||||
-rw-r--r-- | src/mbgl/style/layers/symbol_layer.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/text/placement.cpp | 71 | ||||
-rw-r--r-- | test/gl/bucket.test.cpp | 3 |
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()); |