From 1200046f0c54ce50c91140731213a3949dff2601 Mon Sep 17 00:00:00 2001 From: Stefan Karschti Date: Wed, 15 Nov 2023 17:33:41 +0200 Subject: [PATCH] Collision drawables shared buffers (#1859) --- include/mbgl/gfx/vertex_attribute.hpp | 9 +- include/mbgl/gl/vertex_attribute_gl.hpp | 2 +- include/mbgl/mtl/vertex_attribute.hpp | 4 +- include/mbgl/shaders/mtl/collision_box.hpp | 2 +- include/mbgl/shaders/mtl/collision_circle.hpp | 2 +- src/mbgl/gfx/vertex_attribute.cpp | 65 +++++++++ src/mbgl/mtl/drawable_builder.cpp | 1 - src/mbgl/mtl/vertex_attribute.cpp | 82 ++--------- src/mbgl/programs/attributes.hpp | 2 +- src/mbgl/programs/collision_box_program.hpp | 4 +- .../renderer/layers/render_symbol_layer.cpp | 132 ++++++------------ src/mbgl/shaders/mtl/collision_box.cpp | 2 +- src/mbgl/shaders/mtl/collision_circle.cpp | 4 +- 13 files changed, 134 insertions(+), 177 deletions(-) diff --git a/include/mbgl/gfx/vertex_attribute.hpp b/include/mbgl/gfx/vertex_attribute.hpp index 5c676844a0f..0c622bfd6e4 100644 --- a/include/mbgl/gfx/vertex_attribute.hpp +++ b/include/mbgl/gfx/vertex_attribute.hpp @@ -81,6 +81,11 @@ class VertexAttribute { stride(stride_), dataType(dataType_), items(count_) {} + VertexAttribute(int index_, AttributeDataType dataType_, std::size_t count_) + : index(index_), + stride(getStrideOf(dataType_)), + dataType(dataType_), + items(count_) {} VertexAttribute(const VertexAttribute& other) : index(other.index), stride(other.stride), @@ -105,6 +110,8 @@ class VertexAttribute { public: virtual ~VertexAttribute() = default; + static std::size_t getStrideOf(gfx::AttributeDataType); + /// @brief Get the index of the vertex attribute int getIndex() const { return index; } @@ -455,7 +462,7 @@ class VertexAttributeArray { const UniqueVertexAttribute& add(const StringIdentity id, std::unique_ptr&&); virtual UniqueVertexAttribute create(int index, AttributeDataType dataType, std::size_t count) const { - return std::make_unique(index, dataType, count, count); + return std::make_unique(index, dataType, count); } virtual UniqueVertexAttribute copy(const gfx::VertexAttribute& attr) const { diff --git a/include/mbgl/gl/vertex_attribute_gl.hpp b/include/mbgl/gl/vertex_attribute_gl.hpp index e0b9b2a008e..b1814a18608 100644 --- a/include/mbgl/gl/vertex_attribute_gl.hpp +++ b/include/mbgl/gl/vertex_attribute_gl.hpp @@ -19,7 +19,7 @@ class VertexAttributeGL final : public gfx::VertexAttribute { private: friend VertexAttributeArrayGL; VertexAttributeGL(int index_, gfx::AttributeDataType dataType_, std::size_t count_) - : VertexAttribute(index_, dataType_, count_, /*stride_=*/0) {} + : VertexAttribute(index_, dataType_, count_) {} VertexAttributeGL(const VertexAttributeGL& other) : VertexAttribute(other), glType(other.glType) {} diff --git a/include/mbgl/mtl/vertex_attribute.hpp b/include/mbgl/mtl/vertex_attribute.hpp index 84eb12fea1a..0658b8253f7 100644 --- a/include/mbgl/mtl/vertex_attribute.hpp +++ b/include/mbgl/mtl/vertex_attribute.hpp @@ -17,7 +17,7 @@ class VertexAttribute final : public gfx::VertexAttribute { private: friend VertexAttributeArray; VertexAttribute(int index_, gfx::AttributeDataType dataType_, std::size_t count_) - : gfx::VertexAttribute(index_, dataType_, count_, /*stride_=*/0) {} + : gfx::VertexAttribute(index_, dataType_, count_) {} VertexAttribute(const VertexAttribute& other) : gfx::VertexAttribute(other) {} VertexAttribute(VertexAttribute&& other) @@ -32,8 +32,6 @@ class VertexAttribute final : public gfx::VertexAttribute { static const gfx::UniqueVertexBufferResource& getBuffer(gfx::VertexAttribute&, UploadPass&, const gfx::BufferUsageType); - - static std::size_t getStrideOf(gfx::AttributeDataType); }; /// Stores a collection of vertex attributes by name diff --git a/include/mbgl/shaders/mtl/collision_box.hpp b/include/mbgl/shaders/mtl/collision_box.hpp index a26249fcd86..6f87dfce96b 100644 --- a/include/mbgl/shaders/mtl/collision_box.hpp +++ b/include/mbgl/shaders/mtl/collision_box.hpp @@ -24,7 +24,7 @@ struct VertexStage { short2 pos [[attribute(0)]]; short2 anchor_pos [[attribute(1)]]; short2 extrude [[attribute(2)]]; - uchar2 placed [[attribute(3)]]; + ushort2 placed [[attribute(3)]]; float2 shift [[attribute(4)]]; }; diff --git a/include/mbgl/shaders/mtl/collision_circle.hpp b/include/mbgl/shaders/mtl/collision_circle.hpp index 39822a7bbcc..52a9b2e24f1 100644 --- a/include/mbgl/shaders/mtl/collision_circle.hpp +++ b/include/mbgl/shaders/mtl/collision_circle.hpp @@ -24,7 +24,7 @@ struct VertexStage { short2 pos [[attribute(0)]]; short2 anchor_pos [[attribute(1)]]; short2 extrude [[attribute(2)]]; - uchar2 placed [[attribute(3)]]; + ushort2 placed [[attribute(3)]]; }; struct FragmentStage { diff --git a/src/mbgl/gfx/vertex_attribute.cpp b/src/mbgl/gfx/vertex_attribute.cpp index b1e6c3c5dac..fcde4fa6be5 100644 --- a/src/mbgl/gfx/vertex_attribute.cpp +++ b/src/mbgl/gfx/vertex_attribute.cpp @@ -13,6 +13,71 @@ namespace { const UniqueVertexAttribute nullref; } // namespace +std::size_t VertexAttribute::getStrideOf(gfx::AttributeDataType type) { + switch (type) { + case gfx::AttributeDataType::Byte: + return 1; + case gfx::AttributeDataType::Byte2: + return 2; + case gfx::AttributeDataType::Byte3: + return 3; + case gfx::AttributeDataType::Byte4: + return 4; + case gfx::AttributeDataType::UByte: + return 1; + case gfx::AttributeDataType::UByte2: + return 2; + case gfx::AttributeDataType::UByte3: + return 3; + case gfx::AttributeDataType::UByte4: + return 4; + case gfx::AttributeDataType::Short: + return 2; + case gfx::AttributeDataType::Short2: + return 4; + case gfx::AttributeDataType::Short3: + return 6; + case gfx::AttributeDataType::Short4: + return 8; + case gfx::AttributeDataType::UShort: + return 2; + case gfx::AttributeDataType::UShort2: + return 4; + case gfx::AttributeDataType::UShort3: + return 6; + case gfx::AttributeDataType::UShort4: + return 8; + case gfx::AttributeDataType::UShort8: + return 16; + case gfx::AttributeDataType::Int: + return 4; + case gfx::AttributeDataType::Int2: + return 8; + case gfx::AttributeDataType::Int3: + return 12; + case gfx::AttributeDataType::Int4: + return 16; + case gfx::AttributeDataType::UInt: + return 4; + case gfx::AttributeDataType::UInt2: + return 8; + case gfx::AttributeDataType::UInt3: + return 12; + case gfx::AttributeDataType::UInt4: + return 16; + case gfx::AttributeDataType::Float: + return 4; + case gfx::AttributeDataType::Float2: + return 8; + case gfx::AttributeDataType::Float3: + return 12; + case gfx::AttributeDataType::Float4: + return 16; + default: + return 0; + } +} + std::size_t VertexAttribute::getCount() const { return sharedRawData ? sharedRawData->getRawCount() : items.size(); } diff --git a/src/mbgl/mtl/drawable_builder.cpp b/src/mbgl/mtl/drawable_builder.cpp index 741db0a78f7..00d52f55b43 100644 --- a/src/mbgl/mtl/drawable_builder.cpp +++ b/src/mbgl/mtl/drawable_builder.cpp @@ -27,7 +27,6 @@ void DrawableBuilder::init() { if (impl->rawVerticesCount) { auto raw = impl->rawVertices; drawable.setVertices(std::move(raw), impl->rawVerticesCount, impl->rawVerticesType); - impl->rawVerticesCount = 0; } else { const auto& verts = impl->vertices.vector(); constexpr auto vertSize = sizeof(std::remove_reference::type::value_type); diff --git a/src/mbgl/mtl/vertex_attribute.cpp b/src/mbgl/mtl/vertex_attribute.cpp index bc27acec3c9..d904393cb98 100644 --- a/src/mbgl/mtl/vertex_attribute.cpp +++ b/src/mbgl/mtl/vertex_attribute.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -11,72 +12,6 @@ namespace mbgl { namespace mtl { -std::size_t VertexAttribute::getStrideOf(gfx::AttributeDataType type) { - switch (type) { - case gfx::AttributeDataType::Byte: - return 1; - case gfx::AttributeDataType::Byte2: - return 2; - case gfx::AttributeDataType::Byte3: - return 3; - case gfx::AttributeDataType::Byte4: - return 4; - case gfx::AttributeDataType::UByte: - return 1; - case gfx::AttributeDataType::UByte2: - return 2; - case gfx::AttributeDataType::UByte3: - return 3; - case gfx::AttributeDataType::UByte4: - return 4; - case gfx::AttributeDataType::Short: - return 2; - case gfx::AttributeDataType::Short2: - return 4; - case gfx::AttributeDataType::Short3: - return 6; - case gfx::AttributeDataType::Short4: - return 8; - case gfx::AttributeDataType::UShort: - return 2; - case gfx::AttributeDataType::UShort2: - return 4; - case gfx::AttributeDataType::UShort3: - return 6; - case gfx::AttributeDataType::UShort4: - return 8; - case gfx::AttributeDataType::UShort8: - return 16; - case gfx::AttributeDataType::Int: - return 4; - case gfx::AttributeDataType::Int2: - return 8; - case gfx::AttributeDataType::Int3: - return 12; - case gfx::AttributeDataType::Int4: - return 16; - case gfx::AttributeDataType::UInt: - return 4; - case gfx::AttributeDataType::UInt2: - return 8; - case gfx::AttributeDataType::UInt3: - return 12; - case gfx::AttributeDataType::UInt4: - return 16; - case gfx::AttributeDataType::Float: - return 4; - case gfx::AttributeDataType::Float2: - return 8; - case gfx::AttributeDataType::Float3: - return 12; - case gfx::AttributeDataType::Float4: - return 16; - default: - assert(false); - return 0; - } -} - const gfx::UniqueVertexBufferResource& VertexAttribute::getBuffer(gfx::VertexAttribute& attrib_, UploadPass& uploadPass, const gfx::BufferUsageType usage) { @@ -84,14 +19,15 @@ const gfx::UniqueVertexBufferResource& VertexAttribute::getBuffer(gfx::VertexAtt auto& attrib = static_cast(attrib_); if (attrib.sharedRawData) { return uploadPass.getBuffer(attrib.sharedRawData, usage); - } else if (!attrib.rawData.empty()) { - auto buffer = uploadPass.createVertexBufferResource( - attrib.rawData.data(), attrib.rawData.size(), usage, false); - attrib.setBuffer(std::move(buffer)); - attrib.setRawData({}); } else { - // TODO: vertex building - assert(false); + if (!attrib.rawData.empty()) { + auto buffer = uploadPass.createVertexBufferResource( + attrib.rawData.data(), attrib.rawData.size(), usage, false); + attrib.setBuffer(std::move(buffer)); + attrib.setRawData({}); + } else { + assert(false); + } } } return attrib_.getBuffer(); diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index b6df1c145d6..df8f7cef6c8 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -18,7 +18,7 @@ MBGL_DEFINE_ATTRIBUTE(int16_t, 2, anchor_pos); MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, texture_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 4, normal_ed); MBGL_DEFINE_ATTRIBUTE(float, 1, fade_opacity); -MBGL_DEFINE_ATTRIBUTE(uint8_t, 2, placed); +MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, placed); MBGL_DEFINE_ATTRIBUTE(uint16_t, 3, size); MBGL_DEFINE_ATTRIBUTE(float, 1, offset); MBGL_DEFINE_ATTRIBUTE(float, 2, shift); diff --git a/src/mbgl/programs/collision_box_program.hpp b/src/mbgl/programs/collision_box_program.hpp index cb402a01e17..2a963546723 100644 --- a/src/mbgl/programs/collision_box_program.hpp +++ b/src/mbgl/programs/collision_box_program.hpp @@ -35,7 +35,7 @@ class CollisionBoxProgram final } static gfx::Vertex dynamicVertex(bool placed, bool notUsed, Point shift) { - return {{{static_cast(placed), static_cast(notUsed)}}, {{shift.x, shift.y}}}; + return {{{static_cast(placed), static_cast(notUsed)}}, {{shift.x, shift.y}}}; } template @@ -165,6 +165,4 @@ class CollisionCircleProgram final } }; -using CollisionBoxVertex = CollisionBoxProgram::LayoutVertex; - } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 377b48a1b23..cd365fd559a 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -878,80 +878,47 @@ const StringIdentity idCollisionExtrudeAttribName = stringIndexer().get("a_extru const StringIdentity idCollisionPlacedAttribName = stringIndexer().get("a_placed"); const StringIdentity idCollisionShiftAttribName = stringIndexer().get("a_shift"); -gfx::VertexAttributeArray getCollisionVertexAttributes(const SymbolBucket::CollisionBuffer& buffer, bool staticCopy) { +gfx::VertexAttributeArray getCollisionVertexAttributes(const SymbolBucket::CollisionBuffer& buffer) { gfx::VertexAttributeArray vertexAttrs; + using LayoutVertex = gfx::Vertex; - if (staticCopy) { - if (auto& attr = vertexAttrs.getOrAdd(idCollisionPosAttribName)) { - std::size_t index{0}; - for (auto& v : buffer.vertices().vector()) { - attr->set(index++, {v.a1[0], v.a1[1]}); - } - } - if (auto& attr = vertexAttrs.getOrAdd(idCollisionAnchorPosAttribName)) { - std::size_t index{0}; - for (auto& v : buffer.vertices().vector()) { - attr->set(index++, {v.a2[0], v.a2[1]}); - } - } - if (auto& attr = vertexAttrs.getOrAdd(idCollisionExtrudeAttribName)) { - std::size_t index{0}; - for (auto& v : buffer.vertices().vector()) { - attr->set(index++, {v.a3[0], v.a3[1]}); - } - } - - if (auto& attr = vertexAttrs.getOrAdd(idCollisionPlacedAttribName)) { - std::size_t index{0}; - for (auto& v : buffer.dynamicVertices().vector()) { - attr->set(index++, {v.a1[0], v.a1[1]}); - } - } - if (auto& attr = vertexAttrs.getOrAdd(idCollisionShiftAttribName)) { - std::size_t index{0}; - for (auto& v : buffer.dynamicVertices().vector()) { - attr->set(index++, {v.a2[0], v.a2[1]}); - } - } - } else { - if (const auto& attr = vertexAttrs.getOrAdd(idCollisionPosAttribName)) { - attr->setSharedRawData(buffer.sharedVertices, - offsetof(CollisionBoxVertex, a1), - /*vertexOffset=*/0, - sizeof(CollisionBoxVertex), - gfx::AttributeDataType::Short2); - } - if (const auto& attr = vertexAttrs.getOrAdd(idCollisionAnchorPosAttribName)) { - attr->setSharedRawData(buffer.sharedVertices, - offsetof(CollisionBoxVertex, a2), - /*vertexOffset=*/0, - sizeof(CollisionBoxVertex), - gfx::AttributeDataType::Short2); - } - if (const auto& attr = vertexAttrs.getOrAdd(idCollisionExtrudeAttribName)) { - attr->setSharedRawData(buffer.sharedVertices, - offsetof(CollisionBoxVertex, a3), - /*vertexOffset=*/0, - sizeof(CollisionBoxVertex), - gfx::AttributeDataType::Short2); - } + if (const auto& attr = vertexAttrs.getOrAdd(idCollisionPosAttribName)) { + attr->setSharedRawData(buffer.sharedVertices, + offsetof(LayoutVertex, a1), + /*vertexOffset=*/0, + sizeof(LayoutVertex), + gfx::AttributeDataType::Short2); + } + if (const auto& attr = vertexAttrs.getOrAdd(idCollisionAnchorPosAttribName)) { + attr->setSharedRawData(buffer.sharedVertices, + offsetof(LayoutVertex, a2), + /*vertexOffset=*/0, + sizeof(LayoutVertex), + gfx::AttributeDataType::Short2); + } + if (const auto& attr = vertexAttrs.getOrAdd(idCollisionExtrudeAttribName)) { + attr->setSharedRawData(buffer.sharedVertices, + offsetof(LayoutVertex, a3), + /*vertexOffset=*/0, + sizeof(LayoutVertex), + gfx::AttributeDataType::Short2); + } - using DynamicVertex = gfx::Vertex; + using DynamicVertex = gfx::Vertex; - if (const auto& attr = vertexAttrs.getOrAdd(idCollisionPlacedAttribName)) { - attr->setSharedRawData(buffer.sharedDynamicVertices, - offsetof(DynamicVertex, a1), - /*vertexOffset=*/0, - sizeof(DynamicVertex), - gfx::AttributeDataType::UByte2); - } - if (const auto& attr = vertexAttrs.getOrAdd(idCollisionShiftAttribName)) { - attr->setSharedRawData(buffer.sharedDynamicVertices, - offsetof(DynamicVertex, a2), - /*vertexOffset=*/0, - sizeof(DynamicVertex), - gfx::AttributeDataType::Float2); - } + if (const auto& attr = vertexAttrs.getOrAdd(idCollisionPlacedAttribName)) { + attr->setSharedRawData(buffer.sharedDynamicVertices, + offsetof(DynamicVertex, a1), + /*vertexOffset=*/0, + sizeof(DynamicVertex), + gfx::AttributeDataType::UShort2); + } + if (const auto& attr = vertexAttrs.getOrAdd(idCollisionShiftAttribName)) { + attr->setSharedRawData(buffer.sharedDynamicVertices, + offsetof(DynamicVertex, a2), + /*vertexOffset=*/0, + sizeof(DynamicVertex), + gfx::AttributeDataType::Float2); } return vertexAttrs; @@ -1131,21 +1098,10 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, const auto values = isText ? textPropertyValues(evaluated, layout) : iconPropertyValues(evaluated, layout); const std::string suffix = isText ? "text/" : "icon/"; - auto addVertices = [&collisionBuilder](const auto& vertices, bool staticCopy) { - if (staticCopy) { - std::vector> verts(vertices.size()); - std::transform( - vertices.begin(), vertices.end(), verts.begin(), [](const auto& v) -> std::array { - return v.a1; - }); - collisionBuilder->addVertices(verts, 0, verts.size()); - } else { - collisionBuilder->setRawVertices({}, vertices.size(), gfx::AttributeDataType::Short2); - } + auto addVertices = [&collisionBuilder](const auto& vertices) { + collisionBuilder->setRawVertices({}, vertices.size(), gfx::AttributeDataType::Short2); }; - constexpr bool staticVertexAndAttributes = true; - if (hasCollisionBox) { const auto& collisionBox = isText ? bucket.textCollisionBox : bucket.iconCollisionBox; if (const auto shader = std::static_pointer_cast( @@ -1153,9 +1109,8 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, context, {}, stringIndexer().get(idCollisionPosAttribName)))) { collisionBuilder->setDrawableName(layerCollisionPrefix + suffix + "box"); collisionBuilder->setShader(shader); - addVertices(collisionBox->vertices().vector(), staticVertexAndAttributes); - collisionBuilder->setVertexAttributes( - getCollisionVertexAttributes(*collisionBox, staticVertexAndAttributes)); + addVertices(collisionBox->vertices().vector()); + collisionBuilder->setVertexAttributes(getCollisionVertexAttributes(*collisionBox)); collisionBuilder->setSegments(gfx::Lines(1.0f), collisionBox->sharedLines, collisionBox->segments.data(), @@ -1171,9 +1126,8 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, context, {}, stringIndexer().get(idCollisionPosAttribName)))) { collisionBuilder->setDrawableName(layerCollisionPrefix + suffix + "circle"); collisionBuilder->setShader(shader); - addVertices(collisionCircle->vertices().vector(), staticVertexAndAttributes); - collisionBuilder->setVertexAttributes( - getCollisionVertexAttributes(*collisionCircle, staticVertexAndAttributes)); + addVertices(collisionCircle->vertices().vector()); + collisionBuilder->setVertexAttributes(getCollisionVertexAttributes(*collisionCircle)); collisionBuilder->setSegments(gfx::Triangles(), collisionCircle->sharedTriangles, collisionCircle->segments.data(), diff --git a/src/mbgl/shaders/mtl/collision_box.cpp b/src/mbgl/shaders/mtl/collision_box.cpp index 66cbbef9ae8..dfc1a034298 100644 --- a/src/mbgl/shaders/mtl/collision_box.cpp +++ b/src/mbgl/shaders/mtl/collision_box.cpp @@ -7,7 +7,7 @@ const std::array ShaderSource ShaderSource::uniforms = { diff --git a/src/mbgl/shaders/mtl/collision_circle.cpp b/src/mbgl/shaders/mtl/collision_circle.cpp index 9eb6934abd8..5d43ffeb691 100644 --- a/src/mbgl/shaders/mtl/collision_circle.cpp +++ b/src/mbgl/shaders/mtl/collision_circle.cpp @@ -8,11 +8,11 @@ const std::array ShaderSource ShaderSource::uniforms = { - UniformBlockInfo{5, true, true, sizeof(CollisionUBO), "CollisionCircleUBO"}, + UniformBlockInfo{4, true, true, sizeof(CollisionUBO), "CollisionCircleUBO"}, }; const std::array ShaderSource::textures = {};