diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-07-08 15:41:54 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2016-09-26 11:14:40 +0200 |
commit | afb93d4d3adc9bfb4b3f9b78584e1c2c66c11919 (patch) | |
tree | 8a4c9924a6ff847abab1fdd8dbd6c74874e959ae | |
parent | adcb449ff348a3ae5f74c38824ae43718122dafa (diff) | |
download | qtlocation-mapboxgl-afb93d4d3adc9bfb4b3f9b78584e1c2c66c11919.tar.gz |
[core] track VAOs and Buffers
26 files changed, 214 insertions, 123 deletions
diff --git a/include/mbgl/gl/gl_values.hpp b/include/mbgl/gl/gl_values.hpp index d251e7bf52..e5ad2380d1 100644 --- a/include/mbgl/gl/gl_values.hpp +++ b/include/mbgl/gl/gl_values.hpp @@ -319,5 +319,37 @@ struct BindTexture { } }; +template <GLenum target> +struct BindBuffer { + static_assert(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER, + "target must be one of GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER"); + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBindBuffer(target, value)); + } + static Type Get() { + GLint binding; + MBGL_CHECK_ERROR(glGetIntegerv(target == GL_ARRAY_BUFFER ? GL_ARRAY_BUFFER_BINDING + : GL_ELEMENT_ARRAY_BUFFER_BINDING, + &binding)); + return binding; + } +}; + +template <GLenum target> +const typename BindBuffer<target>::Type BindBuffer<target>::Default; + +struct BindVAO { + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + if (gl::BindVertexArray) { + MBGL_CHECK_ERROR(gl::BindVertexArray(value)); + } + } +}; + + } // namespace gl } // namespace mbgl diff --git a/src/mbgl/geometry/buffer.hpp b/src/mbgl/geometry/buffer.hpp index d372a040bf..f1b493eb41 100644 --- a/src/mbgl/geometry/buffer.hpp +++ b/src/mbgl/geometry/buffer.hpp @@ -2,6 +2,7 @@ #include <mbgl/gl/gl.hpp> #include <mbgl/gl/object_store.hpp> +#include <mbgl/gl/gl_config.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/optional.hpp> @@ -15,11 +16,14 @@ namespace mbgl { template < GLsizei item_size, - GLenum bufferType = GL_ARRAY_BUFFER, + GLenum target = GL_ARRAY_BUFFER, GLsizei defaultLength = 8192, bool retainAfterUpload = false > class Buffer : private util::noncopyable { + static_assert(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER, + "target must be one of GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER"); + public: ~Buffer() { cleanup(); @@ -36,17 +40,24 @@ public: } // Transfers this buffer to the GPU and binds the buffer to the GL context. - void bind(gl::ObjectStore& store) { - if (buffer) { - MBGL_CHECK_ERROR(glBindBuffer(bufferType, *buffer)); - } else { + void bind(gl::ObjectStore& store, gl::Config& config) { + const bool initialized { buffer }; + if (!initialized) { buffer = store.createBuffer(); - MBGL_CHECK_ERROR(glBindBuffer(bufferType, *buffer)); + } + + if (target == GL_ARRAY_BUFFER) { + config.vertexBuffer = *buffer; + } else { + config.elementBuffer = *buffer; + } + + if (!initialized) { if (array == nullptr) { Log::Debug(Event::OpenGL, "Buffer doesn't contain elements"); pos = 0; } - MBGL_CHECK_ERROR(glBufferData(bufferType, pos, array, GL_STATIC_DRAW)); + MBGL_CHECK_ERROR(glBufferData(target, pos, array, GL_STATIC_DRAW)); if (!retainAfterUpload) { cleanup(); } @@ -65,9 +76,9 @@ public: } // Uploads the buffer to the GPU to be available when we need it. - void upload(gl::ObjectStore& store) { + void upload(gl::ObjectStore& store, gl::Config& config) { if (!buffer) { - bind(store); + bind(store, config); } } diff --git a/src/mbgl/geometry/vao.cpp b/src/mbgl/geometry/vao.cpp index 30f5484896..e475f43273 100644 --- a/src/mbgl/geometry/vao.cpp +++ b/src/mbgl/geometry/vao.cpp @@ -5,17 +5,12 @@ namespace mbgl { -void VertexArrayObject::Unbind() { - if (!gl::BindVertexArray) return; - MBGL_CHECK_ERROR(gl::BindVertexArray(0)); -} - VertexArrayObject::VertexArrayObject() { } VertexArrayObject::~VertexArrayObject() = default; -void VertexArrayObject::bindVertexArrayObject(gl::ObjectStore& store) { +void VertexArrayObject::bindVertexArrayObject(gl::ObjectStore& store, gl::Config& config) { if (!gl::GenVertexArrays || !gl::BindVertexArray) { static bool reported = false; if (!reported) { @@ -27,8 +22,11 @@ void VertexArrayObject::bindVertexArrayObject(gl::ObjectStore& store) { if (!vao) { vao = store.createVAO(); + config.vertexBuffer.setDirty(); + config.elementBuffer.setDirty(); } - MBGL_CHECK_ERROR(gl::BindVertexArray(*vao)); + + config.vertexArrayObject = *vao; } void VertexArrayObject::verifyBinding(Shader& shader, GLuint vertexBuffer, GLuint elementsBuffer, diff --git a/src/mbgl/geometry/vao.hpp b/src/mbgl/geometry/vao.hpp index aa0a72ec59..5a2486fae1 100644 --- a/src/mbgl/geometry/vao.hpp +++ b/src/mbgl/geometry/vao.hpp @@ -3,6 +3,7 @@ #include <mbgl/shader/shader.hpp> #include <mbgl/gl/gl.hpp> #include <mbgl/gl/object_store.hpp> +#include <mbgl/gl/gl_config.hpp> #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/optional.hpp> @@ -12,16 +13,18 @@ namespace mbgl { class VertexArrayObject : public util::noncopyable { public: - static void Unbind(); - VertexArrayObject(); ~VertexArrayObject(); template <typename VertexBuffer> - void bind(Shader& shader, VertexBuffer& vertexBuffer, GLbyte* offset, gl::ObjectStore& store) { - bindVertexArrayObject(store); + void bind(Shader& shader, + VertexBuffer& vertexBuffer, + GLbyte* offset, + gl::ObjectStore& store, + gl::Config& config) { + bindVertexArrayObject(store, config); if (bound_shader == 0) { - vertexBuffer.bind(store); + vertexBuffer.bind(store, config); shader.bind(offset); if (vao) { storeBinding(shader, vertexBuffer.getID(), 0, offset); @@ -32,11 +35,16 @@ public: } template <typename VertexBuffer, typename ElementsBuffer> - void bind(Shader& shader, VertexBuffer& vertexBuffer, ElementsBuffer& elementsBuffer, GLbyte* offset, gl::ObjectStore& store) { - bindVertexArrayObject(store); + void bind(Shader& shader, + VertexBuffer& vertexBuffer, + ElementsBuffer& elementsBuffer, + GLbyte* offset, + gl::ObjectStore& store, + gl::Config& config) { + bindVertexArrayObject(store, config); if (bound_shader == 0) { - vertexBuffer.bind(store); - elementsBuffer.bind(store); + vertexBuffer.bind(store, config); + elementsBuffer.bind(store, config); shader.bind(offset); if (vao) { storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset); @@ -51,7 +59,7 @@ public: } private: - void bindVertexArrayObject(gl::ObjectStore&); + void bindVertexArrayObject(gl::ObjectStore&, gl::Config&); void storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset); void verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset); diff --git a/src/mbgl/gl/gl_config.hpp b/src/mbgl/gl/gl_config.hpp index 41bee8fab7..1e0f25a0f3 100644 --- a/src/mbgl/gl/gl_config.hpp +++ b/src/mbgl/gl/gl_config.hpp @@ -70,6 +70,9 @@ public: pixelZoom.reset(); rasterPos.reset(); #endif // GL_ES_VERSION_2_0 + vertexBuffer.reset(); + elementBuffer.reset(); + vertexArrayObject.reset(); } void setDirty() { @@ -95,6 +98,9 @@ public: pixelZoom.setDirty(); rasterPos.setDirty(); #endif // GL_ES_VERSION_2_0 + vertexBuffer.setDirty(); + elementBuffer.setDirty(); + vertexArrayObject.setDirty(); } Value<StencilFunc> stencilFunc; @@ -120,6 +126,9 @@ public: Value<RasterPos> rasterPos; #endif // GL_ES_VERSION_2_0 std::array<Value<BindTexture>, 2> texture; + Value<BindBuffer<GL_ARRAY_BUFFER>> vertexBuffer; + Value<BindBuffer<GL_ELEMENT_ARRAY_BUFFER>> elementBuffer; + Value<BindVAO> vertexArrayObject; }; } // namespace gl diff --git a/src/mbgl/gl/gl_values.cpp b/src/mbgl/gl/gl_values.cpp index 04a3026e24..c987c65aa0 100644 --- a/src/mbgl/gl/gl_values.cpp +++ b/src/mbgl/gl/gl_values.cpp @@ -22,6 +22,7 @@ const constexpr Program::Type Program::Default; const constexpr LineWidth::Type LineWidth::Default; const constexpr ActiveTexture::Type ActiveTexture::Default; const constexpr BindTexture::Type BindTexture::Default; +const constexpr BindVAO::Type BindVAO::Default; #ifndef GL_ES_VERSION_2_0 const constexpr PixelZoom::Type PixelZoom::Default; diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp index 0b5c45ccc2..d330c98d65 100644 --- a/src/mbgl/renderer/circle_bucket.cpp +++ b/src/mbgl/renderer/circle_bucket.cpp @@ -16,9 +16,9 @@ CircleBucket::~CircleBucket() { // Do not remove. header file only contains forward definitions to unique pointers. } -void CircleBucket::upload(gl::ObjectStore& store, gl::Config&) { - vertexBuffer_.upload(store); - elementsBuffer_.upload(store); +void CircleBucket::upload(gl::ObjectStore& store, gl::Config& config) { + vertexBuffer_.upload(store, config); + elementsBuffer_.upload(store, config); uploaded = true; } @@ -82,7 +82,7 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) { } } -void CircleBucket::drawCircles(CircleShader& shader, gl::ObjectStore& store) { +void CircleBucket::drawCircles(CircleShader& shader, gl::ObjectStore& store, gl::Config& config) { GLbyte* vertexIndex = BUFFER_OFFSET(0); GLbyte* elementsIndex = BUFFER_OFFSET(0); @@ -91,7 +91,7 @@ void CircleBucket::drawCircles(CircleShader& shader, gl::ObjectStore& store) { if (!group->elements_length) continue; - group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex, store); + group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elementsIndex)); diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index 617a9e5b24..13ade90bdf 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -25,7 +25,7 @@ public: bool needsClipping() const override; void addGeometry(const GeometryCollection&); - void drawCircles(CircleShader&, gl::ObjectStore&); + void drawCircles(CircleShader&, gl::ObjectStore&, gl::Config&); private: CircleVertexBuffer vertexBuffer_; diff --git a/src/mbgl/renderer/debug_bucket.cpp b/src/mbgl/renderer/debug_bucket.cpp index b4218485b2..6e7f08e6ad 100644 --- a/src/mbgl/renderer/debug_bucket.cpp +++ b/src/mbgl/renderer/debug_bucket.cpp @@ -38,16 +38,16 @@ DebugBucket::DebugBucket(const OverscaledTileID& id, } } -void DebugBucket::drawLines(PlainShader& shader, gl::ObjectStore& store) { +void DebugBucket::drawLines(PlainShader& shader, gl::ObjectStore& store, gl::Config& config) { if (!fontBuffer.empty()) { - array.bind(shader, fontBuffer, BUFFER_OFFSET_0, store); + array.bind(shader, fontBuffer, BUFFER_OFFSET_0, store, config); MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, (GLsizei)(fontBuffer.index()))); } } -void DebugBucket::drawPoints(PlainShader& shader, gl::ObjectStore& store) { +void DebugBucket::drawPoints(PlainShader& shader, gl::ObjectStore& store, gl::Config& config) { if (!fontBuffer.empty()) { - array.bind(shader, fontBuffer, BUFFER_OFFSET_0, store); + array.bind(shader, fontBuffer, BUFFER_OFFSET_0, store, config); MBGL_CHECK_ERROR(glDrawArrays(GL_POINTS, 0, (GLsizei)(fontBuffer.index()))); } } diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp index 7097ae0735..1c8f44c4f1 100644 --- a/src/mbgl/renderer/debug_bucket.hpp +++ b/src/mbgl/renderer/debug_bucket.hpp @@ -12,6 +12,7 @@ class PlainShader; namespace gl { class ObjectStore; +class Config; } // namespace gl class DebugBucket : private util::noncopyable { @@ -23,8 +24,8 @@ public: optional<Timestamp> expires, MapDebugOptions); - void drawLines(PlainShader&, gl::ObjectStore&); - void drawPoints(PlainShader&, gl::ObjectStore&); + void drawLines(PlainShader&, gl::ObjectStore&, gl::Config&); + void drawPoints(PlainShader&, gl::ObjectStore&, gl::Config&); const bool renderable; const bool complete; diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index b92f3184e5..706f063ca0 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -95,10 +95,10 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) { } } -void FillBucket::upload(gl::ObjectStore& store, gl::Config&) { - vertexBuffer.upload(store); - triangleElementsBuffer.upload(store); - lineElementsBuffer.upload(store); +void FillBucket::upload(gl::ObjectStore& store, gl::Config& config) { + vertexBuffer.upload(store, config); + triangleElementsBuffer.upload(store, config); + lineElementsBuffer.upload(store, config); // From now on, we're going to render during the opaque and translucent pass. uploaded = true; @@ -119,13 +119,16 @@ bool FillBucket::needsClipping() const { return true; } -void FillBucket::drawElements(PlainShader& shader, gl::ObjectStore& store, PaintMode paintMode) { +void FillBucket::drawElements(PlainShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { assert(group); group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind( - shader, vertexBuffer, triangleElementsBuffer, vertex_index, store); + shader, vertexBuffer, triangleElementsBuffer, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; @@ -133,13 +136,16 @@ void FillBucket::drawElements(PlainShader& shader, gl::ObjectStore& store, Paint } } -void FillBucket::drawElements(PatternShader& shader, gl::ObjectStore& store, PaintMode paintMode) { +void FillBucket::drawElements(PatternShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { assert(group); group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind( - shader, vertexBuffer, triangleElementsBuffer, vertex_index, store); + shader, vertexBuffer, triangleElementsBuffer, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; @@ -147,13 +153,16 @@ void FillBucket::drawElements(PatternShader& shader, gl::ObjectStore& store, Pai } } -void FillBucket::drawVertices(OutlineShader& shader, gl::ObjectStore& store, PaintMode paintMode) { +void FillBucket::drawVertices(OutlineShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : lineGroups) { assert(group); group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind( - shader, vertexBuffer, lineElementsBuffer, vertex_index, store); + shader, vertexBuffer, lineElementsBuffer, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; @@ -161,13 +170,16 @@ void FillBucket::drawVertices(OutlineShader& shader, gl::ObjectStore& store, Pai } } -void FillBucket::drawVertices(OutlinePatternShader& shader, gl::ObjectStore& store, PaintMode paintMode) { +void FillBucket::drawVertices(OutlinePatternShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : lineGroups) { assert(group); group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind( - shader, vertexBuffer, lineElementsBuffer, vertex_index, store); + shader, vertexBuffer, lineElementsBuffer, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index 135bf3721c..fd28cd83ce 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -27,10 +27,10 @@ public: void addGeometry(const GeometryCollection&); - void drawElements(PlainShader&, gl::ObjectStore&, PaintMode); - void drawElements(PatternShader&, gl::ObjectStore&, PaintMode); - void drawVertices(OutlineShader&, gl::ObjectStore&, PaintMode); - void drawVertices(OutlinePatternShader&, gl::ObjectStore&, PaintMode); + void drawElements(PlainShader&, gl::ObjectStore&, gl::Config&, PaintMode); + void drawElements(PatternShader&, gl::ObjectStore&, gl::Config&, PaintMode); + void drawVertices(OutlineShader&, gl::ObjectStore&, gl::Config&, PaintMode); + void drawVertices(OutlinePatternShader&, gl::ObjectStore&, gl::Config&, PaintMode); private: FillVertexBuffer vertexBuffer; diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index ee8ee66b00..700d334f79 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -437,9 +437,9 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex, } } -void LineBucket::upload(gl::ObjectStore& store, gl::Config&) { - vertexBuffer.upload(store); - triangleElementsBuffer.upload(store); +void LineBucket::upload(gl::ObjectStore& store, gl::Config& config) { + vertexBuffer.upload(store, config); + triangleElementsBuffer.upload(store, config); // From now on, we're only going to render during the translucent pass. uploaded = true; @@ -460,7 +460,10 @@ bool LineBucket::needsClipping() const { return true; } -void LineBucket::drawLines(LineShader& shader, gl::ObjectStore& store, PaintMode paintMode) { +void LineBucket::drawLines(LineShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { @@ -469,7 +472,7 @@ void LineBucket::drawLines(LineShader& shader, gl::ObjectStore& store, PaintMode continue; } group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind( - shader, vertexBuffer, triangleElementsBuffer, vertex_index, store); + shader, vertexBuffer, triangleElementsBuffer, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; @@ -477,7 +480,10 @@ void LineBucket::drawLines(LineShader& shader, gl::ObjectStore& store, PaintMode } } -void LineBucket::drawLineSDF(LineSDFShader& shader, gl::ObjectStore& store, PaintMode paintMode) { +void LineBucket::drawLineSDF(LineSDFShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { @@ -486,7 +492,7 @@ void LineBucket::drawLineSDF(LineSDFShader& shader, gl::ObjectStore& store, Pain continue; } group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind( - shader, vertexBuffer, triangleElementsBuffer, vertex_index, store); + shader, vertexBuffer, triangleElementsBuffer, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; @@ -494,7 +500,10 @@ void LineBucket::drawLineSDF(LineSDFShader& shader, gl::ObjectStore& store, Pain } } -void LineBucket::drawLinePatterns(LinepatternShader& shader, gl::ObjectStore& store, PaintMode paintMode) { +void LineBucket::drawLinePatterns(LinepatternShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { @@ -503,7 +512,7 @@ void LineBucket::drawLinePatterns(LinepatternShader& shader, gl::ObjectStore& st continue; } group->array[paintMode == PaintMode::Overdraw ? 5 : 4].bind( - shader, vertexBuffer, triangleElementsBuffer, vertex_index, store); + shader, vertexBuffer, triangleElementsBuffer, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index d24becdf02..32dd157c65 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -32,9 +32,9 @@ public: void addGeometry(const GeometryCollection&); void addGeometry(const GeometryCoordinates& line); - void drawLines(LineShader&, gl::ObjectStore&, PaintMode); - void drawLineSDF(LineSDFShader&, gl::ObjectStore&, PaintMode); - void drawLinePatterns(LinepatternShader&, gl::ObjectStore&, PaintMode); + void drawLines(LineShader&, gl::ObjectStore&, gl::Config&, PaintMode); + void drawLineSDF(LineSDFShader&, gl::ObjectStore&, gl::Config&, PaintMode); + void drawLinePatterns(LinepatternShader&, gl::ObjectStore&, gl::Config&, PaintMode); private: struct TriangleElement { diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 9822b6b914..5178af004e 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -100,9 +100,9 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a { MBGL_DEBUG_GROUP("upload"); - tileStencilBuffer.upload(store); - rasterBoundsBuffer.upload(store); - tileBorderBuffer.upload(store); + tileStencilBuffer.upload(store, config); + rasterBoundsBuffer.upload(store, config); + tileBorderBuffer.upload(store, config); spriteAtlas->upload(store, config, 0); lineAtlas->upload(store, config, 0); glyphAtlas->upload(store, config, 0); @@ -215,7 +215,7 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a config.activeTexture = 0; config.texture[0] = 0; - MBGL_CHECK_ERROR(VertexArrayObject::Unbind()); + config.vertexArrayObject = 0; } if (frame.contextMode == GLContextMode::Shared) { @@ -263,7 +263,7 @@ void Painter::renderPass(PaintParameters& parameters, renderBackground(parameters, *layer.as<BackgroundLayer>()); } else if (layer.is<CustomLayer>()) { MBGL_DEBUG_GROUP(layer.baseImpl->id + " - custom"); - VertexArrayObject::Unbind(); + config.vertexArrayObject = 0; config.depthFunc.reset(); config.depthTest = GL_TRUE; config.depthMask = GL_FALSE; diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 66ce60ba08..66607c81f0 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -125,7 +125,7 @@ private: float scaleDivisor, std::array<float, 2> texsize, SDFShader& sdfShader, - void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&, PaintMode), + void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&, gl::Config&, PaintMode), // Layout style::AlignmentType rotationAlignment, diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index 48c03fe3f9..942f993f55 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -45,14 +45,14 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye patternShader.u_opacity = properties.backgroundOpacity; spriteAtlas->bind(true, store, config, 0); - arrayBackgroundPattern.bind(patternShader, tileStencilBuffer, BUFFER_OFFSET(0), store); + arrayBackgroundPattern.bind(patternShader, tileStencilBuffer, BUFFER_OFFSET(0), store, config); } else { config.program = plainShader.getID(); plainShader.u_color = properties.backgroundColor; plainShader.u_opacity = properties.backgroundOpacity; - arrayBackground.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET(0), store); + arrayBackground.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET(0), store, config); } config.stencilTest = GL_FALSE; diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index f91370ff22..991ba2d4bc 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -51,7 +51,7 @@ void Painter::renderCircle(PaintParameters& parameters, circleShader.u_blur = properties.circleBlur; circleShader.u_opacity = properties.circleOpacity; - bucket.drawCircles(circleShader, store); + bucket.drawCircles(circleShader, store, config); } } // namespace mbgl diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index 7cb8e01c57..bbef57399a 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -26,7 +26,7 @@ void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<Unwr config.colorMask = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE }; config.stencilMask = mask; - arrayCoveringPlain.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET_0, store); + arrayCoveringPlain.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET_0, store, config); for (const auto& stencil : stencils) { const auto& id = stencil.first; diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp index 7c24f67fb4..8c15070cd5 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -48,18 +48,18 @@ void Painter::renderDebugText(Tile& tile, const mat4 &matrix) { // Draw white outline plainShader.u_color = Color::white(); config.lineWidth = 4.0f * frame.pixelRatio; - tile.debugBucket->drawLines(plainShader, store); + tile.debugBucket->drawLines(plainShader, store, config); #ifndef GL_ES_VERSION_2_0 // Draw line "end caps" MBGL_CHECK_ERROR(glPointSize(2)); - tile.debugBucket->drawPoints(plainShader, store); + tile.debugBucket->drawPoints(plainShader, store, config); #endif // Draw black text. plainShader.u_color = Color::black(); config.lineWidth = 2.0f * frame.pixelRatio; - tile.debugBucket->drawLines(plainShader, store); + tile.debugBucket->drawLines(plainShader, store, config); config.depthFunc.reset(); config.depthTest = GL_TRUE; @@ -81,7 +81,7 @@ void Painter::renderDebugFrame(const mat4 &matrix) { plainShader.u_opacity = 1.0f; // draw tile outline - tileBorderArray.bind(plainShader, tileBorderBuffer, BUFFER_OFFSET_0, store); + tileBorderArray.bind(plainShader, tileBorderBuffer, BUFFER_OFFSET_0, store, config); plainShader.u_color = { 1.0f, 0.0f, 0.0f, 1.0f }; config.lineWidth = 4.0f * frame.pixelRatio; MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index())); diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index 7d952caa12..a948cf1651 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -69,7 +69,7 @@ void Painter::renderFill(PaintParameters& parameters, // the (non-antialiased) fill. setDepthSublayer(0); // OK } - bucket.drawVertices(outlineShader, store, paintMode()); + bucket.drawVertices(outlineShader, store, config, paintMode()); } if (pattern) { @@ -105,7 +105,7 @@ void Painter::renderFill(PaintParameters& parameters, // Draw the actual triangles into the color & stencil buffer. setDepthSublayer(0); - bucket.drawElements(patternShader, store, paintMode()); + bucket.drawElements(patternShader, store, config, paintMode()); if (properties.fillAntialias && !isOutlineColorDefined) { config.program = outlinePatternShader.getID(); @@ -132,7 +132,7 @@ void Painter::renderFill(PaintParameters& parameters, spriteAtlas->bind(true, store, config, 0); setDepthSublayer(2); - bucket.drawVertices(outlinePatternShader, store, paintMode()); + bucket.drawVertices(outlinePatternShader, store, config, paintMode()); } } } else { @@ -149,7 +149,7 @@ void Painter::renderFill(PaintParameters& parameters, // Draw the actual triangles into the color & stencil buffer. setDepthSublayer(1); - bucket.drawElements(plainShader, store, paintMode()); + bucket.drawElements(plainShader, store, config, paintMode()); } } @@ -166,7 +166,7 @@ void Painter::renderFill(PaintParameters& parameters, outlineShader.u_world = worldSize; setDepthSublayer(2); - bucket.drawVertices(outlineShader, store, paintMode()); + bucket.drawVertices(outlineShader, store, config, paintMode()); } } diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index f6afaa7ec3..b93ef6d73d 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -98,7 +98,7 @@ void Painter::renderLine(PaintParameters& parameters, linesdfShader.u_image = 0; lineAtlas->bind(store, config, 0); - bucket.drawLineSDF(linesdfShader, store, paintMode()); + bucket.drawLineSDF(linesdfShader, store, config, paintMode()); } else if (!properties.linePattern.value.from.empty()) { optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition( @@ -141,7 +141,7 @@ void Painter::renderLine(PaintParameters& parameters, linepatternShader.u_image = 0; spriteAtlas->bind(true, store, config, 0); - bucket.drawLinePatterns(linepatternShader, store, paintMode()); + bucket.drawLinePatterns(linepatternShader, store, config, paintMode()); } else { config.program = lineShader.getID(); @@ -159,7 +159,7 @@ void Painter::renderLine(PaintParameters& parameters, lineShader.u_color = color; lineShader.u_opacity = opacity; - bucket.drawLines(lineShader, store, paintMode()); + bucket.drawLines(lineShader, store, config, paintMode()); } } diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 3d886eb4de..2dded27c6c 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -20,7 +20,7 @@ void Painter::renderSDF(SymbolBucket& bucket, float sdfFontSize, std::array<float, 2> texsize, SDFShader& sdfShader, - void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&, PaintMode), + void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&, gl::Config&, PaintMode), // Layout AlignmentType rotationAlignment, @@ -94,7 +94,7 @@ void Painter::renderSDF(SymbolBucket& bucket, sdfShader.u_color = haloColor; sdfShader.u_opacity = opacity; sdfShader.u_buffer = (haloOffset - haloWidth / fontScale) / sdfPx; - (bucket.*drawSDF)(sdfShader, store, paintMode()); + (bucket.*drawSDF)(sdfShader, store, config, paintMode()); } // Then, we draw the text/icon over the halo @@ -103,7 +103,7 @@ void Painter::renderSDF(SymbolBucket& bucket, sdfShader.u_color = color; sdfShader.u_opacity = opacity; sdfShader.u_buffer = (256.0f - 64.0f) / 256.0f; - (bucket.*drawSDF)(sdfShader, store, paintMode()); + (bucket.*drawSDF)(sdfShader, store, config, paintMode()); } } @@ -216,7 +216,7 @@ void Painter::renderSymbol(PaintParameters& parameters, frameHistory.bind(store, config, 1); iconShader.u_fadetexture = 1; - bucket.drawIcons(iconShader, store, paintMode()); + bucket.drawIcons(iconShader, store, config, paintMode()); } } @@ -262,8 +262,7 @@ void Painter::renderSymbol(PaintParameters& parameters, collisionBoxShader.u_maxzoom = (tile.id.canonical.z + 1) * 10; config.lineWidth = 1.0f; - bucket.drawCollisionBoxes(collisionBoxShader, store); - + bucket.drawCollisionBoxes(collisionBoxShader, store, config); } } diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp index 58647a330d..d167f1605b 100644 --- a/src/mbgl/renderer/raster_bucket.cpp +++ b/src/mbgl/renderer/raster_bucket.cpp @@ -32,7 +32,7 @@ void RasterBucket::drawRaster(RasterShader& shader, gl::ObjectStore& store) { raster.bind(store, config, 0, Raster::Scaling::Linear); raster.bind(store, config, 1, Raster::Scaling::Linear); - array.bind(shader, vertices, BUFFER_OFFSET_0, store); + array.bind(shader, vertices, BUFFER_OFFSET_0, store, config); MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)vertices.index())); } diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 2fd1bee951..f7fd34cd84 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -19,14 +19,14 @@ SymbolBucket::SymbolBucket(const MapMode mode_, iconsNeedLinear(iconsNeedLinear_) { } -void SymbolBucket::upload(gl::ObjectStore& store, gl::Config&) { +void SymbolBucket::upload(gl::ObjectStore& store, gl::Config& config) { if (hasTextData()) { - text.vertices.upload(store); - text.triangles.upload(store); + text.vertices.upload(store, config); + text.triangles.upload(store, config); } if (hasIconData()) { - icon.vertices.upload(store); - icon.triangles.upload(store); + icon.vertices.upload(store, config); + icon.triangles.upload(store, config); } uploaded = true; @@ -60,13 +60,16 @@ bool SymbolBucket::needsClipping() const { return mode == MapMode::Still; } -void SymbolBucket::drawGlyphs(SDFShader& shader, gl::ObjectStore& store, PaintMode paintMode) { - GLbyte *vertex_index = BUFFER_OFFSET_0; - GLbyte *elements_index = BUFFER_OFFSET_0; - for (auto &group : text.groups) { +void SymbolBucket::drawGlyphs(SDFShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { + GLbyte* vertex_index = BUFFER_OFFSET_0; + GLbyte* elements_index = BUFFER_OFFSET_0; + for (auto& group : text.groups) { assert(group); group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind( - shader, text.vertices, text.triangles, vertex_index, store); + shader, text.vertices, text.triangles, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * text.vertices.itemSize; @@ -74,13 +77,16 @@ void SymbolBucket::drawGlyphs(SDFShader& shader, gl::ObjectStore& store, PaintMo } } -void SymbolBucket::drawIcons(SDFShader& shader, gl::ObjectStore& store, PaintMode paintMode) { - GLbyte *vertex_index = BUFFER_OFFSET_0; - GLbyte *elements_index = BUFFER_OFFSET_0; - for (auto &group : icon.groups) { +void SymbolBucket::drawIcons(SDFShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { + GLbyte* vertex_index = BUFFER_OFFSET_0; + GLbyte* elements_index = BUFFER_OFFSET_0; + for (auto& group : icon.groups) { assert(group); group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind( - shader, icon.vertices, icon.triangles, vertex_index, store); + shader, icon.vertices, icon.triangles, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * icon.vertices.itemSize; @@ -88,13 +94,16 @@ void SymbolBucket::drawIcons(SDFShader& shader, gl::ObjectStore& store, PaintMod } } -void SymbolBucket::drawIcons(IconShader& shader, gl::ObjectStore& store, PaintMode paintMode) { - GLbyte *vertex_index = BUFFER_OFFSET_0; - GLbyte *elements_index = BUFFER_OFFSET_0; - for (auto &group : icon.groups) { +void SymbolBucket::drawIcons(IconShader& shader, + gl::ObjectStore& store, + gl::Config& config, + PaintMode paintMode) { + GLbyte* vertex_index = BUFFER_OFFSET_0; + GLbyte* elements_index = BUFFER_OFFSET_0; + for (auto& group : icon.groups) { assert(group); group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind( - shader, icon.vertices, icon.triangles, vertex_index, store); + shader, icon.vertices, icon.triangles, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * icon.vertices.itemSize; @@ -102,10 +111,12 @@ void SymbolBucket::drawIcons(IconShader& shader, gl::ObjectStore& store, PaintMo } } -void SymbolBucket::drawCollisionBoxes(CollisionBoxShader& shader, gl::ObjectStore& store) { - GLbyte *vertex_index = BUFFER_OFFSET_0; - for (auto &group : collisionBox.groups) { - group->array[0].bind(shader, collisionBox.vertices, vertex_index, store); +void SymbolBucket::drawCollisionBoxes(CollisionBoxShader& shader, + gl::ObjectStore& store, + gl::Config& config) { + GLbyte* vertex_index = BUFFER_OFFSET_0; + for (auto& group : collisionBox.groups) { + group->array[0].bind(shader, collisionBox.vertices, vertex_index, store, config); MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, group->vertex_length)); } } diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index ad53cd6630..5384979ebe 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -33,10 +33,10 @@ public: bool hasCollisionBoxData() const; bool needsClipping() const override; - void drawGlyphs(SDFShader&, gl::ObjectStore&, PaintMode); - void drawIcons(SDFShader&, gl::ObjectStore&, PaintMode); - void drawIcons(IconShader&, gl::ObjectStore&, PaintMode); - void drawCollisionBoxes(CollisionBoxShader&, gl::ObjectStore&); + void drawGlyphs(SDFShader&, gl::ObjectStore&, gl::Config&, PaintMode); + void drawIcons(SDFShader&, gl::ObjectStore&, gl::Config&, PaintMode); + void drawIcons(IconShader&, gl::ObjectStore&, gl::Config&, PaintMode); + void drawCollisionBoxes(CollisionBoxShader&, gl::ObjectStore&, gl::Config&); const MapMode mode; const style::SymbolLayoutProperties layout; |