make vaos immovable

This commit is contained in:
Konstantin Käfer
2015-01-21 12:01:06 +01:00
parent 31a0d18ca1
commit 5503aef690
10 changed files with 111 additions and 100 deletions

View File

@@ -80,7 +80,7 @@ protected:
}
}
pos += itemSize;
return static_cast<char *>(array) + (pos - itemSize);
return reinterpret_cast<char *>(array) + (pos - itemSize);
}
// Get a pointer to the item at a given index.
@@ -92,7 +92,7 @@ protected:
if (i * itemSize >= pos) {
throw new std::runtime_error("Can't get element after array bounds");
} else {
return static_cast<char *>(array) + (i * itemSize);
return reinterpret_cast<char *>(array) + (i * itemSize);
}
}

View File

@@ -21,11 +21,6 @@ struct ElementGroup : public util::noncopyable {
: vertex_length(vertex_length_),
elements_length(elements_length_) {
}
ElementGroup(ElementGroup &&rhs) noexcept
: array(std::move(rhs.array)),
vertex_length(rhs.vertex_length),
elements_length(rhs.elements_length) {};
};
class TriangleElementsBuffer : public Buffer<

View File

@@ -4,6 +4,9 @@
namespace mbgl {
VertexArrayObject::VertexArrayObject() {
}
VertexArrayObject::~VertexArrayObject() {
if (!gl::DeleteVertexArrays) return;

View File

@@ -11,15 +11,8 @@ namespace mbgl {
class VertexArrayObject : public util::noncopyable {
public:
inline VertexArrayObject() {};
inline VertexArrayObject(VertexArrayObject &&rhs) noexcept
: vao(rhs.vao),
bound_shader(rhs.bound_shader),
bound_shader_name(rhs.bound_shader_name),
bound_vertex_buffer(rhs.bound_vertex_buffer),
bound_elements_buffer(rhs.bound_elements_buffer),
bound_offset(rhs.bound_offset) {};
VertexArrayObject();
~VertexArrayObject();
template <typename Shader, typename VertexBuffer>
inline void bind(Shader& shader, VertexBuffer &vertexBuffer, char *offset) {
@@ -50,7 +43,9 @@ public:
}
}
~VertexArrayObject();
inline GLuint getID() const {
return vao;
}
private:
void bindVertexArrayObject();

View File

@@ -6,6 +6,7 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/platform/gl.hpp>
@@ -111,12 +112,13 @@ void FillBucket::tessellate() {
throw geometry_too_long_exception();
}
if (!lineGroups.size() || (lineGroups.back().vertex_length + total_vertex_count > 65535)) {
if (!lineGroups.size() || (lineGroups.back()->vertex_length + total_vertex_count > 65535)) {
// Move to a new group because the old one can't hold the geometry.
lineGroups.emplace_back();
lineGroups.emplace_back(util::make_unique<line_group_type>());
}
line_group_type& lineGroup = lineGroups.back();
assert(lineGroups.back());
line_group_type& lineGroup = *lineGroups.back();
uint32_t lineIndex = lineGroup.vertex_length;
for (const std::vector<ClipperLib::IntPoint>& polygon : polygons) {
@@ -157,14 +159,15 @@ void FillBucket::tessellate() {
}
}
if (!triangleGroups.size() || (triangleGroups.back().vertex_length + total_vertex_count > 65535)) {
if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + total_vertex_count > 65535)) {
// Move to a new group because the old one can't hold the geometry.
triangleGroups.emplace_back();
triangleGroups.emplace_back(util::make_unique<triangle_group_type>());
}
// We're generating triangle fans, so we always start with the first
// coordinate in this polygon.
triangle_group_type& triangleGroup = triangleGroups.back();
assert(triangleGroups.back());
triangle_group_type& triangleGroup = *triangleGroups.back();
uint32_t triangleIndex = triangleGroup.vertex_length;
for (int i = 0; i < triangle_count; ++i) {
@@ -215,32 +218,35 @@ bool FillBucket::hasData() const {
void FillBucket::drawElements(PlainShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
for (triangle_group_type& group : triangleGroups) {
group.array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * vertexBuffer.itemSize;
elements_index += group.elements_length * triangleElementsBuffer.itemSize;
for (auto& group : triangleGroups) {
assert(group);
group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
void FillBucket::drawElements(PatternShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
for (triangle_group_type& group : triangleGroups) {
group.array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * vertexBuffer.itemSize;
elements_index += group.elements_length * triangleElementsBuffer.itemSize;
for (auto& group : triangleGroups) {
assert(group);
group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
void FillBucket::drawVertices(OutlineShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(line_elements_start * lineElementsBuffer.itemSize);
for (line_group_type& group : lineGroups) {
group.array[0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group.elements_length * 2, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * vertexBuffer.itemSize;
elements_index += group.elements_length * lineElementsBuffer.itemSize;
for (auto& group : lineGroups) {
assert(group);
group->array[0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * lineElementsBuffer.itemSize;
}
}

View File

@@ -72,8 +72,8 @@ private:
const size_t line_elements_start;
VertexArrayObject array;
std::vector<triangle_group_type> triangleGroups;
std::vector<line_group_type> lineGroups;
std::vector<std::unique_ptr<triangle_group_type>> triangleGroups;
std::vector<std::unique_ptr<line_group_type>> lineGroups;
std::vector<ClipperLib::IntPoint> line;
bool hasVertices = false;

View File

@@ -7,6 +7,7 @@
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/platform/gl.hpp>
#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
@@ -306,12 +307,13 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
// Store the triangle/line groups.
{
if (!triangleGroups.size() || (triangleGroups.back().vertex_length + vertex_count > 65535)) {
if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) {
// Move to a new group because the old one can't hold the geometry.
triangleGroups.emplace_back();
triangleGroups.emplace_back(util::make_unique<triangle_group_type>());
}
triangle_group_type& group = triangleGroups.back();
assert(triangleGroups.back());
triangle_group_type& group = *triangleGroups.back();
for (const TriangleElement& triangle : triangle_store) {
triangleElementsBuffer.add(
group.vertex_length + triangle.a,
@@ -326,12 +328,13 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
// Store the line join/cap groups.
{
if (!pointGroups.size() || (pointGroups.back().vertex_length + vertex_count > 65535)) {
if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) {
// Move to a new group because the old one can't hold the geometry.
pointGroups.emplace_back();
pointGroups.emplace_back(util::make_unique<point_group_type>());
}
point_group_type& group = pointGroups.back();
assert(pointGroups.back());
point_group_type& group = *pointGroups.back();
for (PointElement point : point_store) {
pointElementsBuffer.add(group.vertex_length + point);
}
@@ -351,8 +354,9 @@ bool LineBucket::hasData() const {
bool LineBucket::hasPoints() const {
if (!pointGroups.empty()) {
for (const point_group_type& group : pointGroups) {
if (group.elements_length) {
for (const auto& group : pointGroups) {
assert(group);
if (group->elements_length) {
return true;
}
}
@@ -363,55 +367,59 @@ bool LineBucket::hasPoints() const {
void LineBucket::drawLines(LineShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
for (triangle_group_type& group : triangleGroups) {
if (!group.elements_length) {
for (auto& group : triangleGroups) {
assert(group);
if (!group->elements_length) {
continue;
}
group.array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * vertexBuffer.itemSize;
elements_index += group.elements_length * triangleElementsBuffer.itemSize;
group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
void LineBucket::drawLineSDF(LineSDFShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
for (triangle_group_type& group : triangleGroups) {
if (!group.elements_length) {
for (auto& group : triangleGroups) {
assert(group);
if (!group->elements_length) {
continue;
}
group.array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * vertexBuffer.itemSize;
elements_index += group.elements_length * triangleElementsBuffer.itemSize;
group->array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
void LineBucket::drawLinePatterns(LinepatternShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
for (triangle_group_type& group : triangleGroups) {
if (!group.elements_length) {
for (auto& group : triangleGroups) {
assert(group);
if (!group->elements_length) {
continue;
}
group.array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * vertexBuffer.itemSize;
elements_index += group.elements_length * triangleElementsBuffer.itemSize;
group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
void LineBucket::drawPoints(LinejoinShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(point_elements_start * pointElementsBuffer.itemSize);
for (point_group_type& group : pointGroups) {
if (!group.elements_length) {
for (auto& group : pointGroups) {
assert(group);
if (!group->elements_length) {
continue;
}
group.array[0].bind(shader, vertexBuffer, pointElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_POINTS, group.elements_length, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * vertexBuffer.itemSize;
elements_index += group.elements_length * pointElementsBuffer.itemSize;
group->array[0].bind(shader, vertexBuffer, pointElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_POINTS, group->elements_length, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * pointElementsBuffer.itemSize;
}
}

View File

@@ -55,8 +55,8 @@ private:
const size_t triangle_elements_start;
const size_t point_elements_start;
std::vector<triangle_group_type> triangleGroups;
std::vector<point_group_type> pointGroups;
std::vector<std::unique_ptr<triangle_group_type>> triangleGroups;
std::vector<std::unique_ptr<point_group_type>> pointGroups;
};
}

View File

@@ -322,19 +322,19 @@ void SymbolBucket::addFeature(const std::vector<Coordinate> &line, const Shaping
collision.insert(glyphPlacement.boxes, anchor, glyphScale, glyphRange,
horizontalText);
}
if (inside) addSymbols(text, glyphPlacement.shapes, glyphScale, glyphRange);
if (inside) addSymbols<TextBuffer, TextElementGroup>(text, glyphPlacement.shapes, glyphScale, glyphRange);
}
if (iconScale && std::isfinite(iconScale)) {
if (!properties.icon.ignore_placement) {
collision.insert(iconPlacement.boxes, anchor, iconScale, iconRange, horizontalIcon);
}
if (inside) addSymbols(icon, iconPlacement.shapes, iconScale, iconRange);
if (inside) addSymbols<IconBuffer, IconElementGroup>(icon, iconPlacement.shapes, iconScale, iconRange);
}
}
}
template <typename Buffer>
template <typename Buffer, typename GroupType>
void SymbolBucket::addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float scale,
PlacementRange placementRange) {
const float zoom = collision.zoom;
@@ -366,14 +366,15 @@ void SymbolBucket::addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float
const int glyph_vertex_length = 4;
if (!buffer.groups.size() ||
(buffer.groups.back().vertex_length + glyph_vertex_length > 65535)) {
(buffer.groups.back()->vertex_length + glyph_vertex_length > 65535)) {
// Move to a new group because the old one can't hold the geometry.
buffer.groups.emplace_back();
buffer.groups.emplace_back(util::make_unique<GroupType>());
}
// We're generating triangle fans, so we always start with the first
// coordinate in this polygon.
auto &triangleGroup = buffer.groups.back();
assert(buffer.groups.back());
auto &triangleGroup = *buffer.groups.back();
uint32_t triangleIndex = triangleGroup.vertex_length;
// coordinates (2 triangles)
@@ -398,33 +399,36 @@ void SymbolBucket::addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float
void SymbolBucket::drawGlyphs(SDFShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
char *elements_index = BUFFER_OFFSET(0);
for (TextElementGroup &group : text.groups) {
group.array[0].bind(shader, text.vertices, text.triangles, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * text.vertices.itemSize;
elements_index += group.elements_length * text.triangles.itemSize;
for (auto &group : text.groups) {
assert(group);
group->array[0].bind(shader, text.vertices, text.triangles, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * text.vertices.itemSize;
elements_index += group->elements_length * text.triangles.itemSize;
}
}
void SymbolBucket::drawIcons(SDFShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
char *elements_index = BUFFER_OFFSET(0);
for (IconElementGroup &group : icon.groups) {
group.array[0].bind(shader, icon.vertices, icon.triangles, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * icon.vertices.itemSize;
elements_index += group.elements_length * icon.triangles.itemSize;
for (auto &group : icon.groups) {
assert(group);
group->array[0].bind(shader, icon.vertices, icon.triangles, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * icon.vertices.itemSize;
elements_index += group->elements_length * icon.triangles.itemSize;
}
}
void SymbolBucket::drawIcons(IconShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
char *elements_index = BUFFER_OFFSET(0);
for (IconElementGroup &group : icon.groups) {
group.array[1].bind(shader, icon.vertices, icon.triangles, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group.vertex_length * icon.vertices.itemSize;
elements_index += group.elements_length * icon.triangles.itemSize;
for (auto &group : icon.groups) {
assert(group);
group->array[1].bind(shader, icon.vertices, icon.triangles, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * icon.vertices.itemSize;
elements_index += group->elements_length * icon.triangles.itemSize;
}
}
}

View File

@@ -81,7 +81,7 @@ private:
// Adds placed items to the buffer.
template <typename Buffer>
template <typename Buffer, typename GroupType>
void addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float scale, PlacementRange placementRange);
// Adds glyphs to the glyph atlas so that they have a left/top/width/height coordinates associated to them that we can use for writing to a buffer.
@@ -95,16 +95,16 @@ public:
private:
Collision &collision;
struct {
struct TextBuffer {
TextVertexBuffer vertices;
TriangleElementsBuffer triangles;
std::vector<TextElementGroup> groups;
std::vector<std::unique_ptr<TextElementGroup>> groups;
} text;
struct {
struct IconBuffer {
IconVertexBuffer vertices;
TriangleElementsBuffer triangles;
std::vector<IconElementGroup> groups;
std::vector<std::unique_ptr<IconElementGroup>> groups;
} icon;
};