summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2019-03-04 13:09:51 +0100
committerKonstantin Käfer <mail@kkaefer.com>2019-03-05 15:20:36 +0100
commit1d050cb6fd1b0efa68c4b11513d3a0d9fe75899f (patch)
treecfc37c2030485ae7b0ecf4a56abe9a3c86e0ed19
parentbc7cfd36bd39883e969d171f59de3b5a6810da38 (diff)
downloadqtlocation-mapboxgl-1d050cb6fd1b0efa68c4b11513d3a0d9fe75899f.tar.gz
[core] make vertex descriptors constexpr
-rw-r--r--src/mbgl/gfx/attribute.hpp138
-rw-r--r--src/mbgl/gl/attribute.hpp7
-rw-r--r--src/mbgl/programs/collision_box_program.cpp2
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