summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2017-07-06 15:31:30 +0200
committerKonstantin Käfer <mail@kkaefer.com>2017-07-11 14:59:04 +0200
commit2d36983bbb1131282241bd4d8b5240bf2c86d0ec (patch)
tree1cef276be48fe6db6dcede1604efc70a00c8a49b
parentcbdfabb4b5c86a5ed8611527cbeb36aaf00c58c7 (diff)
downloadqtlocation-mapboxgl-2d36983bbb1131282241bd4d8b5240bf2c86d0ec.tar.gz
[core] add IndexedPrimitives/Drawables object to encapsulate primitive construction
-rw-r--r--cmake/core-files.cmake2
-rw-r--r--cmake/test-files.cmake1
-rw-r--r--src/mbgl/gl/attribute.hpp26
-rw-r--r--src/mbgl/gl/index_buffer.hpp1
-rw-r--r--src/mbgl/gl/segment.hpp7
-rw-r--r--src/mbgl/gl/vertex_buffer.hpp1
-rw-r--r--src/mbgl/layout/symbol_layout.cpp4
-rw-r--r--src/mbgl/programs/debug_program.hpp9
-rw-r--r--src/mbgl/renderer/buckets/circle_bucket.cpp2
-rw-r--r--src/mbgl/renderer/buckets/debug_bucket.cpp2
-rw-r--r--src/mbgl/renderer/buckets/fill_bucket.cpp4
-rw-r--r--src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp2
-rw-r--r--src/mbgl/renderer/buckets/line_bucket.cpp2
-rw-r--r--src/mbgl/renderer/drawable.hpp28
-rw-r--r--src/mbgl/renderer/indexed_primitives.hpp78
-rw-r--r--src/mbgl/renderer/painter.cpp116
-rw-r--r--src/mbgl/renderer/painter.hpp16
-rw-r--r--src/mbgl/renderer/painters/painter_background.cpp12
-rw-r--r--src/mbgl/renderer/painters/painter_clipping.cpp6
-rw-r--r--src/mbgl/renderer/painters/painter_debug.cpp12
-rw-r--r--src/mbgl/renderer/painters/painter_raster.cpp6
-rw-r--r--src/mbgl/renderer/sources/render_image_source.cpp2
-rw-r--r--test/gl/primitives.test.cpp125
23 files changed, 370 insertions, 94 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index fc476fcd15..395069bc45 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -163,6 +163,7 @@ set(MBGL_CORE_FILES
src/mbgl/renderer/cross_faded_property_evaluator.cpp
src/mbgl/renderer/cross_faded_property_evaluator.hpp
src/mbgl/renderer/data_driven_property_evaluator.hpp
+ src/mbgl/renderer/drawable.hpp
src/mbgl/renderer/frame_history.cpp
src/mbgl/renderer/frame_history.hpp
src/mbgl/renderer/group_by_layout.cpp
@@ -171,6 +172,7 @@ set(MBGL_CORE_FILES
src/mbgl/renderer/image_atlas.hpp
src/mbgl/renderer/image_manager.cpp
src/mbgl/renderer/image_manager.hpp
+ src/mbgl/renderer/indexed_primitives.hpp
src/mbgl/renderer/paint_parameters.hpp
src/mbgl/renderer/paint_property_binder.hpp
src/mbgl/renderer/paint_property_statistics.hpp
diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake
index 4dec9e403d..7271887dac 100644
--- a/cmake/test-files.cmake
+++ b/cmake/test-files.cmake
@@ -22,6 +22,7 @@ set(MBGL_TEST_FILES
# gl
test/gl/bucket.test.cpp
test/gl/object.test.cpp
+ test/gl/primitives.test.cpp
# include/mbgl
test/include/mbgl/test.hpp
diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp
index f018a1d261..c6484a79c7 100644
--- a/src/mbgl/gl/attribute.hpp
+++ b/src/mbgl/gl/attribute.hpp
@@ -221,6 +221,32 @@ const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = {
offsetof(VertexType, a5)
};
+template <class A1>
+bool operator==(const Vertex<A1>& lhs, const Vertex<A1>& rhs) {
+ return std::tie(lhs.a1) == std::tie(rhs.a1);
+}
+
+template <class A1, class A2>
+bool operator==(const Vertex<A1, A2>& lhs, const Vertex<A1, A2>& rhs) {
+ return std::tie(lhs.a1, lhs.a2) == std::tie(rhs.a1, rhs.a2);
+}
+
+template <class A1, class A2, class A3>
+bool operator==(const Vertex<A1, A2, A3>& lhs, const Vertex<A1, A2, A3>& rhs) {
+ return std::tie(lhs.a1, lhs.a2, lhs.a3) == std::tie(rhs.a1, rhs.a2, rhs.a3);
+}
+
+template <class A1, class A2, class A3, class A4>
+bool operator==(const Vertex<A1, A2, A3, A4>& lhs, const Vertex<A1, A2, A3, A4>& rhs) {
+ return std::tie(lhs.a1, lhs.a2, lhs.a3, lhs.a4) == std::tie(rhs.a1, rhs.a2, rhs.a3, rhs.a4);
+}
+
+template <class A1, class A2, class A3, class A4, class A5>
+bool operator==(const Vertex<A1, A2, A3, A4, A5>& lhs, const Vertex<A1, A2, A3, A4, A5>& rhs) {
+ return std::tie(lhs.a1, lhs.a2, lhs.a3, lhs.a4, lhs.a5) ==
+ std::tie(rhs.a1, rhs.a2, rhs.a3, rhs.a4, rhs.a5);
+}
+
} // namespace detail
AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name);
diff --git a/src/mbgl/gl/index_buffer.hpp b/src/mbgl/gl/index_buffer.hpp
index 1e57fb11f2..01b6396e00 100644
--- a/src/mbgl/gl/index_buffer.hpp
+++ b/src/mbgl/gl/index_buffer.hpp
@@ -26,6 +26,7 @@ public:
bool empty() const { return v.empty(); }
void clear() { v.clear(); }
const uint16_t* data() const { return v.data(); }
+ const std::vector<uint16_t>& vector() const { return v; }
private:
std::vector<uint16_t> v;
diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp
index 442f5be532..0dc092c1b4 100644
--- a/src/mbgl/gl/segment.hpp
+++ b/src/mbgl/gl/segment.hpp
@@ -39,13 +39,6 @@ using SegmentInfoVector = std::vector<SegmentInfo>;
template <class Attributes>
class Segment {
public:
- Segment(std::size_t vertexOffset,
- std::size_t indexOffset,
- std::size_t vertexLength = 0,
- std::size_t indexLength = 0)
- : info(vertexOffset, indexOffset, vertexLength, indexLength) {
- }
-
Segment(SegmentInfo info_)
: info(std::move(info_)) {
}
diff --git a/src/mbgl/gl/vertex_buffer.hpp b/src/mbgl/gl/vertex_buffer.hpp
index 4808803d00..9f8b156b25 100644
--- a/src/mbgl/gl/vertex_buffer.hpp
+++ b/src/mbgl/gl/vertex_buffer.hpp
@@ -28,6 +28,7 @@ public:
bool empty() const { return v.empty(); }
void clear() { v.clear(); }
const Vertex* data() const { return v.data(); }
+ const std::vector<Vertex>& vector() const { return v; }
private:
std::vector<Vertex> v;
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 0df2df1988..44374b123e 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -577,7 +577,7 @@ void SymbolLayout::addSymbol(Buffer& buffer,
}
if (buffer.segments.empty() || buffer.segments.back().info.vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
- buffer.segments.emplace_back(buffer.vertices.vertexSize(), buffer.triangles.indexSize());
+ buffer.segments.emplace_back(gl::SegmentInfo{ buffer.vertices.vertexSize(), buffer.triangles.indexSize() });
}
// We're generating triangle fans, so we always start with the first
@@ -640,7 +640,7 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket&
static constexpr std::size_t indexLength = 8;
if (collisionBox.segments.empty() || collisionBox.segments.back().info.vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
- collisionBox.segments.emplace_back(collisionBox.vertices.vertexSize(), collisionBox.lines.indexSize());
+ collisionBox.segments.emplace_back(gl::SegmentInfo{ collisionBox.vertices.vertexSize(), collisionBox.lines.indexSize() });
}
auto& segment = collisionBox.segments.back();
diff --git a/src/mbgl/programs/debug_program.hpp b/src/mbgl/programs/debug_program.hpp
index 7a6d075cdb..c9e7384596 100644
--- a/src/mbgl/programs/debug_program.hpp
+++ b/src/mbgl/programs/debug_program.hpp
@@ -20,6 +20,15 @@ class DebugProgram : public Program<
{
public:
using Program::Program;
+
+ static LayoutVertex layoutVertex(Point<int16_t> p) {
+ return LayoutVertex {
+ {{
+ p.x,
+ p.y
+ }}
+ };
+ }
};
using DebugLayoutVertex = DebugProgram::LayoutVertex;
diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp
index 497c6e2155..aa954ca6d2 100644
--- a/src/mbgl/renderer/buckets/circle_bucket.cpp
+++ b/src/mbgl/renderer/buckets/circle_bucket.cpp
@@ -62,7 +62,7 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature,
if (segments.empty() || segments.back().info.vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
// Move to a new segments because the old one can't hold the geometry.
- segments.emplace_back(vertices.vertexSize(), triangles.indexSize());
+ segments.emplace_back(gl::SegmentInfo{ vertices.vertexSize(), triangles.indexSize() });
}
// this geometry will be of the Point type, and we'll derive
diff --git a/src/mbgl/renderer/buckets/debug_bucket.cpp b/src/mbgl/renderer/buckets/debug_bucket.cpp
index acfe15d2fb..dbe182686b 100644
--- a/src/mbgl/renderer/buckets/debug_bucket.cpp
+++ b/src/mbgl/renderer/buckets/debug_bucket.cpp
@@ -74,7 +74,7 @@ DebugBucket::DebugBucket(const OverscaledTileID& id,
addText(expiresText, 50, baseline + 200, 5);
}
- segments.emplace_back(0, 0, vertices.vertexSize(), indices.indexSize());
+ segments.emplace_back(gl::SegmentInfo{ 0, 0, vertices.vertexSize(), indices.indexSize() });
vertexBuffer = context.createVertexBuffer(std::move(vertices));
indexBuffer = context.createIndexBuffer(std::move(indices));
diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp
index 9cf1c9d6aa..a4167c934a 100644
--- a/src/mbgl/renderer/buckets/fill_bucket.cpp
+++ b/src/mbgl/renderer/buckets/fill_bucket.cpp
@@ -62,7 +62,7 @@ void FillBucket::addFeature(const GeometryTileFeature& feature,
continue;
if (lineSegments.empty() || lineSegments.back().info.vertexLength + nVertices > std::numeric_limits<uint16_t>::max()) {
- lineSegments.emplace_back(vertices.vertexSize(), lines.indexSize());
+ lineSegments.emplace_back(gl::SegmentInfo{ vertices.vertexSize(), lines.indexSize() });
}
auto& lineSegment = lineSegments.back();
@@ -87,7 +87,7 @@ void FillBucket::addFeature(const GeometryTileFeature& feature,
assert(nIndicies % 3 == 0);
if (triangleSegments.empty() || triangleSegments.back().info.vertexLength + totalVertices > std::numeric_limits<uint16_t>::max()) {
- triangleSegments.emplace_back(startVertices, triangles.indexSize());
+ triangleSegments.emplace_back(gl::SegmentInfo{ startVertices, triangles.indexSize() });
}
auto& triangleSegment = triangleSegments.back();
diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp
index ec507da900..bb01eee665 100644
--- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp
+++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp
@@ -69,7 +69,7 @@ void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature,
if (triangleSegments.empty() ||
triangleSegments.back().info.vertexLength + (5 * (totalVertices - 1) + 1) >
std::numeric_limits<uint16_t>::max()) {
- triangleSegments.emplace_back(startVertices, triangles.indexSize());
+ triangleSegments.emplace_back(gl::SegmentInfo{ startVertices, triangles.indexSize() });
}
auto& triangleSegment = triangleSegments.back();
diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp
index d81ad76851..29c2cfb650 100644
--- a/src/mbgl/renderer/buckets/line_bucket.cpp
+++ b/src/mbgl/renderer/buckets/line_bucket.cpp
@@ -372,7 +372,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, FeatureType
const std::size_t vertexCount = endVertex - startVertex;
if (segments.empty() || segments.back().info.vertexLength + vertexCount > std::numeric_limits<uint16_t>::max()) {
- segments.emplace_back(startVertex, triangles.indexSize());
+ segments.emplace_back(gl::SegmentInfo{ startVertex, triangles.indexSize() });
}
auto& segment = segments.back();
diff --git a/src/mbgl/renderer/drawable.hpp b/src/mbgl/renderer/drawable.hpp
new file mode 100644
index 0000000000..4b10d49b0a
--- /dev/null
+++ b/src/mbgl/renderer/drawable.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/gl/segment.hpp>
+
+namespace mbgl {
+
+template <class DrawMode, class LayoutVertex, class AttributeLayout>
+class IndexedPrimitives;
+
+template <class DrawMode, class LayoutVertex, class Attributes>
+class Drawable {
+public:
+ Drawable(gl::Context& context,
+ IndexedPrimitives<DrawMode, LayoutVertex, Attributes>&& primitives)
+ : vertices(context.createVertexBuffer(std::move(primitives.vertices))),
+ indices(context.createIndexBuffer(std::move(primitives.indices))),
+ segments(primitives.segmentInfo.begin(), primitives.segmentInfo.end()) {
+ primitives = {};
+ }
+
+ const gl::VertexBuffer<LayoutVertex> vertices;
+ const gl::IndexBuffer<DrawMode> indices;
+ const gl::SegmentVector<Attributes> segments;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/indexed_primitives.hpp b/src/mbgl/renderer/indexed_primitives.hpp
new file mode 100644
index 0000000000..c75fe61b18
--- /dev/null
+++ b/src/mbgl/renderer/indexed_primitives.hpp
@@ -0,0 +1,78 @@
+#pragma once
+
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/gl/segment.hpp>
+
+#include <stdexcept>
+
+namespace mbgl {
+
+template <class DrawMode, class LayoutVertex, class AttributeLayout>
+class Drawable;
+
+template <class DrawMode, class LayoutVertex, class AttributeLayout>
+class IndexedPrimitives {
+public:
+ void add(std::initializer_list<LayoutVertex> v,
+ std::initializer_list<std::array<uint16_t, DrawMode::bufferGroupSize>> i) {
+ // Check that all vertices fit into the current segment, if not, create a new one.
+ if (segmentInfo.empty() || segmentInfo.back().vertexLength + v.size() > std::numeric_limits<uint16_t>::max()) {
+ segmentInfo.emplace_back(vertices.vertexSize(), indices.indexSize());
+ }
+
+ auto& segment = segmentInfo.back();
+ const uint16_t offset = segment.vertexLength;
+
+ for (const auto& primitive : i) {
+ for (uint16_t index : primitive) {
+ // Check that the index references a vertex supplied in this list and that it is not
+ // out of bounds.
+ if (index >= v.size()) {
+ throw std::out_of_range("primitive contains indices outside its vertex group");
+ }
+ }
+
+ // Insert all indices into the list.
+ addIndices(primitive, offset, std::make_index_sequence<DrawMode::bufferGroupSize>());
+ }
+
+ // Insert all vertices into the list.
+ for (const auto& vertex : v) {
+ vertices.emplace_back(vertex);
+ }
+
+ // Update the current segment statistics.
+ segment.vertexLength += v.size();
+ segment.indexLength += i.size() * DrawMode::bufferGroupSize;
+ }
+
+ // Accessors for test suite.
+ const gl::VertexVector<LayoutVertex>& getVertices() const {
+ return vertices;
+ }
+
+ const gl::IndexVector<DrawMode>& getIndices() const {
+ return indices;
+ }
+
+ const gl::SegmentInfoVector& getSegmentInfo() const {
+ return segmentInfo;
+ }
+
+private:
+ // Helper function for expanding primitives.
+ template <std::size_t N, std::size_t... I>
+ void addIndices(std::array<uint16_t, N> primitive, const uint16_t offset, std::index_sequence<I...>) {
+ // Adds the current offset to the indices.
+ indices.emplace_back((std::get<I>(primitive) + offset)...);
+ }
+
+private:
+ friend class Drawable<DrawMode, LayoutVertex, AttributeLayout>;
+ gl::VertexVector<LayoutVertex> vertices;
+ gl::IndexVector<DrawMode> indices;
+ gl::SegmentInfoVector segmentInfo;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index a3decdb603..fa8756921c 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -3,6 +3,7 @@
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/renderer/render_style.hpp>
+#include <mbgl/renderer/indexed_primitives.hpp>
#include <mbgl/style/source.hpp>
#include <mbgl/style/source_impl.hpp>
@@ -42,68 +43,83 @@ namespace mbgl {
using namespace style;
-static gl::VertexVector<FillLayoutVertex> tileVertices() {
- gl::VertexVector<FillLayoutVertex> result;
- result.emplace_back(FillProgram::layoutVertex({ 0, 0 }));
- result.emplace_back(FillProgram::layoutVertex({ util::EXTENT, 0 }));
- result.emplace_back(FillProgram::layoutVertex({ 0, util::EXTENT }));
- result.emplace_back(FillProgram::layoutVertex({ util::EXTENT, util::EXTENT }));
- return result;
-}
-
-static gl::IndexVector<gl::Triangles> quadTriangleIndices() {
- gl::IndexVector<gl::Triangles> result;
- result.emplace_back(0, 1, 2);
- result.emplace_back(1, 2, 3);
- return result;
+static auto rasterPrimitives() {
+ IndexedPrimitives<gl::Triangles, RasterLayoutVertex, RasterAttributes> primitives;
+ primitives.add(
+ {
+ RasterProgram::layoutVertex({ 0, 0 }, { 0, 0 }),
+ RasterProgram::layoutVertex({ util::EXTENT, 0 }, { 32767, 0 }),
+ RasterProgram::layoutVertex({ 0, util::EXTENT }, { 0, 32767 }),
+ RasterProgram::layoutVertex({ util::EXTENT, util::EXTENT }, { 32767, 32767 }),
+ }, {
+ {{ 0, 1, 2 }},
+ {{ 1, 2, 3 }},
+ }
+ );
+ return primitives;
}
-static gl::IndexVector<gl::LineStrip> tileLineStripIndices() {
- gl::IndexVector<gl::LineStrip> result;
- result.emplace_back(0);
- result.emplace_back(1);
- result.emplace_back(3);
- result.emplace_back(2);
- result.emplace_back(0);
- return result;
+static auto borderPrimitives() {
+ IndexedPrimitives<gl::LineStrip, DebugLayoutVertex, DebugAttributes> primitives;
+ primitives.add(
+ {
+ DebugProgram::layoutVertex({ 0, 0 }),
+ DebugProgram::layoutVertex({ util::EXTENT, 0 }),
+ DebugProgram::layoutVertex({ util::EXTENT, util::EXTENT }),
+ DebugProgram::layoutVertex({ 0, util::EXTENT }),
+ }, {
+ {{ 0 }},
+ {{ 1 }},
+ {{ 2 }},
+ {{ 3 }},
+ {{ 0 }},
+ }
+ );
+ return primitives;
}
-static gl::VertexVector<RasterLayoutVertex> rasterVertices() {
- gl::VertexVector<RasterLayoutVertex> result;
- result.emplace_back(RasterProgram::layoutVertex({ 0, 0 }, { 0, 0 }));
- result.emplace_back(RasterProgram::layoutVertex({ util::EXTENT, 0 }, { 32767, 0 }));
- result.emplace_back(RasterProgram::layoutVertex({ 0, util::EXTENT }, { 0, 32767 }));
- result.emplace_back(RasterProgram::layoutVertex({ util::EXTENT, util::EXTENT }, { 32767, 32767 }));
- return result;
+static auto fillPrimitives() {
+ IndexedPrimitives<gl::Triangles, FillLayoutVertex, FillAttributes> primitives;
+ primitives.add(
+ {
+ FillProgram::layoutVertex({ 0, 0 }),
+ FillProgram::layoutVertex({ util::EXTENT, 0 }),
+ FillProgram::layoutVertex({ 0, util::EXTENT }),
+ FillProgram::layoutVertex({ util::EXTENT, util::EXTENT }),
+ }, {
+ {{ 0, 1, 2 }},
+ {{ 1, 2, 3 }},
+ }
+ );
+ return primitives;
}
-static gl::VertexVector<ExtrusionTextureLayoutVertex> extrusionTextureVertices() {
- gl::VertexVector<ExtrusionTextureLayoutVertex> result;
- result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 0, 0 }));
- result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 1, 0 }));
- result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 0, 1 }));
- result.emplace_back(ExtrusionTextureProgram::layoutVertex({ 1, 1 }));
- return result;
+static auto extrusionTexturePrimitives() {
+ IndexedPrimitives<gl::Triangles, ExtrusionTextureLayoutVertex, ExtrusionTextureAttributes> primitives;
+ primitives.add(
+ {
+ ExtrusionTextureProgram::layoutVertex({ 0, 0 }),
+ ExtrusionTextureProgram::layoutVertex({ 1, 0 }),
+ ExtrusionTextureProgram::layoutVertex({ 0, 1 }),
+ ExtrusionTextureProgram::layoutVertex({ 1, 1 }),
+ }, {
+ {{ 0, 1, 2 }},
+ {{ 1, 2, 3 }},
+ }
+ );
+ return primitives;
}
-
Painter::Painter(gl::Context& context_,
const TransformState& state_,
float pixelRatio,
const optional<std::string>& programCacheDir)
: context(context_),
state(state_),
- tileVertexBuffer(context.createVertexBuffer(tileVertices())),
- rasterVertexBuffer(context.createVertexBuffer(rasterVertices())),
- extrusionTextureVertexBuffer(context.createVertexBuffer(extrusionTextureVertices())),
- quadTriangleIndexBuffer(context.createIndexBuffer(quadTriangleIndices())),
- tileBorderIndexBuffer(context.createIndexBuffer(tileLineStripIndices())) {
-
- tileTriangleSegments.emplace_back(0, 0, 4, 6);
- tileBorderSegments.emplace_back(0, 0, 4, 5);
- rasterSegments.emplace_back(0, 0, 4, 6);
- extrusionTextureSegments.emplace_back(0, 0, 4, 6);
-
+ rasterDrawable(context, rasterPrimitives()),
+ fillDrawable(context, fillPrimitives()),
+ borderDrawable(context, borderPrimitives()),
+ extrusionTextureDrawable(context, extrusionTexturePrimitives()) {
programs = std::make_unique<Programs>(context,
ProgramParameters{ pixelRatio, false, programCacheDir });
#ifndef NDEBUG
@@ -323,7 +339,9 @@ void Painter::renderPass(PaintParameters& parameters,
uniforms::u_image::Value{ 0 },
uniforms::u_opacity::Value{ layer.as<RenderFillExtrusionLayer>()
->evaluated.get<FillExtrusionOpacity>() } },
- extrusionTextureVertexBuffer, quadTriangleIndexBuffer, extrusionTextureSegments,
+ extrusionTextureDrawable.vertices,
+ extrusionTextureDrawable.indices,
+ extrusionTextureDrawable.segments,
ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties,
state.getZoom());
} else {
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 7e966adefa..9e81f50a5a 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -8,6 +8,7 @@
#include <mbgl/renderer/render_item.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/renderer/render_light.hpp>
+#include <mbgl/renderer/drawable.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/programs/debug_program.hpp>
@@ -165,17 +166,10 @@ public:
std::unique_ptr<Programs> overdrawPrograms;
#endif
- gl::VertexBuffer<FillLayoutVertex> tileVertexBuffer;
- gl::VertexBuffer<RasterLayoutVertex> rasterVertexBuffer;
- gl::VertexBuffer<ExtrusionTextureLayoutVertex> extrusionTextureVertexBuffer;
-
- gl::IndexBuffer<gl::Triangles> quadTriangleIndexBuffer;
- gl::IndexBuffer<gl::LineStrip> tileBorderIndexBuffer;
-
- gl::SegmentVector<FillAttributes> tileTriangleSegments;
- gl::SegmentVector<DebugAttributes> tileBorderSegments;
- gl::SegmentVector<RasterAttributes> rasterSegments;
- gl::SegmentVector<ExtrusionTextureAttributes> extrusionTextureSegments;
+ const Drawable<gl::Triangles, RasterLayoutVertex, RasterAttributes> rasterDrawable;
+ const Drawable<gl::Triangles, FillLayoutVertex, FillAttributes> fillDrawable;
+ const Drawable<gl::LineStrip, DebugLayoutVertex, DebugAttributes> borderDrawable;
+ const Drawable<gl::Triangles, ExtrusionTextureLayoutVertex, ExtrusionTextureAttributes> extrusionTextureDrawable;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/painters/painter_background.cpp b/src/mbgl/renderer/painters/painter_background.cpp
index 577d7d6cda..0378182c16 100644
--- a/src/mbgl/renderer/painters/painter_background.cpp
+++ b/src/mbgl/renderer/painters/painter_background.cpp
@@ -49,9 +49,9 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou
tileID,
state
),
- tileVertexBuffer,
- quadTriangleIndexBuffer,
- tileTriangleSegments,
+ fillDrawable.vertices,
+ fillDrawable.indices,
+ fillDrawable.segments,
paintAttibuteData,
properties,
state.getZoom()
@@ -69,9 +69,9 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou
uniforms::u_matrix::Value{ matrixForTile(tileID) },
uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
},
- tileVertexBuffer,
- quadTriangleIndexBuffer,
- tileTriangleSegments,
+ fillDrawable.vertices,
+ fillDrawable.indices,
+ fillDrawable.segments,
paintAttibuteData,
properties,
state.getZoom()
diff --git a/src/mbgl/renderer/painters/painter_clipping.cpp b/src/mbgl/renderer/painters/painter_clipping.cpp
index cad092594e..5de372be14 100644
--- a/src/mbgl/renderer/painters/painter_clipping.cpp
+++ b/src/mbgl/renderer/painters/painter_clipping.cpp
@@ -25,9 +25,9 @@ void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& cl
uniforms::u_matrix::Value{ matrixForTile(tileID) },
uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
},
- tileVertexBuffer,
- quadTriangleIndexBuffer,
- tileTriangleSegments,
+ fillDrawable.vertices,
+ fillDrawable.indices,
+ fillDrawable.segments,
paintAttibuteData,
properties,
state.getZoom()
diff --git a/src/mbgl/renderer/painters/painter_debug.cpp b/src/mbgl/renderer/painters/painter_debug.cpp
index ee76aee54c..d86a150994 100644
--- a/src/mbgl/renderer/painters/painter_debug.cpp
+++ b/src/mbgl/renderer/painters/painter_debug.cpp
@@ -70,9 +70,9 @@ void Painter::renderTileDebug(const RenderTile& renderTile) {
if (frame.debugOptions & MapDebugOptions::TileBorders) {
draw(Color::red(),
- tileVertexBuffer,
- tileBorderIndexBuffer,
- tileBorderSegments,
+ borderDrawable.vertices,
+ borderDrawable.indices,
+ borderDrawable.segments,
gl::LineStrip { 4.0f * frame.pixelRatio });
}
}
@@ -95,9 +95,9 @@ void Painter::renderTileDebug(const mat4& matrix) {
uniforms::u_matrix::Value{ matrix },
uniforms::u_color::Value{ Color::red() }
},
- tileVertexBuffer,
- tileBorderIndexBuffer,
- tileBorderSegments,
+ borderDrawable.vertices,
+ borderDrawable.indices,
+ borderDrawable.segments,
paintAttibuteData,
properties,
state.getZoom()
diff --git a/src/mbgl/renderer/painters/painter_raster.cpp b/src/mbgl/renderer/painters/painter_raster.cpp
index 56e38ae8f4..aa092e94b4 100644
--- a/src/mbgl/renderer/painters/painter_raster.cpp
+++ b/src/mbgl/renderer/painters/painter_raster.cpp
@@ -77,9 +77,9 @@ void Painter::renderRaster(PaintParameters& parameters,
uniforms::u_scale_parent::Value{ 1.0f },
uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} },
},
- useBucketBuffers ? *bucket.vertexBuffer : rasterVertexBuffer,
- useBucketBuffers ? *bucket.indexBuffer : quadTriangleIndexBuffer,
- useBucketBuffers ? bucket.segments : rasterSegments,
+ useBucketBuffers ? *bucket.vertexBuffer : rasterDrawable.vertices,
+ useBucketBuffers ? *bucket.indexBuffer : rasterDrawable.indices,
+ useBucketBuffers ? bucket.segments : rasterDrawable.segments,
paintAttributeData,
properties,
state.getZoom()
diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp
index f5068b9d7f..d9c0355573 100644
--- a/src/mbgl/renderer/sources/render_image_source.cpp
+++ b/src/mbgl/renderer/sources/render_image_source.cpp
@@ -159,7 +159,7 @@ void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_,
bucket->indices.emplace_back(0, 1, 2);
bucket->indices.emplace_back(1, 2, 3);
- bucket->segments.emplace_back(0, 0, 4, 6);
+ bucket->segments.emplace_back(gl::SegmentInfo{ 0, 0, 4, 6 });
}
void RenderImageSource::render(Painter& painter,
diff --git a/test/gl/primitives.test.cpp b/test/gl/primitives.test.cpp
new file mode 100644
index 0000000000..50b0d26977
--- /dev/null
+++ b/test/gl/primitives.test.cpp
@@ -0,0 +1,125 @@
+#include <mbgl/test/util.hpp>
+
+#include <mbgl/renderer/indexed_primitives.hpp>
+#include <mbgl/gl/draw_mode.hpp>
+
+#include <mbgl/programs/fill_program.hpp>
+
+namespace mbgl {
+namespace gl {
+
+std::ostream& operator<<(std::ostream& os, const SegmentInfo& info) {
+ return os << "{ " << info.vertexOffset << ", " << info.indexOffset
+ << ", " << info.vertexLength << ", " << info.indexLength << " }";
+}
+
+} // namespace gl
+} // namespace mbgl
+
+using namespace mbgl;
+
+TEST(Primitives, Adding) {
+ IndexedPrimitives<gl::Triangles, FillLayoutVertex, FillAttributes> primitives;
+
+ primitives.add({
+ FillProgram::layoutVertex({ 0, 0 }),
+ FillProgram::layoutVertex({ util::EXTENT, 0 }),
+ FillProgram::layoutVertex({ 0, util::EXTENT }),
+ FillProgram::layoutVertex({ util::EXTENT, util::EXTENT }),
+ }, {
+ {{ 0, 1, 2 }},
+ {{ 1, 2, 3 }},
+ });
+
+ primitives.add({
+ FillProgram::layoutVertex({ 0, 0 }),
+ FillProgram::layoutVertex({ util::EXTENT, 0 }),
+ FillProgram::layoutVertex({ 0, util::EXTENT }),
+ FillProgram::layoutVertex({ util::EXTENT, util::EXTENT }),
+ }, {
+ {{ 0, 1, 2 }},
+ {{ 1, 2, 3 }},
+ });
+
+ EXPECT_EQ(
+ (std::vector<FillLayoutVertex>{
+ FillProgram::layoutVertex({ 0, 0 }),
+ FillProgram::layoutVertex({ util::EXTENT, 0 }),
+ FillProgram::layoutVertex({ 0, util::EXTENT }),
+ FillProgram::layoutVertex({ util::EXTENT, util::EXTENT }),
+ FillProgram::layoutVertex({ 0, 0 }),
+ FillProgram::layoutVertex({ util::EXTENT, 0 }),
+ FillProgram::layoutVertex({ 0, util::EXTENT }),
+ FillProgram::layoutVertex({ util::EXTENT, util::EXTENT }),
+ }),
+ primitives.getVertices().vector());
+
+ EXPECT_EQ(
+ (std::vector<uint16_t>{
+ 0, 1, 2,
+ 1, 2, 3,
+ 4, 5, 6,
+ 5, 6, 7,
+ }),
+ primitives.getIndices().vector());
+
+
+ EXPECT_EQ(
+ (gl::SegmentInfoVector{
+ { 0, 0, 8, 12 }
+ }),
+ primitives.getSegmentInfo());
+}
+
+TEST(Primitives, OverflowVertices) {
+ IndexedPrimitives<gl::Triangles, FillLayoutVertex, FillAttributes> primitives;
+
+ for (int32_t i = 0; i < 21846; i++) {
+ primitives.add({
+ FillProgram::layoutVertex({ 0, 0 }),
+ FillProgram::layoutVertex({ 0, 0 }),
+ FillProgram::layoutVertex({ 0, 0 }),
+ }, {
+ {{ 0, 1, 2 }},
+ });
+ }
+
+ EXPECT_EQ(
+ (gl::SegmentInfoVector{
+ { 0, 0, 65535, 65535 },
+ { 65535, 65535, 3, 3 }
+ }),
+ primitives.getSegmentInfo());
+}
+
+TEST(Primitives, OverflowIndices) {
+ IndexedPrimitives<gl::Triangles, FillLayoutVertex, FillAttributes> primitives;
+
+ for (int32_t i = 0; i < 65536; i++) {
+ primitives.add({
+ FillProgram::layoutVertex({ 0, 0 }),
+ }, {
+ {{ 0, 0, 0 }},
+ });
+ }
+
+ EXPECT_EQ(
+ (gl::SegmentInfoVector{
+ { 0, 0, 65535, 196605 },
+ { 65535, 196605, 1, 3 }
+ }),
+ primitives.getSegmentInfo());
+}
+
+TEST(Primitives, InvalidIndex) {
+ IndexedPrimitives<gl::Triangles, FillLayoutVertex, FillAttributes> primitives;
+
+ EXPECT_THROW(
+ primitives.add({
+ FillProgram::layoutVertex({ 0, 0 }),
+ }, {
+ {{ 0, 1, 2 }},
+ }),
+ std::out_of_range
+ );
+}