diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2019-03-04 13:09:51 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2019-03-05 15:20:36 +0100 |
commit | 1d050cb6fd1b0efa68c4b11513d3a0d9fe75899f (patch) | |
tree | cfc37c2030485ae7b0ecf4a56abe9a3c86e0ed19 | |
parent | bc7cfd36bd39883e969d171f59de3b5a6810da38 (diff) | |
download | qtlocation-mapboxgl-1d050cb6fd1b0efa68c4b11513d3a0d9fe75899f.tar.gz |
[core] make vertex descriptors constexpr
-rw-r--r-- | src/mbgl/gfx/attribute.hpp | 138 | ||||
-rw-r--r-- | src/mbgl/gl/attribute.hpp | 7 | ||||
-rw-r--r-- | src/mbgl/programs/collision_box_program.cpp | 2 |
3 files changed, 82 insertions, 65 deletions
diff --git a/src/mbgl/gfx/attribute.hpp b/src/mbgl/gfx/attribute.hpp index 66bbf1ec5e..ec34a69a9a 100644 --- a/src/mbgl/gfx/attribute.hpp +++ b/src/mbgl/gfx/attribute.hpp @@ -4,6 +4,7 @@ #include <mbgl/util/indexed_tuple.hpp> #include <array> +#include <type_traits> #include <cstddef> #define MBGL_DEFINE_ATTRIBUTE(type_, n_, name_) \ @@ -14,6 +15,8 @@ } \ } +#define MBGL_VERTEX_ALIGN __attribute__((aligned(4))) + namespace mbgl { namespace gfx { @@ -25,6 +28,12 @@ public: using Value = std::array<T, N>; }; +struct VertexDescriptor { + const uint8_t size; + const uint8_t count; + const uint8_t offsets[5]; +}; + // Attribute binding requires member offsets. The only standard way to // obtain an offset is the offsetof macro. The offsetof macro has defined // behavior only for standard layout types. That rules out std::tuple and @@ -35,114 +44,123 @@ public: namespace detail { template <class...> -class Vertex; - -template <> -class Vertex<> { -public: - using VertexType = Vertex<>; -}; +struct Vertex; template <class A1> -class Vertex<A1> { -public: +struct Vertex<A1> { + using Type = Vertex<A1>; A1 a1; - - using VertexType = Vertex<A1>; - static const std::size_t attributeOffsets[1]; -}; +} MBGL_VERTEX_ALIGN; template <class A1, class A2> -class Vertex<A1, A2> { -public: +struct Vertex<A1, A2> { + using Type = Vertex<A1, A2>; A1 a1; A2 a2; - - using VertexType = Vertex<A1, A2>; - static const std::size_t attributeOffsets[2]; -}; +} MBGL_VERTEX_ALIGN; template <class A1, class A2, class A3> -class Vertex<A1, A2, A3> { -public: +struct Vertex<A1, A2, A3> { + using Type = Vertex<A1, A2, A3>; A1 a1; A2 a2; A3 a3; - - using VertexType = Vertex<A1, A2, A3>; - static const std::size_t attributeOffsets[3]; -}; +} MBGL_VERTEX_ALIGN; template <class A1, class A2, class A3, class A4> -class Vertex<A1, A2, A3, A4> { -public: +struct Vertex<A1, A2, A3, A4> { + using Type = Vertex<A1, A2, A3, A4>; A1 a1; A2 a2; A3 a3; A4 a4; - - using VertexType = Vertex<A1, A2, A3, A4>; - static const std::size_t attributeOffsets[4]; -}; +} MBGL_VERTEX_ALIGN; template <class A1, class A2, class A3, class A4, class A5> -class Vertex<A1, A2, A3, A4, A5> { -public: +struct Vertex<A1, A2, A3, A4, A5> { + using Type = Vertex<A1, A2, A3, A4, A5>; A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; +} MBGL_VERTEX_ALIGN; - using VertexType = Vertex<A1, A2, A3, A4, A5>; - static const std::size_t attributeOffsets[5]; -}; +template <class> +struct Descriptor; template <class A1> -const std::size_t Vertex<A1>::attributeOffsets[1] = { - offsetof(VertexType, a1) +struct Descriptor<Vertex<A1>> { + using Type = Vertex<A1>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor Data = { sizeof(Type), 1, { + offsetof(Type, a1), + }}; }; template <class A1, class A2> -const std::size_t Vertex<A1, A2>::attributeOffsets[2] = { - offsetof(VertexType, a1), - offsetof(VertexType, a2) +struct Descriptor<Vertex<A1, A2>> { + using Type = Vertex<A1, A2>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor Data = { sizeof(Type), 2, { + offsetof(Type, a1), + offsetof(Type, a2), + }}; }; template <class A1, class A2, class A3> -const std::size_t Vertex<A1, A2, A3>::attributeOffsets[3] = { - offsetof(VertexType, a1), - offsetof(VertexType, a2), - offsetof(VertexType, a3) +struct Descriptor<Vertex<A1, A2, A3>> { + using Type = Vertex<A1, A2, A3>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor Data = { sizeof(Type), 3, { + offsetof(Type, a1), + offsetof(Type, a2), + offsetof(Type, a3), + }}; }; template <class A1, class A2, class A3, class A4> -const std::size_t Vertex<A1, A2, A3, A4>::attributeOffsets[4] = { - offsetof(VertexType, a1), - offsetof(VertexType, a2), - offsetof(VertexType, a3), - offsetof(VertexType, a4) +struct Descriptor<Vertex<A1, A2, A3, A4>> { + using Type = Vertex<A1, A2, A3, A4>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor Data = { sizeof(Type), 4, { + offsetof(Type, a1), + offsetof(Type, a2), + offsetof(Type, a3), + offsetof(Type, a4), + }}; }; template <class A1, class A2, class A3, class A4, class A5> -const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = { - offsetof(VertexType, a1), - offsetof(VertexType, a2), - offsetof(VertexType, a3), - offsetof(VertexType, a4), - offsetof(VertexType, a5) +struct Descriptor<Vertex<A1, A2, A3, A4, A5>> { + using Type = Vertex<A1, A2, A3, A4, A5>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor Data = { sizeof(Type), 5, { + offsetof(Type, a1), + offsetof(Type, a2), + offsetof(Type, a3), + offsetof(Type, a4), + offsetof(Type, a5), + }}; }; template <class... As> -class Vertex<TypeList<As...>> { -public: - using VertexType = Vertex<typename As::Type::Value...>; +struct Vertex<TypeList<As...>> { + using Type = Vertex<typename As::Type::Value...>; }; } // namespace detail template <class A> -using Vertex = typename detail::Vertex<A>::VertexType; +using Vertex = typename detail::Vertex<A>::Type; + +template <class V> +constexpr const VertexDescriptor vertexDescriptor = detail::Descriptor<V>::Data; } // namespace gfx } // namespace mbgl diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index 95a9942381..e03e3ebf89 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -58,14 +58,13 @@ AttributeBinding attributeBinding(const VertexBuffer<Vertex>& buffer, static_assert(std::is_standard_layout<Vertex>::value, "vertex type must use standard layout"); assert(attributeSize >= 1); assert(attributeSize <= 4); - assert(Vertex::attributeOffsets[attributeIndex] <= std::numeric_limits<uint32_t>::max()); - static_assert(sizeof(Vertex) <= std::numeric_limits<uint32_t>::max(), "vertex too large"); + assert(gfx::vertexDescriptor<Vertex>.count > attributeIndex); return AttributeBinding { DataTypeOf<typename AttributeType::ValueType>::value, static_cast<uint8_t>(attributeSize), - static_cast<uint32_t>(Vertex::attributeOffsets[attributeIndex]), + static_cast<uint32_t>(gfx::vertexDescriptor<Vertex>.offsets[attributeIndex]), buffer.buffer, - static_cast<uint32_t>(sizeof(Vertex)), + static_cast<uint32_t>(gfx::vertexDescriptor<Vertex>.size), 0, }; } diff --git a/src/mbgl/programs/collision_box_program.cpp b/src/mbgl/programs/collision_box_program.cpp index 57107db75d..869f4be61f 100644 --- a/src/mbgl/programs/collision_box_program.cpp +++ b/src/mbgl/programs/collision_box_program.cpp @@ -2,6 +2,6 @@ namespace mbgl { -static_assert(sizeof(CollisionBoxProgram::LayoutVertex) == 14, "expected CollisionBoxVertex size"); +static_assert(sizeof(CollisionBoxProgram::LayoutVertex) == 16, "expected CollisionBoxVertex size"); } // namespace mbgl |