summaryrefslogtreecommitdiff
path: root/src/mbgl/gfx
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2019-03-15 20:31:12 +0100
committerGitHub <noreply@github.com>2019-03-15 20:31:12 +0100
commitc8cfdb1ced822711e772dfcc8f708b1a7a68b5fc (patch)
treebf511253e25459cafc91a5f3bea2f5c773677162 /src/mbgl/gfx
parent62695c56956add5560933137a479f29f2d3a091b (diff)
downloadqtlocation-mapboxgl-c8cfdb1ced822711e772dfcc8f708b1a7a68b5fc.tar.gz
Merge pull request #14126 from mapbox/gfx-refactor-4
Graphics refactor #4
Diffstat (limited to 'src/mbgl/gfx')
-rw-r--r--src/mbgl/gfx/attribute.cpp21
-rw-r--r--src/mbgl/gfx/attribute.hpp123
-rw-r--r--src/mbgl/gfx/context.hpp26
-rw-r--r--src/mbgl/gfx/context_impl.hpp23
-rw-r--r--src/mbgl/gfx/draw_mode.hpp89
-rw-r--r--src/mbgl/gfx/draw_scope.hpp21
-rw-r--r--src/mbgl/gfx/index_vector.hpp3
-rw-r--r--src/mbgl/gfx/primitives.hpp24
-rw-r--r--src/mbgl/gfx/program.hpp53
-rw-r--r--src/mbgl/gfx/texture.hpp16
-rw-r--r--src/mbgl/gfx/types.hpp10
-rw-r--r--src/mbgl/gfx/uniform.hpp15
12 files changed, 310 insertions, 114 deletions
diff --git a/src/mbgl/gfx/attribute.cpp b/src/mbgl/gfx/attribute.cpp
new file mode 100644
index 0000000000..ed5d4032f4
--- /dev/null
+++ b/src/mbgl/gfx/attribute.cpp
@@ -0,0 +1,21 @@
+#include <mbgl/gfx/attribute.hpp>
+
+#include <limits>
+#include <cassert>
+
+namespace mbgl {
+namespace gfx {
+
+optional<AttributeBinding> offsetAttributeBinding(const optional<AttributeBinding>& binding, std::size_t vertexOffset) {
+ assert(vertexOffset <= std::numeric_limits<uint32_t>::max());
+ if (binding) {
+ AttributeBinding result = *binding;
+ result.vertexOffset = static_cast<uint32_t>(vertexOffset);
+ return result;
+ } else {
+ return binding;
+ }
+}
+
+} // namespace gfx
+} // namespace mbgl
diff --git a/src/mbgl/gfx/attribute.hpp b/src/mbgl/gfx/attribute.hpp
index 0dce6b2a06..4f44d68d7b 100644
--- a/src/mbgl/gfx/attribute.hpp
+++ b/src/mbgl/gfx/attribute.hpp
@@ -1,8 +1,11 @@
#pragma once
#include <mbgl/gfx/types.hpp>
+#include <mbgl/gfx/vertex_buffer.hpp>
#include <mbgl/util/type_list.hpp>
#include <mbgl/util/indexed_tuple.hpp>
+#include <mbgl/util/ignore.hpp>
+#include <mbgl/util/optional.hpp>
#include <array>
#include <type_traits>
@@ -79,6 +82,21 @@ struct VertexDescriptor {
AttributeDescriptor attributes[5];
};
+class AttributeBinding {
+public:
+ AttributeDescriptor attribute;
+ uint8_t vertexStride;
+ const VertexBufferResource* vertexBufferResource;
+ uint32_t vertexOffset;
+
+ friend bool operator==(const AttributeBinding& lhs, const AttributeBinding& rhs) {
+ return lhs.attribute == rhs.attribute &&
+ lhs.vertexStride == rhs.vertexStride &&
+ lhs.vertexBufferResource == rhs.vertexBufferResource &&
+ lhs.vertexOffset == rhs.vertexOffset;
+ }
+};
+
// 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
@@ -89,32 +107,32 @@ struct VertexDescriptor {
namespace detail {
template <class...>
-struct Vertex;
+struct VertexType;
template <class A1>
-struct Vertex<A1> {
- using Type = Vertex<A1>;
+struct VertexType<A1> {
+ using Type = VertexType<A1>;
typename A1::Value a1;
} MBGL_VERTEX_ALIGN;
template <class A1, class A2>
-struct Vertex<A1, A2> {
- using Type = Vertex<A1, A2>;
+struct VertexType<A1, A2> {
+ using Type = VertexType<A1, A2>;
typename A1::Value a1;
typename A2::Value a2;
} MBGL_VERTEX_ALIGN;
template <class A1, class A2, class A3>
-struct Vertex<A1, A2, A3> {
- using Type = Vertex<A1, A2, A3>;
+struct VertexType<A1, A2, A3> {
+ using Type = VertexType<A1, A2, A3>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
} MBGL_VERTEX_ALIGN;
template <class A1, class A2, class A3, class A4>
-struct Vertex<A1, A2, A3, A4> {
- using Type = Vertex<A1, A2, A3, A4>;
+struct VertexType<A1, A2, A3, A4> {
+ using Type = VertexType<A1, A2, A3, A4>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
@@ -122,8 +140,8 @@ struct Vertex<A1, A2, A3, A4> {
} MBGL_VERTEX_ALIGN;
template <class A1, class A2, class A3, class A4, class A5>
-struct Vertex<A1, A2, A3, A4, A5> {
- using Type = Vertex<A1, A2, A3, A4, A5>;
+struct VertexType<A1, A2, A3, A4, A5> {
+ using Type = VertexType<A1, A2, A3, A4, A5>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
@@ -135,8 +153,8 @@ template <class>
struct Descriptor;
template <class A1>
-struct Descriptor<Vertex<A1>> {
- using Type = Vertex<A1>;
+struct Descriptor<VertexType<A1>> {
+ using Type = VertexType<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, {
@@ -145,11 +163,11 @@ struct Descriptor<Vertex<A1>> {
};
template <class A1>
-constexpr const VertexDescriptor Descriptor<Vertex<A1>>::data;
+constexpr const VertexDescriptor Descriptor<VertexType<A1>>::data;
template <class A1, class A2>
-struct Descriptor<Vertex<A1, A2>> {
- using Type = Vertex<A1, A2>;
+struct Descriptor<VertexType<A1, A2>> {
+ using Type = VertexType<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, {
@@ -159,11 +177,11 @@ struct Descriptor<Vertex<A1, A2>> {
};
template <class A1, class A2>
-constexpr const VertexDescriptor Descriptor<Vertex<A1, A2>>::data;
+constexpr const VertexDescriptor Descriptor<VertexType<A1, A2>>::data;
template <class A1, class A2, class A3>
-struct Descriptor<Vertex<A1, A2, A3>> {
- using Type = Vertex<A1, A2, A3>;
+struct Descriptor<VertexType<A1, A2, A3>> {
+ using Type = VertexType<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, {
@@ -174,11 +192,11 @@ struct Descriptor<Vertex<A1, A2, A3>> {
};
template <class A1, class A2, class A3>
-constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3>>::data;
+constexpr const VertexDescriptor Descriptor<VertexType<A1, A2, A3>>::data;
template <class A1, class A2, class A3, class A4>
-struct Descriptor<Vertex<A1, A2, A3, A4>> {
- using Type = Vertex<A1, A2, A3, A4>;
+struct Descriptor<VertexType<A1, A2, A3, A4>> {
+ using Type = VertexType<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, {
@@ -190,11 +208,11 @@ struct Descriptor<Vertex<A1, A2, A3, A4>> {
};
template <class A1, class A2, class A3, class A4>
-constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3, A4>>::data;
+constexpr const VertexDescriptor Descriptor<VertexType<A1, A2, A3, A4>>::data;
template <class A1, class A2, class A3, class A4, class A5>
-struct Descriptor<Vertex<A1, A2, A3, A4, A5>> {
- using Type = Vertex<A1, A2, A3, A4, A5>;
+struct Descriptor<VertexType<A1, A2, A3, A4, A5>> {
+ using Type = VertexType<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, {
@@ -207,11 +225,14 @@ struct Descriptor<Vertex<A1, A2, A3, A4, A5>> {
};
template <class A1, class A2, class A3, class A4, class A5>
-constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3, A4, A5>>::data;
+constexpr const VertexDescriptor Descriptor<VertexType<A1, A2, A3, A4, A5>>::data;
+
+template <class>
+struct Vertex;
template <class... As>
struct Vertex<TypeList<As...>> {
- using Type = Vertex<typename As::Type...>;
+ using Type = VertexType<typename As::Type...>;
};
} // namespace detail
@@ -219,8 +240,52 @@ struct Vertex<TypeList<As...>> {
template <class A>
using Vertex = typename detail::Vertex<A>::Type;
-template <class V>
-using VertexDescriptorOf = detail::Descriptor<V>;
+template <class T>
+using VertexType = typename detail::VertexType<T>;
+
+template <size_t I = 0, class... As>
+AttributeBinding attributeBinding(const VertexBuffer<detail::VertexType<As...>>& buffer) {
+ using Descriptor = detail::Descriptor<detail::VertexType<As...>>;
+ static_assert(I < Descriptor::data.count, "attribute index must be in range");
+ return {
+ Descriptor::data.attributes[I],
+ Descriptor::data.stride,
+ buffer.resource.get(),
+ 0,
+ };
+}
+
+optional<gfx::AttributeBinding> offsetAttributeBinding(const optional<gfx::AttributeBinding>& binding, std::size_t vertexOffset);
+
+template <class>
+class AttributeBindings;
+
+template <class... As>
+class AttributeBindings<TypeList<As...>> final
+ : public IndexedTuple<TypeList<As...>,
+ TypeList<ExpandToType<As, optional<AttributeBinding>>...>> {
+ using Base = IndexedTuple<TypeList<As...>,
+ TypeList<ExpandToType<As, optional<AttributeBinding>>...>>;
+
+public:
+ AttributeBindings(const VertexBuffer<Vertex<TypeList<As...>>>& buffer)
+ : Base{ attributeBinding<TypeIndex<As, As...>::value>(buffer)... } {
+ }
+
+ template <class... Args>
+ AttributeBindings(Args&&... args) : Base(std::forward<Args>(args)...) {
+ }
+
+ AttributeBindings offset(const std::size_t vertexOffset) const {
+ return { offsetAttributeBinding(Base::template get<As>(), vertexOffset)... };
+ }
+
+ uint32_t activeCount() const {
+ uint32_t result = 0;
+ util::ignore({ ((result += bool(Base::template get<As>())), 0)... });
+ return result;
+ }
+};
} // namespace gfx
} // namespace mbgl
diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp
index 5ec73b8a41..90b62c94a4 100644
--- a/src/mbgl/gfx/context.hpp
+++ b/src/mbgl/gfx/context.hpp
@@ -5,14 +5,22 @@
#include <mbgl/gfx/index_vector.hpp>
#include <mbgl/gfx/index_buffer.hpp>
#include <mbgl/gfx/texture.hpp>
+#include <mbgl/gfx/draw_scope.hpp>
+#include <mbgl/gfx/program.hpp>
#include <mbgl/gfx/types.hpp>
namespace mbgl {
+
+class ProgramParameters;
+
namespace gfx {
class Context {
protected:
- Context() = default;
+ Context(ContextType type_) : backend(type_) {
+ }
+
+ const ContextType backend;
public:
Context(Context&&) = delete;
@@ -89,6 +97,22 @@ protected:
Size, const void* data, TexturePixelType, TextureChannelDataType) = 0;
virtual void updateTextureResource(const TextureResource&, Size, const void* data,
TexturePixelType, TextureChannelDataType) = 0;
+
+public:
+ DrawScope createDrawScope() {
+ return { createDrawScopeResource() };
+ }
+
+protected:
+ virtual std::unique_ptr<DrawScopeResource> createDrawScopeResource() = 0;
+
+public:
+ template <typename Name>
+ std::unique_ptr<Program<Name>> createProgram(const ProgramParameters&);
+
+private:
+ template <typename Backend, typename Name>
+ std::unique_ptr<Program<Name>> createProgram(const ProgramParameters&);
};
} // namespace gfx
diff --git a/src/mbgl/gfx/context_impl.hpp b/src/mbgl/gfx/context_impl.hpp
new file mode 100644
index 0000000000..0145535bb3
--- /dev/null
+++ b/src/mbgl/gfx/context_impl.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <mbgl/gfx/context.hpp>
+
+namespace mbgl {
+
+namespace gl {
+class Context;
+} // namespace gl
+
+namespace gfx {
+
+template <typename Name>
+std::unique_ptr<Program<Name>> Context::createProgram(const ProgramParameters& programParameters) {
+ if (backend == ContextType::OpenGL) {
+ return createProgram<gl::Context, Name>(programParameters);
+ }
+ assert(false);
+ return nullptr;
+}
+
+} // namespace gfx
+} // namespace mbgl
diff --git a/src/mbgl/gfx/draw_mode.hpp b/src/mbgl/gfx/draw_mode.hpp
index a0a9b6c575..e18a38903e 100644
--- a/src/mbgl/gfx/draw_mode.hpp
+++ b/src/mbgl/gfx/draw_mode.hpp
@@ -1,72 +1,77 @@
#pragma once
#include <mbgl/gfx/types.hpp>
-#include <mbgl/gfx/primitives.hpp>
#include <cassert>
namespace mbgl {
namespace gfx {
-class Points {
-public:
- using Primitive = Point;
-
- static constexpr std::size_t bufferGroupSize = 1;
- static constexpr PrimitiveType primitiveType = PrimitiveType::Points;
-
- explicit Points(float pointSize_) : pointSize(pointSize_) {}
-
- float pointSize;
-};
+class DrawMode {
+protected:
+ DrawMode(DrawModeType type_, float size_)
+ : type(type_), size(size_) {
+ }
-class Lines {
public:
- using Primitive = Line;
+ const DrawModeType type;
+ const float size;
+};
- static constexpr std::size_t bufferGroupSize = 2;
- static constexpr PrimitiveType primitiveType = PrimitiveType::Lines;
+template <class> struct BufferGroupSizeOf;
+template <class> struct PrimitiveTypeOf;
- explicit Lines(float lineWidth_) : lineWidth(lineWidth_) {
- assert(lineWidth > 0);
+class Points : public DrawMode {
+public:
+ explicit Points(float pointSize_) : DrawMode(DrawModeType::Points, pointSize_) {
+ assert(size > 0);
}
-
- float lineWidth;
};
-class LineStrip {
+template <> struct BufferGroupSizeOf<Points> : std::integral_constant<std::size_t, 1> {};
+template <> struct PrimitiveTypeOf<Points> : std::integral_constant<PrimitiveType, PrimitiveType::Point> {};
+
+class Lines : public DrawMode {
public:
- // LineStrip is a form of "Line" rendering, but the element buffer
- // cannot be grouped into logical elements beyond a single Point.
- using Primitive = Line;
+ explicit Lines(float lineWidth_) : DrawMode(DrawModeType::Lines, lineWidth_) {
+ assert(size > 0);
+ }
+};
- static constexpr std::size_t bufferGroupSize = 1;
- static constexpr PrimitiveType primitiveType = PrimitiveType::LineStrip;
+template <> struct BufferGroupSizeOf<Lines> : std::integral_constant<std::size_t, 2> {};
+template <> struct PrimitiveTypeOf<Lines> : std::integral_constant<PrimitiveType, PrimitiveType::Line> {};
- explicit LineStrip(float lineWidth_) : lineWidth(lineWidth_) {
- assert(lineWidth > 0);
+// LineStrip is a form of "Line" rendering, but the element buffer
+// cannot be grouped into logical elements beyond a single Point.
+class LineStrip : public DrawMode {
+public:
+ explicit LineStrip(float lineWidth_) : DrawMode(DrawModeType::LineStrip, lineWidth_) {
+ assert(size > 0);
}
-
- float lineWidth;
};
-class Triangles {
-public:
- using Primitive = Triangle;
+template <> struct BufferGroupSizeOf<LineStrip> : std::integral_constant<std::size_t, 1> {};
+template <> struct PrimitiveTypeOf<LineStrip> : std::integral_constant<PrimitiveType, PrimitiveType::Line> {};
- static constexpr std::size_t bufferGroupSize = 3;
- static constexpr PrimitiveType primitiveType = PrimitiveType::Triangles;
+class Triangles : public DrawMode {
+public:
+ explicit Triangles() : DrawMode(DrawModeType::Triangles, 0) {
+ }
};
-class TriangleStrip {
-public:
- // TriangleStrip is a form of "Triangle" rendering, but the element buffer
- // cannot be grouped into logical elements beyond a single Point.
- using Primitive = Triangle;
+template <> struct BufferGroupSizeOf<Triangles> : std::integral_constant<std::size_t, 3> {};
+template <> struct PrimitiveTypeOf<Triangles> : std::integral_constant<PrimitiveType, PrimitiveType::Triangle> {};
- static constexpr std::size_t bufferGroupSize = 1;
- static constexpr PrimitiveType primitiveType = PrimitiveType::TriangleStrip;
+// TriangleStrip is a form of "Triangle" rendering, but the element buffer
+// cannot be grouped into logical elements beyond a single Point.
+class TriangleStrip : public DrawMode {
+public:
+ explicit TriangleStrip() : DrawMode(DrawModeType::TriangleStrip, 0) {
+ }
};
+template <> struct BufferGroupSizeOf<TriangleStrip> : std::integral_constant<std::size_t, 1> {};
+template <> struct PrimitiveTypeOf<TriangleStrip> : std::integral_constant<PrimitiveType, PrimitiveType::Triangle> {};
+
} // namespace gfx
} // namespace mbgl
diff --git a/src/mbgl/gfx/draw_scope.hpp b/src/mbgl/gfx/draw_scope.hpp
new file mode 100644
index 0000000000..60aae7a44c
--- /dev/null
+++ b/src/mbgl/gfx/draw_scope.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <memory>
+
+namespace mbgl {
+namespace gfx {
+
+class DrawScopeResource {
+protected:
+ DrawScopeResource() = default;
+public:
+ virtual ~DrawScopeResource() = default;
+};
+
+class DrawScope {
+public:
+ std::unique_ptr<DrawScopeResource> resource;
+};
+
+} // namespace gfx
+} // namespace mbgl
diff --git a/src/mbgl/gfx/index_vector.hpp b/src/mbgl/gfx/index_vector.hpp
index dc760feb90..826d43bee3 100644
--- a/src/mbgl/gfx/index_vector.hpp
+++ b/src/mbgl/gfx/index_vector.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <mbgl/gfx/draw_mode.hpp>
#include <mbgl/util/ignore.hpp>
#include <vector>
@@ -10,7 +11,7 @@ namespace gfx {
template <class DrawMode>
class IndexVector {
public:
- static constexpr std::size_t groupSize = DrawMode::bufferGroupSize;
+ static constexpr std::size_t groupSize = BufferGroupSizeOf<DrawMode>::value;
template <class... Args>
void emplace_back(Args&&... args) {
diff --git a/src/mbgl/gfx/primitives.hpp b/src/mbgl/gfx/primitives.hpp
deleted file mode 100644
index f92b1ec525..0000000000
--- a/src/mbgl/gfx/primitives.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <cstddef>
-
-namespace mbgl {
-namespace gfx {
-
-class Point {
-public:
- static constexpr std::size_t vertexCount = 1;
-};
-
-class Line {
-public:
- static constexpr std::size_t vertexCount = 2;
-};
-
-class Triangle {
-public:
- static constexpr std::size_t vertexCount = 3;
-};
-
-} // namespace gfx
-} // namespace mbgl
diff --git a/src/mbgl/gfx/program.hpp b/src/mbgl/gfx/program.hpp
new file mode 100644
index 0000000000..94ba3b18ef
--- /dev/null
+++ b/src/mbgl/gfx/program.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <cstddef>
+
+namespace mbgl {
+namespace gfx {
+
+class Context;
+class DrawMode;
+class DepthMode;
+class StencilMode;
+class ColorMode;
+class CullFaceMode;
+class DrawScope;
+class IndexBuffer;
+template <class> class UniformValues;
+template <class> class AttributeBindings;
+template <class> class TextureBindings;
+
+template <class Name>
+class Program {
+protected:
+ Program() = default;
+
+public:
+ virtual ~Program() = default;
+
+ Program(Program&&) = delete;
+ Program(const Program&) = delete;
+ Program& operator=(Program&&) = delete;
+ Program& operator=(const Program&) = delete;
+
+ using AttributeList = typename Name::AttributeList;
+ using UniformList = typename Name::UniformList;
+ using TextureList = typename Name::TextureList;
+
+ virtual void draw(Context&,
+ const DrawMode&,
+ const DepthMode&,
+ const StencilMode&,
+ const ColorMode&,
+ const CullFaceMode&,
+ const UniformValues<UniformList>&,
+ DrawScope&,
+ const AttributeBindings<AttributeList>&,
+ const TextureBindings<TextureList>&,
+ const IndexBuffer&,
+ std::size_t indexOffset,
+ std::size_t indexLength) = 0;
+};
+
+} // namespace gfx
+} // namespace mbgl
diff --git a/src/mbgl/gfx/texture.hpp b/src/mbgl/gfx/texture.hpp
index 758bdd1b09..a957c4ebdf 100644
--- a/src/mbgl/gfx/texture.hpp
+++ b/src/mbgl/gfx/texture.hpp
@@ -52,21 +52,19 @@ public:
TextureWrapType wrapY;
};
-namespace detail {
-
template <class>
class TextureBindings;
template <class... Ts>
-class TextureBindings<TypeList<Ts...>> {
+class TextureBindings<TypeList<Ts...>> final
+ : public IndexedTuple<TypeList<Ts...>, TypeList<ExpandToType<Ts, TextureBinding>...>> {
+ using Base = IndexedTuple<TypeList<Ts...>, TypeList<ExpandToType<Ts, TextureBinding>...>>;
+
public:
- using Type = IndexedTuple<TypeList<Ts...>, TypeList<ExpandToType<Ts, TextureBinding>...>>;
+ template <class... Args>
+ TextureBindings(Args&&... args) : Base(std::forward<Args>(args)...) {
+ }
};
-} // namespace detail
-
-template <class TextureTypeList>
-using TextureBindings = typename detail::TextureBindings<TextureTypeList>::Type;
-
} // namespace gfx
} // namespace mbgl
diff --git a/src/mbgl/gfx/types.hpp b/src/mbgl/gfx/types.hpp
index 4c6a040b1f..da2bc14ddd 100644
--- a/src/mbgl/gfx/types.hpp
+++ b/src/mbgl/gfx/types.hpp
@@ -5,7 +5,17 @@
namespace mbgl {
namespace gfx {
+enum class ContextType : uint8_t {
+ OpenGL,
+};
+
enum class PrimitiveType : uint8_t {
+ Point,
+ Line,
+ Triangle,
+};
+
+enum class DrawModeType : uint8_t {
Points,
Lines,
LineLoop,
diff --git a/src/mbgl/gfx/uniform.hpp b/src/mbgl/gfx/uniform.hpp
index bc6e7c1866..f6896b9138 100644
--- a/src/mbgl/gfx/uniform.hpp
+++ b/src/mbgl/gfx/uniform.hpp
@@ -31,21 +31,20 @@
namespace mbgl {
namespace gfx {
-namespace detail {
template <class>
class UniformValues;
template <class... Us>
-class UniformValues<TypeList<Us...>> {
+class UniformValues<TypeList<Us...>> final
+ : public IndexedTuple<TypeList<Us...>, TypeList<typename Us::Value...>> {
+ using Base = IndexedTuple<TypeList<Us...>, TypeList<typename Us::Value...>>;
+
public:
- using Type = IndexedTuple<TypeList<Us...>, TypeList<typename Us::Value...>>;
+ template <class... Args>
+ UniformValues(Args&&... args) : Base(std::forward<Args>(args)...) {
+ }
};
-} // namespace detail
-
-template <class UniformTypeList>
-using UniformValues = typename detail::UniformValues<UniformTypeList>::Type;
-
} // namespace gfx
} // namespace mbgl