diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-02-18 11:19:24 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-02-18 15:15:24 -0800 |
commit | 9c26f063187b129218910dbb86eb21215a2cdf40 (patch) | |
tree | 189f84f90cef341a0a084fefde40f4f07da117cb /src | |
parent | 7b39ce95210ceb6640b3a3399dacd1d0e826ac1f (diff) | |
download | qtlocation-mapboxgl-9c26f063187b129218910dbb86eb21215a2cdf40.tar.gz |
[core] Thread GLObjectStore through to Holder objects
This eliminates the reliance on ThreadContext to provide GLObjectStore, and statically enforces that GL cleanup functions happen only when GLObjectStore::performCleanup is called.
With the elimination of the Map thread, this becomes important because there may be multiple GLObjectStore's per-thread, and Map will need to ensure that the correct context is active when calling GLObjectStore::performCleanup.
Diffstat (limited to 'src')
66 files changed, 313 insertions, 321 deletions
diff --git a/src/mbgl/geometry/buffer.hpp b/src/mbgl/geometry/buffer.hpp index a84af91e2e..143597ed0a 100644 --- a/src/mbgl/geometry/buffer.hpp +++ b/src/mbgl/geometry/buffer.hpp @@ -24,9 +24,6 @@ class Buffer : private util::noncopyable { public: ~Buffer() { cleanup(); - if (buffer) { - util::ThreadContext::getGLObjectStore()->abandon(std::move(buffer)); - } } // Returns the number of elements in this buffer. This is not the number of @@ -40,11 +37,11 @@ public: } // Transfers this buffer to the GPU and binds the buffer to the GL context. - void bind() { + void bind(gl::GLObjectStore& glObjectStore) { if (buffer) { MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID())); } else { - buffer.create(); + buffer.create(glObjectStore); MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID())); if (array == nullptr) { Log::Debug(Event::OpenGL, "Buffer doesn't contain elements"); @@ -69,9 +66,9 @@ public: } // Uploads the buffer to the GPU to be available when we need it. - inline void upload() { + inline void upload(gl::GLObjectStore& glObjectStore) { if (!buffer) { - bind(); + bind(glObjectStore); } } diff --git a/src/mbgl/geometry/glyph_atlas.cpp b/src/mbgl/geometry/glyph_atlas.cpp index a5e07f2523..24c1b8c8db 100644 --- a/src/mbgl/geometry/glyph_atlas.cpp +++ b/src/mbgl/geometry/glyph_atlas.cpp @@ -146,10 +146,10 @@ void GlyphAtlas::removeGlyphs(uintptr_t tileUID) { } } -void GlyphAtlas::upload() { +void GlyphAtlas::upload(gl::GLObjectStore& glObjectStore) { if (dirty) { const bool first = !texture; - bind(); + bind(glObjectStore); std::lock_guard<std::mutex> lock(mtx); @@ -187,9 +187,9 @@ void GlyphAtlas::upload() { } } -void GlyphAtlas::bind() { +void GlyphAtlas::bind(gl::GLObjectStore& glObjectStore) { if (!texture) { - texture.create(); + texture.create(glObjectStore); MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); #ifndef GL_ES_VERSION_2_0 MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); diff --git a/src/mbgl/geometry/glyph_atlas.hpp b/src/mbgl/geometry/glyph_atlas.hpp index c123d01133..2758ac7cee 100644 --- a/src/mbgl/geometry/glyph_atlas.hpp +++ b/src/mbgl/geometry/glyph_atlas.hpp @@ -28,11 +28,11 @@ public: void removeGlyphs(uintptr_t tileUID); // Binds the atlas texture to the GPU, and uploads data if it is out of date. - void bind(); + void bind(gl::GLObjectStore&); // Uploads the texture to the GPU to be available when we need it. This is a lazy operation; // the texture is only bound when the data is out of date (=dirty). - void upload(); + void upload(gl::GLObjectStore&); const GLsizei width; const GLsizei height; diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp index 6163306dc9..9b133319dc 100644 --- a/src/mbgl/geometry/line_atlas.cpp +++ b/src/mbgl/geometry/line_atlas.cpp @@ -23,7 +23,7 @@ LineAtlas::~LineAtlas() { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); } -LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, bool round) { +LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, bool round, gl::GLObjectStore& glObjectStore) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); size_t key = round ? std::numeric_limits<size_t>::min() : std::numeric_limits<size_t>::max(); @@ -34,7 +34,7 @@ LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, b // Note: We're not handling hash collisions here. const auto it = positions.find(key); if (it == positions.end()) { - auto inserted = positions.emplace(key, addDash(dasharray, round)); + auto inserted = positions.emplace(key, addDash(dasharray, round, glObjectStore)); assert(inserted.second); return inserted.first->second; } else { @@ -42,7 +42,7 @@ LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, b } } -LinePatternPos LineAtlas::addDash(const std::vector<float> &dasharray, bool round) { +LinePatternPos LineAtlas::addDash(const std::vector<float> &dasharray, bool round, gl::GLObjectStore& glObjectStore) { int n = round ? 7 : 0; int dashheight = 2 * n + 1; @@ -120,23 +120,23 @@ LinePatternPos LineAtlas::addDash(const std::vector<float> &dasharray, bool roun nextRow += dashheight; dirty = true; - bind(); + bind(glObjectStore); return position; }; -void LineAtlas::upload() { +void LineAtlas::upload(gl::GLObjectStore& glObjectStore) { if (dirty) { - bind(); + bind(glObjectStore); } } -void LineAtlas::bind() { +void LineAtlas::bind(gl::GLObjectStore& glObjectStore) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); bool first = false; if (!texture) { - texture.create(); + texture.create(glObjectStore); MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); diff --git a/src/mbgl/geometry/line_atlas.hpp b/src/mbgl/geometry/line_atlas.hpp index 0e6e14ff54..e94b399457 100644 --- a/src/mbgl/geometry/line_atlas.hpp +++ b/src/mbgl/geometry/line_atlas.hpp @@ -21,14 +21,14 @@ public: ~LineAtlas(); // Binds the atlas texture to the GPU, and uploads data if it is out of date. - void bind(); + void bind(gl::GLObjectStore&); // Uploads the texture to the GPU to be available when we need it. This is a lazy operation; // the texture is only bound when the data is out of date (=dirty). - void upload(); + void upload(gl::GLObjectStore&); - LinePatternPos getDashPosition(const std::vector<float>&, bool); - LinePatternPos addDash(const std::vector<float> &dasharray, bool round); + LinePatternPos getDashPosition(const std::vector<float>&, bool, gl::GLObjectStore&); + LinePatternPos addDash(const std::vector<float> &dasharray, bool round, gl::GLObjectStore&); const GLsizei width; const GLsizei height; diff --git a/src/mbgl/geometry/vao.cpp b/src/mbgl/geometry/vao.cpp index 964ac31a2f..8239604264 100644 --- a/src/mbgl/geometry/vao.cpp +++ b/src/mbgl/geometry/vao.cpp @@ -2,7 +2,6 @@ #include <mbgl/platform/log.hpp> #include <mbgl/gl/gl_object_store.hpp> #include <mbgl/util/string.hpp> -#include <mbgl/util/thread_context.hpp> namespace mbgl { @@ -15,10 +14,9 @@ VertexArrayObject::VertexArrayObject() { } VertexArrayObject::~VertexArrayObject() { - if (vao) util::ThreadContext::getGLObjectStore()->abandon(std::move(vao)); } -void VertexArrayObject::bindVertexArrayObject() { +void VertexArrayObject::bindVertexArrayObject(gl::GLObjectStore& glObjectStore) { if (!gl::GenVertexArrays || !gl::BindVertexArray) { static bool reported = false; if (!reported) { @@ -28,7 +26,7 @@ void VertexArrayObject::bindVertexArrayObject() { return; } - if (!vao) vao.create(); + if (!vao) vao.create(glObjectStore); MBGL_CHECK_ERROR(gl::BindVertexArray(vao.getID())); } diff --git a/src/mbgl/geometry/vao.hpp b/src/mbgl/geometry/vao.hpp index cab258cb5c..dcb66dd41d 100644 --- a/src/mbgl/geometry/vao.hpp +++ b/src/mbgl/geometry/vao.hpp @@ -20,10 +20,10 @@ public: ~VertexArrayObject(); template <typename Shader, typename VertexBuffer> - inline void bind(Shader& shader, VertexBuffer &vertexBuffer, GLbyte *offset) { - bindVertexArrayObject(); + inline void bind(Shader& shader, VertexBuffer &vertexBuffer, GLbyte *offset, gl::GLObjectStore& glObjectStore) { + bindVertexArrayObject(glObjectStore); if (bound_shader == 0) { - vertexBuffer.bind(); + vertexBuffer.bind(glObjectStore); shader.bind(offset); if (vao) { storeBinding(shader, vertexBuffer.getID(), 0, offset); @@ -34,11 +34,11 @@ public: } template <typename Shader, typename VertexBuffer, typename ElementsBuffer> - inline void bind(Shader& shader, VertexBuffer &vertexBuffer, ElementsBuffer &elementsBuffer, GLbyte *offset) { - bindVertexArrayObject(); + inline void bind(Shader& shader, VertexBuffer &vertexBuffer, ElementsBuffer &elementsBuffer, GLbyte *offset, gl::GLObjectStore& glObjectStore) { + bindVertexArrayObject(glObjectStore); if (bound_shader == 0) { - vertexBuffer.bind(); - elementsBuffer.bind(); + vertexBuffer.bind(glObjectStore); + elementsBuffer.bind(glObjectStore); shader.bind(offset); if (vao) { storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset); @@ -53,7 +53,7 @@ public: } private: - void bindVertexArrayObject(); + void bindVertexArrayObject(gl::GLObjectStore&); 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_object_store.cpp b/src/mbgl/gl/gl_object_store.cpp index 62d92f3100..4948e20694 100644 --- a/src/mbgl/gl/gl_object_store.cpp +++ b/src/mbgl/gl/gl_object_store.cpp @@ -1,115 +1,119 @@ #include <mbgl/gl/gl_object_store.hpp> -#include <mbgl/util/thread_context.hpp> #include <cassert> namespace mbgl { namespace gl { -void ProgramHolder::create() { +void ProgramHolder::create(GLObjectStore& objectStore_) { if (id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + objectStore = &objectStore_; id = MBGL_CHECK_ERROR(glCreateProgram()); } void ProgramHolder::reset() { if (!id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - MBGL_CHECK_ERROR(glDeleteProgram(id)); + objectStore->abandonedPrograms.push_back(id); id = 0; } -void ShaderHolder::create() { +void ShaderHolder::create(GLObjectStore& objectStore_) { if (id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + objectStore = &objectStore_; id = MBGL_CHECK_ERROR(glCreateShader(type)); } void ShaderHolder::reset() { if (!id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - MBGL_CHECK_ERROR(glDeleteShader(id)); + objectStore->abandonedShaders.push_back(id); id = 0; } -void BufferHolder::create() { +void BufferHolder::create(GLObjectStore& objectStore_) { if (id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + objectStore = &objectStore_; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); } void BufferHolder::reset() { if (!id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - MBGL_CHECK_ERROR(glDeleteBuffers(1, &id)); + objectStore->abandonedBuffers.push_back(id); id = 0; } -void TextureHolder::create() { +void TextureHolder::create(GLObjectStore& objectStore_) { if (id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + objectStore = &objectStore_; MBGL_CHECK_ERROR(glGenTextures(1, &id)); } void TextureHolder::reset() { if (!id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - MBGL_CHECK_ERROR(glDeleteTextures(1, &id)); + objectStore->abandonedTextures.push_back(id); id = 0; } -void TexturePoolHolder::create() { +void TexturePoolHolder::create(GLObjectStore& objectStore_) { if (bool()) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + objectStore = &objectStore_; MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data())); } void TexturePoolHolder::reset() { if (!bool()) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - MBGL_CHECK_ERROR(glDeleteTextures(TextureMax, ids.data())); + for (GLuint id : ids) { + if (id) { + objectStore->abandonedTextures.push_back(id); + } + } ids.fill(0); } -void VAOHolder::create() { +void VAOHolder::create(GLObjectStore& objectStore_) { if (id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + objectStore = &objectStore_; MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id)); } void VAOHolder::reset() { if (!id) return; - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - MBGL_CHECK_ERROR(gl::DeleteVertexArrays(1, &id)); + objectStore->abandonedVAOs.push_back(id); id = 0; } -void GLObjectStore::abandon(BufferHolder&& buffer) { - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - abandonedBuffers.push_back(std::move(buffer)); -} - -void GLObjectStore::abandon(TextureHolder&& texture) { - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - abandonedTextures.push_back(std::move(texture)); -} - -void GLObjectStore::abandon(TexturePoolHolder&& texture) { - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - abandonedTexturePools.push_back(std::move(texture)); -} - -void GLObjectStore::abandon(VAOHolder&& vao) { - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - abandonedVAOs.push_back(std::move(vao)); +GLObjectStore::~GLObjectStore() { + assert(abandonedPrograms.empty()); + assert(abandonedShaders.empty()); + assert(abandonedBuffers.empty()); + assert(abandonedTextures.empty()); + assert(abandonedVAOs.empty()); } void GLObjectStore::performCleanup() { - assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - abandonedBuffers.clear(); - abandonedTextures.clear(); - abandonedTexturePools.clear(); - abandonedVAOs.clear(); + for (GLuint id : abandonedPrograms) { + MBGL_CHECK_ERROR(glDeleteProgram(id)); + } + abandonedPrograms.clear(); + + for (GLuint id : abandonedShaders) { + MBGL_CHECK_ERROR(glDeleteShader(id)); + } + abandonedShaders.clear(); + + if (!abandonedBuffers.empty()) { + MBGL_CHECK_ERROR(glDeleteBuffers(int(abandonedBuffers.size()), abandonedBuffers.data())); + abandonedBuffers.clear(); + } + + if (!abandonedTextures.empty()) { + MBGL_CHECK_ERROR(glDeleteTextures(int(abandonedTextures.size()), abandonedTextures.data())); + abandonedTextures.clear(); + } + + if (!abandonedVAOs.empty()) { + MBGL_CHECK_ERROR(gl::DeleteVertexArrays(int(abandonedVAOs.size()), abandonedVAOs.data())); + abandonedVAOs.clear(); + } } } // namespace gl diff --git a/src/mbgl/gl/gl_object_store.hpp b/src/mbgl/gl/gl_object_store.hpp index 684400d443..832f1d09b3 100644 --- a/src/mbgl/gl/gl_object_store.hpp +++ b/src/mbgl/gl/gl_object_store.hpp @@ -12,6 +12,29 @@ namespace mbgl { namespace gl { +class GLObjectStore : private util::noncopyable { +public: + ~GLObjectStore(); + + // Actually remove the objects we marked as abandoned with the above methods. + // Only call this while the OpenGL context is exclusive to this thread. + void performCleanup(); + +private: + friend class ProgramHolder; + friend class ShaderHolder; + friend class BufferHolder; + friend class TextureHolder; + friend class TexturePoolHolder; + friend class VAOHolder; + + std::vector<GLuint> abandonedPrograms; + std::vector<GLuint> abandonedShaders; + std::vector<GLuint> abandonedBuffers; + std::vector<GLuint> abandonedTextures; + std::vector<GLuint> abandonedVAOs; +}; + class GLHolder : private util::noncopyable { public: GLHolder() {} @@ -24,6 +47,7 @@ public: protected: GLuint id = 0; + GLObjectStore* objectStore = nullptr; }; class ProgramHolder : public GLHolder { @@ -34,7 +58,7 @@ public: ProgramHolder(ProgramHolder&& o) noexcept : GLHolder(std::move(o)) {} ProgramHolder& operator=(ProgramHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; } - void create(); + void create(GLObjectStore&); void reset(); }; @@ -46,7 +70,7 @@ public: ShaderHolder(ShaderHolder&& o) noexcept : GLHolder(std::move(o)), type(o.type) {} ShaderHolder& operator=(ShaderHolder&& o) noexcept { GLHolder::operator=(std::move(o)); type = o.type; return *this; } - void create(); + void create(GLObjectStore&); void reset(); private: @@ -61,7 +85,7 @@ public: BufferHolder(BufferHolder&& o) noexcept : GLHolder(std::move(o)) {} BufferHolder& operator=(BufferHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; } - void create(); + void create(GLObjectStore&); void reset(); }; @@ -73,7 +97,7 @@ public: TextureHolder(TextureHolder&& o) noexcept : GLHolder(std::move(o)) {} TextureHolder& operator=(TextureHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; } - void create(); + void create(GLObjectStore&); void reset(); }; @@ -91,11 +115,12 @@ public: const std::array<GLuint, TextureMax>& getIDs() const { return ids; } const GLuint& operator[](size_t pos) { return ids[pos]; } - void create(); + void create(GLObjectStore&); void reset(); private: std::array<GLuint, TextureMax> ids; + GLObjectStore* objectStore = nullptr; }; class VAOHolder : public GLHolder { @@ -106,31 +131,10 @@ public: VAOHolder(VAOHolder&& o) noexcept : GLHolder(std::move(o)) {} VAOHolder& operator=(VAOHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; } - void create(); + void create(GLObjectStore&); void reset(); }; -class GLObjectStore : private util::noncopyable { -public: - // Mark OpenGL objects for deletion - void abandon(VAOHolder&&); - void abandon(BufferHolder&&); - void abandon(TextureHolder&&); - void abandon(TexturePoolHolder&&); - - // Actually remove the objects we marked as abandoned with the above methods. - // Only call this while the OpenGL context is exclusive to this thread. - void performCleanup(); - -private: - // We split the holder objects in separate containers because each - // GLHolder-derived object can vary in size. - std::vector<VAOHolder> abandonedVAOs; - std::vector<BufferHolder> abandonedBuffers; - std::vector<TextureHolder> abandonedTextures; - std::vector<TexturePoolHolder> abandonedTexturePools; -}; - } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp index edde485374..a875f4d579 100644 --- a/src/mbgl/gl/texture_pool.cpp +++ b/src/mbgl/gl/texture_pool.cpp @@ -1,15 +1,12 @@ #include <mbgl/gl/texture_pool.hpp> #include <mbgl/gl/gl_object_store.hpp> -#include <mbgl/util/thread_context.hpp> #include <vector> namespace mbgl { namespace gl { -GLuint TexturePool::getTextureID() { - if (pools.empty()) pools.emplace_back(); - +GLuint TexturePool::getTextureID(gl::GLObjectStore& glObjectStore) { for (auto& impl : pools) { if (impl.ids.empty()) continue; auto it = impl.ids.begin(); @@ -19,7 +16,7 @@ GLuint TexturePool::getTextureID() { } // All texture IDs are in use. - pools.emplace_back(); + pools.emplace_back(Impl(glObjectStore)); auto it = pools.back().ids.begin(); GLuint id = *it; pools.back().ids.erase(it); @@ -32,7 +29,6 @@ void TexturePool::releaseTextureID(GLuint id) { if (it->pool[i] == id) { it->ids.push_back(id); if (GLsizei(it->ids.size()) == gl::TexturePoolHolder::TextureMax) { - util::ThreadContext::getGLObjectStore()->abandon(std::move(it->pool)); pools.erase(it); } return; diff --git a/src/mbgl/gl/texture_pool.hpp b/src/mbgl/gl/texture_pool.hpp index 0992b8398d..10f63bfac9 100644 --- a/src/mbgl/gl/texture_pool.hpp +++ b/src/mbgl/gl/texture_pool.hpp @@ -14,14 +14,14 @@ namespace gl { class TexturePool : private util::noncopyable { public: - GLuint getTextureID(); + GLuint getTextureID(gl::GLObjectStore&); void releaseTextureID(GLuint); private: class Impl : private util::noncopyable { public: - Impl() : ids(gl::TexturePoolHolder::TextureMax) { - pool.create(); + Impl(gl::GLObjectStore& glObjectStore) : ids(gl::TexturePoolHolder::TextureMax) { + pool.create(glObjectStore); std::copy(pool.getIDs().begin(), pool.getIDs().end(), ids.begin()); } diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index a4c6abdb21..f9397d4f78 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -38,8 +38,6 @@ MapContext::MapContext(View& view_, FileSource& fileSource_, MapMode mode_, GLCo texturePool(std::make_unique<gl::TexturePool>()) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - util::ThreadContext::setGLObjectStore(&glObjectStore); - view.activate(); } @@ -238,7 +236,7 @@ bool MapContext::renderSync(const TransformState& state, const FrameData& frame) // Cleanup OpenGL objects that we abandoned since the last render call. glObjectStore.performCleanup(); - if (!painter) painter = std::make_unique<Painter>(data, transformState); + if (!painter) painter = std::make_unique<Painter>(data, transformState, glObjectStore); painter->render(*style, frame, data.getAnnotationManager()->getSpriteAtlas()); if (data.mode == MapMode::Still) { diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index e50345d0eb..85f97688dd 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -18,13 +18,17 @@ class StyleLayer; class TileID; class CollisionTile; +namespace gl { +class GLObjectStore; +} + class Bucket : private util::noncopyable { public: Bucket() : uploaded(false) {} // As long as this bucket has a Prepare render pass, this function is getting called. Typically, // this only happens once when the bucket is being rendered for the first time. - virtual void upload() = 0; + virtual void upload(gl::GLObjectStore&) = 0; // Every time this bucket is getting rendered, this function is called. This happens either // once or twice (for Opaque and Transparent render passes). diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp index 1ebe8ffaf3..fcead38c33 100644 --- a/src/mbgl/renderer/circle_bucket.cpp +++ b/src/mbgl/renderer/circle_bucket.cpp @@ -14,9 +14,9 @@ CircleBucket::~CircleBucket() { // Do not remove. header file only contains forward definitions to unique pointers. } -void CircleBucket::upload() { - vertexBuffer_.upload(); - elementsBuffer_.upload(); +void CircleBucket::upload(gl::GLObjectStore& glObjectStore) { + vertexBuffer_.upload(glObjectStore); + elementsBuffer_.upload(glObjectStore); uploaded = true; } @@ -73,7 +73,7 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) { } } -void CircleBucket::drawCircles(CircleShader& shader) { +void CircleBucket::drawCircles(CircleShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte* vertexIndex = BUFFER_OFFSET(0); GLbyte* elementsIndex = BUFFER_OFFSET(0); @@ -82,7 +82,7 @@ void CircleBucket::drawCircles(CircleShader& shader) { if (!group->elements_length) continue; - group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex); + group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex, glObjectStore); 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 d098a7a686..875e5bb4a9 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -20,13 +20,13 @@ public: CircleBucket(); ~CircleBucket() override; - void upload() override; + void upload(gl::GLObjectStore&) override; void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; bool hasData() const override; void addGeometry(const GeometryCollection&); - void drawCircles(CircleShader& shader); + void drawCircles(CircleShader&, gl::GLObjectStore&); private: CircleVertexBuffer vertexBuffer_; diff --git a/src/mbgl/renderer/debug_bucket.cpp b/src/mbgl/renderer/debug_bucket.cpp index 909316a343..947783ddb8 100644 --- a/src/mbgl/renderer/debug_bucket.cpp +++ b/src/mbgl/renderer/debug_bucket.cpp @@ -30,12 +30,12 @@ DebugBucket::DebugBucket(const TileID id, const TileData::State state_, optional } } -void DebugBucket::drawLines(PlainShader& shader) { - array.bind(shader, fontBuffer, BUFFER_OFFSET_0); +void DebugBucket::drawLines(PlainShader& shader, gl::GLObjectStore& glObjectStore) { + array.bind(shader, fontBuffer, BUFFER_OFFSET_0, glObjectStore); MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, (GLsizei)(fontBuffer.index()))); } -void DebugBucket::drawPoints(PlainShader& shader) { - array.bind(shader, fontBuffer, BUFFER_OFFSET_0); +void DebugBucket::drawPoints(PlainShader& shader, gl::GLObjectStore& glObjectStore) { + array.bind(shader, fontBuffer, BUFFER_OFFSET_0, glObjectStore); 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 9338f65157..f12452751c 100644 --- a/src/mbgl/renderer/debug_bucket.hpp +++ b/src/mbgl/renderer/debug_bucket.hpp @@ -11,6 +11,10 @@ namespace mbgl { class PlainShader; +namespace util { +class GLObjectStore; +} + class DebugBucket : private util::noncopyable { public: DebugBucket(TileID id, TileData::State, @@ -18,8 +22,8 @@ public: optional<SystemTimePoint> expires, MapDebugOptions); - void drawLines(PlainShader& shader); - void drawPoints(PlainShader& shader); + void drawLines(PlainShader&, gl::GLObjectStore&); + void drawPoints(PlainShader&, gl::GLObjectStore&); const TileData::State state; const optional<SystemTimePoint> modified; diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index a8b63f58dd..d3a4bc2b57 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -186,10 +186,10 @@ void FillBucket::tessellate() { lineGroup.vertex_length += total_vertex_count; } -void FillBucket::upload() { - vertexBuffer.upload(); - triangleElementsBuffer.upload(); - lineElementsBuffer.upload(); +void FillBucket::upload(gl::GLObjectStore& glObjectStore) { + vertexBuffer.upload(glObjectStore); + triangleElementsBuffer.upload(glObjectStore); + lineElementsBuffer.upload(glObjectStore); // From now on, we're going to render during the opaque and translucent pass. uploaded = true; @@ -206,36 +206,36 @@ bool FillBucket::hasData() const { return !triangleGroups.empty() || !lineGroups.empty(); } -void FillBucket::drawElements(PlainShader& shader) { +void FillBucket::drawElements(PlainShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { assert(group); - group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); + group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore); 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) { +void FillBucket::drawElements(PatternShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { assert(group); - group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); + group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore); 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) { +void FillBucket::drawVertices(OutlineShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : lineGroups) { assert(group); - group->array[0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index); + group->array[0].bind(shader, vertexBuffer, lineElementsBuffer, vertex_index, glObjectStore); 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; diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index 9b2022af50..b3b46f030b 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -32,16 +32,16 @@ public: FillBucket(); ~FillBucket() override; - void upload() override; + void upload(gl::GLObjectStore&) override; void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; bool hasData() const override; void addGeometry(const GeometryCollection&); void tessellate(); - void drawElements(PlainShader& shader); - void drawElements(PatternShader& shader); - void drawVertices(OutlineShader& shader); + void drawElements(PlainShader&, gl::GLObjectStore&); + void drawElements(PatternShader&, gl::GLObjectStore&); + void drawVertices(OutlineShader&, gl::GLObjectStore&); private: TESSalloc *allocator; diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 51b735daa0..ba50e6b1f0 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -418,9 +418,9 @@ void LineBucket::addPieSliceVertex(const Coordinate& currentVertex, } } -void LineBucket::upload() { - vertexBuffer.upload(); - triangleElementsBuffer.upload(); +void LineBucket::upload(gl::GLObjectStore& glObjectStore) { + vertexBuffer.upload(glObjectStore); + triangleElementsBuffer.upload(glObjectStore); // From now on, we're only going to render during the translucent pass. uploaded = true; @@ -437,7 +437,7 @@ bool LineBucket::hasData() const { return !triangleGroups.empty(); } -void LineBucket::drawLines(LineShader& shader) { +void LineBucket::drawLines(LineShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { @@ -445,7 +445,7 @@ void LineBucket::drawLines(LineShader& shader) { if (!group->elements_length) { continue; } - group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); + group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; @@ -453,7 +453,7 @@ void LineBucket::drawLines(LineShader& shader) { } } -void LineBucket::drawLineSDF(LineSDFShader& shader) { +void LineBucket::drawLineSDF(LineSDFShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { @@ -461,7 +461,7 @@ void LineBucket::drawLineSDF(LineSDFShader& shader) { if (!group->elements_length) { continue; } - group->array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); + group->array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore); MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; @@ -469,7 +469,7 @@ void LineBucket::drawLineSDF(LineSDFShader& shader) { } } -void LineBucket::drawLinePatterns(LinepatternShader& shader) { +void LineBucket::drawLinePatterns(LinepatternShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte* vertex_index = BUFFER_OFFSET(0); GLbyte* elements_index = BUFFER_OFFSET(0); for (auto& group : triangleGroups) { @@ -477,7 +477,7 @@ void LineBucket::drawLinePatterns(LinepatternShader& shader) { if (!group->elements_length) { continue; } - group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); + group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index, glObjectStore); 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 883f446b4a..dd0ce4ff29 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -27,16 +27,16 @@ public: LineBucket(float overscaling); ~LineBucket() override; - void upload() override; + void upload(gl::GLObjectStore&) override; void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; bool hasData() const override; void addGeometry(const GeometryCollection&); void addGeometry(const std::vector<Coordinate>& line); - void drawLines(LineShader& shader); - void drawLineSDF(LineSDFShader& shader); - void drawLinePatterns(LinepatternShader& shader); + void drawLines(LineShader&, gl::GLObjectStore&); + void drawLineSDF(LineSDFShader&, gl::GLObjectStore&); + void drawLinePatterns(LinepatternShader&, gl::GLObjectStore&); private: struct TriangleElement { diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index ccee950c73..da3551aa74 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -46,23 +46,25 @@ using namespace mbgl; -Painter::Painter(MapData& data_, TransformState& state_) - : data(data_), state(state_) { +Painter::Painter(MapData& data_, TransformState& state_, gl::GLObjectStore& glObjectStore_) + : data(data_), + state(state_), + glObjectStore(glObjectStore_) { gl::debugging::enable(); - plainShader = std::make_unique<PlainShader>(); - outlineShader = std::make_unique<OutlineShader>(); - lineShader = std::make_unique<LineShader>(); - linesdfShader = std::make_unique<LineSDFShader>(); - linepatternShader = std::make_unique<LinepatternShader>(); - patternShader = std::make_unique<PatternShader>(); - iconShader = std::make_unique<IconShader>(); - rasterShader = std::make_unique<RasterShader>(); - sdfGlyphShader = std::make_unique<SDFGlyphShader>(); - sdfIconShader = std::make_unique<SDFIconShader>(); - dotShader = std::make_unique<DotShader>(); - collisionBoxShader = std::make_unique<CollisionBoxShader>(); - circleShader = std::make_unique<CircleShader>(); + plainShader = std::make_unique<PlainShader>(glObjectStore); + outlineShader = std::make_unique<OutlineShader>(glObjectStore); + lineShader = std::make_unique<LineShader>(glObjectStore); + linesdfShader = std::make_unique<LineSDFShader>(glObjectStore); + linepatternShader = std::make_unique<LinepatternShader>(glObjectStore); + patternShader = std::make_unique<PatternShader>(glObjectStore); + iconShader = std::make_unique<IconShader>(glObjectStore); + rasterShader = std::make_unique<RasterShader>(glObjectStore); + sdfGlyphShader = std::make_unique<SDFGlyphShader>(glObjectStore); + sdfIconShader = std::make_unique<SDFIconShader>(glObjectStore); + dotShader = std::make_unique<DotShader>(glObjectStore); + collisionBoxShader = std::make_unique<CollisionBoxShader>(glObjectStore); + circleShader = std::make_unique<CircleShader>(glObjectStore); // Reset GL values config.reset(); @@ -108,16 +110,16 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a { MBGL_DEBUG_GROUP("upload"); - tileStencilBuffer.upload(); - tileBorderBuffer.upload(); - spriteAtlas->upload(); - lineAtlas->upload(); - glyphAtlas->upload(); - annotationSpriteAtlas.upload(); + tileStencilBuffer.upload(glObjectStore); + tileBorderBuffer.upload(glObjectStore); + spriteAtlas->upload(glObjectStore); + lineAtlas->upload(glObjectStore); + glyphAtlas->upload(glObjectStore); + annotationSpriteAtlas.upload(glObjectStore); for (const auto& item : order) { if (item.bucket && item.bucket->needsUpload()) { - item.bucket->upload(); + item.bucket->upload(glObjectStore); } } } @@ -315,9 +317,9 @@ void Painter::renderBackground(const BackgroundLayer& layer) { patternShader->u_patternmatrix_b = matrixB; VertexArrayObject::Unbind(); - backgroundBuffer.bind(); + backgroundBuffer.bind(glObjectStore); patternShader->bind(0); - spriteAtlas->bind(true); + spriteAtlas->bind(true, glObjectStore); } else { Color color = properties.color; color[0] *= properties.opacity; @@ -328,7 +330,7 @@ void Painter::renderBackground(const BackgroundLayer& layer) { config.program = plainShader->getID(); plainShader->u_matrix = identityMatrix; plainShader->u_color = color; - backgroundArray.bind(*plainShader, backgroundBuffer, BUFFER_OFFSET(0)); + backgroundArray.bind(*plainShader, backgroundBuffer, BUFFER_OFFSET(0), glObjectStore); } config.stencilTest = GL_FALSE; diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 8ab0a49806..83d051359b 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -66,9 +66,13 @@ class CollisionBoxShader; struct ClipID; +namespace util { +class GLObjectStore; +} + class Painter : private util::noncopyable { public: - Painter(MapData&, TransformState&); + Painter(MapData&, TransformState&, gl::GLObjectStore&); ~Painter(); void render(const Style& style, @@ -118,7 +122,7 @@ private: float scaleDivisor, std::array<float, 2> texsize, SDFShader& sdfShader, - void (SymbolBucket::*drawSDF)(SDFShader&)); + void (SymbolBucket::*drawSDF)(SDFShader&, gl::GLObjectStore&)); void setDepthSublayer(int n); @@ -142,6 +146,8 @@ private: MapData& data; TransformState& state; + gl::GLObjectStore& glObjectStore; + FrameData frame; int indent = 0; diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index 9965e3ab7a..4ae562d674 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -46,5 +46,5 @@ void Painter::renderCircle(CircleBucket& bucket, circleShader->u_blur = std::max<float>(properties.blur, antialiasing); circleShader->u_size = properties.radius; - bucket.drawCircles(*circleShader); + bucket.drawCircles(*circleShader, glObjectStore); } diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index f3f8a647d4..aed4c45869 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -21,7 +21,7 @@ void Painter::drawClippingMasks(const std::map<TileID, ClipID>& stencils) { config.colorMask = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE }; config.stencilMask = mask; - coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET_0); + coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET_0, glObjectStore); 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 756c5e41ea..575bffe53f 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -39,18 +39,18 @@ void Painter::renderDebugText(TileData& tileData, const mat4 &matrix) { // Draw white outline plainShader->u_color = {{ 1.0f, 1.0f, 1.0f, 1.0f }}; config.lineWidth = 4.0f * data.pixelRatio; - tileData.debugBucket->drawLines(*plainShader); + tileData.debugBucket->drawLines(*plainShader, glObjectStore); #ifndef GL_ES_VERSION_2_0 // Draw line "end caps" MBGL_CHECK_ERROR(glPointSize(2)); - tileData.debugBucket->drawPoints(*plainShader); + tileData.debugBucket->drawPoints(*plainShader, glObjectStore); #endif // Draw black text. plainShader->u_color = {{ 0.0f, 0.0f, 0.0f, 1.0f }}; config.lineWidth = 2.0f * data.pixelRatio; - tileData.debugBucket->drawLines(*plainShader); + tileData.debugBucket->drawLines(*plainShader, glObjectStore); config.depthFunc.reset(); config.depthTest = GL_TRUE; @@ -70,7 +70,7 @@ void Painter::renderDebugFrame(const mat4 &matrix) { plainShader->u_matrix = matrix; // draw tile outline - tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET_0); + tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET_0, glObjectStore); plainShader->u_color = {{ 1.0f, 0.0f, 0.0f, 1.0f }}; config.lineWidth = 4.0f * data.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 28f64c1baf..cd54645c2b 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -56,7 +56,7 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI static_cast<float>(frame.framebufferSize[1]) }}; setDepthSublayer(0); - bucket.drawVertices(*outlineShader); + bucket.drawVertices(*outlineShader, glObjectStore); } if (pattern) { @@ -111,11 +111,11 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI patternShader->u_offset_b = std::array<float, 2>{{offsetBx, offsetBy}}; MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0)); - spriteAtlas->bind(true); + spriteAtlas->bind(true, glObjectStore); // Draw the actual triangles into the color & stencil buffer. setDepthSublayer(0); - bucket.drawElements(*patternShader); + bucket.drawElements(*patternShader, glObjectStore); } } else { @@ -131,7 +131,7 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI // Draw the actual triangles into the color & stencil buffer. setDepthSublayer(1); - bucket.drawElements(*plainShader); + bucket.drawElements(*plainShader, glObjectStore); } } @@ -151,6 +151,6 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI }}; setDepthSublayer(2); - bucket.drawVertices(*outlineShader); + bucket.drawVertices(*outlineShader, glObjectStore); } } diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index c17beb3f6b..5fc5ee0221 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -79,9 +79,9 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI linesdfShader->u_blur = blur; linesdfShader->u_color = color; - LinePatternPos posA = lineAtlas->getDashPosition(properties.dasharray.value.from, layout.cap == CapType::Round); - LinePatternPos posB = lineAtlas->getDashPosition(properties.dasharray.value.to, layout.cap == CapType::Round); - lineAtlas->bind(); + LinePatternPos posA = lineAtlas->getDashPosition(properties.dasharray.value.from, layout.cap == CapType::Round, glObjectStore); + LinePatternPos posB = lineAtlas->getDashPosition(properties.dasharray.value.to, layout.cap == CapType::Round, glObjectStore); + lineAtlas->bind(glObjectStore); const float widthA = posA.width * properties.dasharray.value.fromScale; const float widthB = posB.width * properties.dasharray.value.toScale; @@ -102,7 +102,7 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI linesdfShader->u_offset = -properties.offset; linesdfShader->u_antialiasingmatrix = antialiasingMatrix; - bucket.drawLineSDF(*linesdfShader); + bucket.drawLineSDF(*linesdfShader, glObjectStore); } else if (!properties.pattern.value.from.empty()) { optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(properties.pattern.value.from, true); @@ -134,9 +134,9 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI linepatternShader->u_antialiasingmatrix = antialiasingMatrix; MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0)); - spriteAtlas->bind(true); + spriteAtlas->bind(true, glObjectStore); - bucket.drawLinePatterns(*linepatternShader); + bucket.drawLinePatterns(*linepatternShader, glObjectStore); } else { config.program = lineShader->getID(); @@ -152,6 +152,6 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI lineShader->u_color = color; - bucket.drawLines(*lineShader); + bucket.drawLines(*lineShader, glObjectStore); } } diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp index f921ceefc2..377b2c005c 100644 --- a/src/mbgl/renderer/painter_raster.cpp +++ b/src/mbgl/renderer/painter_raster.cpp @@ -28,7 +28,7 @@ void Painter::renderRaster(RasterBucket& bucket, const RasterLayer& layer, const config.depthTest = GL_TRUE; config.depthMask = GL_FALSE; setDepthSublayer(0); - bucket.drawRaster(*rasterShader, tileStencilBuffer, coveringRasterArray); + bucket.drawRaster(*rasterShader, tileStencilBuffer, coveringRasterArray, glObjectStore); } } diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index c2bb1e757f..5f59d6a8a6 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -23,7 +23,7 @@ void Painter::renderSDF(SymbolBucket &bucket, float sdfFontSize, std::array<float, 2> texsize, SDFShader& sdfShader, - void (SymbolBucket::*drawSDF)(SDFShader&)) + void (SymbolBucket::*drawSDF)(SDFShader&, gl::GLObjectStore&)) { mat4 vtxMatrix = translatedMatrix(matrix, styleProperties.translate, id, styleProperties.translateAnchor); @@ -101,7 +101,7 @@ void Painter::renderSDF(SymbolBucket &bucket, sdfShader.u_buffer = (haloOffset - styleProperties.haloWidth / fontScale) / sdfPx; setDepthSublayer(0); - (bucket.*drawSDF)(sdfShader); + (bucket.*drawSDF)(sdfShader, glObjectStore); } // Then, we draw the text/icon over the halo @@ -122,7 +122,7 @@ void Painter::renderSDF(SymbolBucket &bucket, sdfShader.u_buffer = (256.0f - 64.0f) / 256.0f; setDepthSublayer(1); - (bucket.*drawSDF)(sdfShader); + (bucket.*drawSDF)(sdfShader, glObjectStore); } } @@ -174,7 +174,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const SpriteAtlas* activeSpriteAtlas = layer.spriteAtlas; const bool iconScaled = fontScale != 1 || data.pixelRatio != activeSpriteAtlas->getPixelRatio() || bucket.iconsNeedLinear; const bool iconTransformed = layout.icon.rotationAlignment == RotationAlignmentType::Map || angleOffset != 0 || state.getPitch() != 0; - activeSpriteAtlas->bind(sdf || state.isChanging() || iconScaled || iconTransformed); + activeSpriteAtlas->bind(sdf || state.isChanging() || iconScaled || iconTransformed, glObjectStore); if (sdf) { renderSDF(bucket, @@ -230,7 +230,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const iconShader->u_opacity = properties.icon.opacity; setDepthSublayer(0); - bucket.drawIcons(*iconShader); + bucket.drawIcons(*iconShader, glObjectStore); } } @@ -242,7 +242,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const config.depthTest = GL_FALSE; } - glyphAtlas->bind(); + glyphAtlas->bind(glObjectStore); renderSDF(bucket, id, @@ -267,7 +267,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const config.lineWidth = 1.0f; setDepthSublayer(0); - bucket.drawCollisionBoxes(*collisionBoxShader); + bucket.drawCollisionBoxes(*collisionBoxShader, glObjectStore); } diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp index 0b19fa0c1e..137574b731 100644 --- a/src/mbgl/renderer/raster_bucket.cpp +++ b/src/mbgl/renderer/raster_bucket.cpp @@ -9,9 +9,9 @@ RasterBucket::RasterBucket(gl::TexturePool& texturePool) : raster(texturePool) { } -void RasterBucket::upload() { +void RasterBucket::upload(gl::GLObjectStore& glObjectStore) { if (hasData()) { - raster.upload(); + raster.upload(glObjectStore); uploaded = true; } } @@ -27,10 +27,10 @@ void RasterBucket::setImage(PremultipliedImage image) { raster.load(std::move(image)); } -void RasterBucket::drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array) { - raster.bind(true); +void RasterBucket::drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array, gl::GLObjectStore& glObjectStore) { + raster.bind(true, glObjectStore); shader.u_image = 0; - array.bind(shader, vertices, BUFFER_OFFSET_0); + array.bind(shader, vertices, BUFFER_OFFSET_0, glObjectStore); MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.index())); } diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp index 92c6a8ea02..466a7602ed 100644 --- a/src/mbgl/renderer/raster_bucket.hpp +++ b/src/mbgl/renderer/raster_bucket.hpp @@ -14,13 +14,13 @@ class RasterBucket : public Bucket { public: RasterBucket(gl::TexturePool&); - void upload() override; + void upload(gl::GLObjectStore&) override; void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; bool hasData() const override; void setImage(PremultipliedImage); - void drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array); + void drawRaster(RasterShader&, StaticVertexBuffer&, VertexArrayObject&, gl::GLObjectStore&); Raster raster; }; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 0854f697a3..683a6f4b11 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -64,14 +64,14 @@ SymbolBucket::~SymbolBucket() { // Do not remove. header file only contains forward definitions to unique pointers. } -void SymbolBucket::upload() { +void SymbolBucket::upload(gl::GLObjectStore& glObjectStore) { if (hasTextData()) { - renderData->text.vertices.upload(); - renderData->text.triangles.upload(); + renderData->text.vertices.upload(glObjectStore); + renderData->text.triangles.upload(glObjectStore); } if (hasIconData()) { - renderData->icon.vertices.upload(); - renderData->icon.triangles.upload(); + renderData->icon.vertices.upload(glObjectStore); + renderData->icon.triangles.upload(glObjectStore); } uploaded = true; @@ -572,50 +572,50 @@ void SymbolBucket::swapRenderData() { } } -void SymbolBucket::drawGlyphs(SDFShader &shader) { +void SymbolBucket::drawGlyphs(SDFShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte *vertex_index = BUFFER_OFFSET_0; GLbyte *elements_index = BUFFER_OFFSET_0; auto& text = renderData->text; for (auto &group : text.groups) { assert(group); - group->array[0].bind(shader, text.vertices, text.triangles, vertex_index); + group->array[0].bind(shader, text.vertices, text.triangles, vertex_index, glObjectStore); 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) { +void SymbolBucket::drawIcons(SDFShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte *vertex_index = BUFFER_OFFSET_0; GLbyte *elements_index = BUFFER_OFFSET_0; auto& icon = renderData->icon; for (auto &group : icon.groups) { assert(group); - group->array[0].bind(shader, icon.vertices, icon.triangles, vertex_index); + group->array[0].bind(shader, icon.vertices, icon.triangles, vertex_index, glObjectStore); 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) { +void SymbolBucket::drawIcons(IconShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte *vertex_index = BUFFER_OFFSET_0; GLbyte *elements_index = BUFFER_OFFSET_0; auto& icon = renderData->icon; for (auto &group : icon.groups) { assert(group); - group->array[1].bind(shader, icon.vertices, icon.triangles, vertex_index); + group->array[1].bind(shader, icon.vertices, icon.triangles, vertex_index, glObjectStore); 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::drawCollisionBoxes(CollisionBoxShader &shader) { +void SymbolBucket::drawCollisionBoxes(CollisionBoxShader& shader, gl::GLObjectStore& glObjectStore) { GLbyte *vertex_index = BUFFER_OFFSET_0; auto& collisionBox = renderData->collisionBox; for (auto &group : collisionBox.groups) { - group->array[0].bind(shader, collisionBox.vertices, vertex_index); + group->array[0].bind(shader, collisionBox.vertices, vertex_index, glObjectStore); 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 cca34cd858..cebb7e5dbe 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -70,7 +70,7 @@ public: SymbolBucket(float overscaling, float zoom, const MapMode); ~SymbolBucket() override; - void upload() override; + void upload(gl::GLObjectStore&) override; void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; bool hasData() const override; bool hasTextData() const; @@ -82,10 +82,10 @@ public: GlyphAtlas&, GlyphStore&); - void drawGlyphs(SDFShader& shader); - void drawIcons(SDFShader& shader); - void drawIcons(IconShader& shader); - void drawCollisionBoxes(CollisionBoxShader& shader); + void drawGlyphs(SDFShader&, gl::GLObjectStore&); + void drawIcons(SDFShader&, gl::GLObjectStore&); + void drawIcons(IconShader&, gl::GLObjectStore&); + void drawCollisionBoxes(CollisionBoxShader&, gl::GLObjectStore&); void parseFeatures(const GeometryTileLayer&, const FilterExpression&); diff --git a/src/mbgl/shader/box_shader.cpp b/src/mbgl/shader/box_shader.cpp index 59fd104f83..63f800ea69 100644 --- a/src/mbgl/shader/box_shader.cpp +++ b/src/mbgl/shader/box_shader.cpp @@ -7,8 +7,8 @@ using namespace mbgl; -CollisionBoxShader::CollisionBoxShader() - : Shader("collisionbox", shaders::box::vertex, shaders::box::fragment) { +CollisionBoxShader::CollisionBoxShader(gl::GLObjectStore& glObjectStore) + : Shader("collisionbox", shaders::box::vertex, shaders::box::fragment, glObjectStore) { a_extrude = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_extrude")); a_data = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data")); } diff --git a/src/mbgl/shader/box_shader.hpp b/src/mbgl/shader/box_shader.hpp index bc781dbc15..f3015b73a7 100644 --- a/src/mbgl/shader/box_shader.hpp +++ b/src/mbgl/shader/box_shader.hpp @@ -9,7 +9,7 @@ namespace mbgl { class CollisionBoxShader : public Shader { public: - CollisionBoxShader(); + CollisionBoxShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/circle_shader.cpp b/src/mbgl/shader/circle_shader.cpp index d128f8b699..3ec822747f 100644 --- a/src/mbgl/shader/circle_shader.cpp +++ b/src/mbgl/shader/circle_shader.cpp @@ -7,8 +7,8 @@ using namespace mbgl; -CircleShader::CircleShader() - : Shader("circle", shaders::circle::vertex, shaders::circle::fragment) { +CircleShader::CircleShader(gl::GLObjectStore& glObjectStore) + : Shader("circle", shaders::circle::vertex, shaders::circle::fragment, glObjectStore) { } void CircleShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/circle_shader.hpp b/src/mbgl/shader/circle_shader.hpp index 7c1212c275..a28bf3c6ae 100644 --- a/src/mbgl/shader/circle_shader.hpp +++ b/src/mbgl/shader/circle_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class CircleShader : public Shader { public: - CircleShader(); + CircleShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/dot_shader.cpp b/src/mbgl/shader/dot_shader.cpp index 12e2ee7845..9d60306da2 100644 --- a/src/mbgl/shader/dot_shader.cpp +++ b/src/mbgl/shader/dot_shader.cpp @@ -7,7 +7,8 @@ using namespace mbgl; -DotShader::DotShader() : Shader("dot", shaders::dot::vertex, shaders::dot::fragment) { +DotShader::DotShader(gl::GLObjectStore& glObjectStore) + : Shader("dot", shaders::dot::vertex, shaders::dot::fragment, glObjectStore) { } void DotShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/dot_shader.hpp b/src/mbgl/shader/dot_shader.hpp index 606764c2d6..a015310a62 100644 --- a/src/mbgl/shader/dot_shader.hpp +++ b/src/mbgl/shader/dot_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class DotShader : public Shader { public: - DotShader(); + DotShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/icon_shader.cpp b/src/mbgl/shader/icon_shader.cpp index 609f2bb293..2ff653a87c 100644 --- a/src/mbgl/shader/icon_shader.cpp +++ b/src/mbgl/shader/icon_shader.cpp @@ -7,7 +7,8 @@ using namespace mbgl; -IconShader::IconShader() : Shader("icon", shaders::icon::vertex, shaders::icon::fragment) { +IconShader::IconShader(gl::GLObjectStore& glObjectStore) + : Shader("icon", shaders::icon::vertex, shaders::icon::fragment, glObjectStore) { a_offset = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_offset")); a_data1 = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data1")); a_data2 = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data2")); diff --git a/src/mbgl/shader/icon_shader.hpp b/src/mbgl/shader/icon_shader.hpp index 8a25b635fe..ec6311ea80 100644 --- a/src/mbgl/shader/icon_shader.hpp +++ b/src/mbgl/shader/icon_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class IconShader : public Shader { public: - IconShader(); + IconShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/line_shader.cpp b/src/mbgl/shader/line_shader.cpp index e0dc5384b5..e4df0531d8 100644 --- a/src/mbgl/shader/line_shader.cpp +++ b/src/mbgl/shader/line_shader.cpp @@ -7,7 +7,8 @@ using namespace mbgl; -LineShader::LineShader() : Shader("line", shaders::line::vertex, shaders::line::fragment) { +LineShader::LineShader(gl::GLObjectStore& glObjectStore) + : Shader("line", shaders::line::vertex, shaders::line::fragment, glObjectStore) { a_data = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data")); } diff --git a/src/mbgl/shader/line_shader.hpp b/src/mbgl/shader/line_shader.hpp index 14e03c2eaf..1a9598f925 100644 --- a/src/mbgl/shader/line_shader.hpp +++ b/src/mbgl/shader/line_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class LineShader : public Shader { public: - LineShader(); + LineShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/linepattern_shader.cpp b/src/mbgl/shader/linepattern_shader.cpp index 4c15d8b075..7acd42f727 100644 --- a/src/mbgl/shader/linepattern_shader.cpp +++ b/src/mbgl/shader/linepattern_shader.cpp @@ -7,8 +7,8 @@ using namespace mbgl; -LinepatternShader::LinepatternShader() - : Shader("linepattern", shaders::linepattern::vertex, shaders::linepattern::fragment) { +LinepatternShader::LinepatternShader(gl::GLObjectStore& glObjectStore) + : Shader("linepattern", shaders::linepattern::vertex, shaders::linepattern::fragment, glObjectStore) { a_data = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data")); } diff --git a/src/mbgl/shader/linepattern_shader.hpp b/src/mbgl/shader/linepattern_shader.hpp index 6c83cb0cc3..0d3e98c834 100644 --- a/src/mbgl/shader/linepattern_shader.hpp +++ b/src/mbgl/shader/linepattern_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class LinepatternShader : public Shader { public: - LinepatternShader(); + LinepatternShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/linesdf_shader.cpp b/src/mbgl/shader/linesdf_shader.cpp index f5eba0a046..00adaf0c86 100644 --- a/src/mbgl/shader/linesdf_shader.cpp +++ b/src/mbgl/shader/linesdf_shader.cpp @@ -7,8 +7,8 @@ using namespace mbgl; -LineSDFShader::LineSDFShader() - : Shader("line", shaders::linesdf::vertex, shaders::linesdf::fragment) { +LineSDFShader::LineSDFShader(gl::GLObjectStore& glObjectStore) + : Shader("line", shaders::linesdf::vertex, shaders::linesdf::fragment, glObjectStore) { a_data = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data")); } diff --git a/src/mbgl/shader/linesdf_shader.hpp b/src/mbgl/shader/linesdf_shader.hpp index 2a8bdc6629..8ac0aa5793 100644 --- a/src/mbgl/shader/linesdf_shader.hpp +++ b/src/mbgl/shader/linesdf_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class LineSDFShader : public Shader { public: - LineSDFShader(); + LineSDFShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/outline_shader.cpp b/src/mbgl/shader/outline_shader.cpp index df42e09e01..8c7458327f 100644 --- a/src/mbgl/shader/outline_shader.cpp +++ b/src/mbgl/shader/outline_shader.cpp @@ -7,8 +7,8 @@ using namespace mbgl; -OutlineShader::OutlineShader() - : Shader("outline", shaders::outline::vertex, shaders::outline::fragment) { +OutlineShader::OutlineShader(gl::GLObjectStore& glObjectStore) + : Shader("outline", shaders::outline::vertex, shaders::outline::fragment, glObjectStore) { } void OutlineShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/outline_shader.hpp b/src/mbgl/shader/outline_shader.hpp index 3af9b8349f..800461bf06 100644 --- a/src/mbgl/shader/outline_shader.hpp +++ b/src/mbgl/shader/outline_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class OutlineShader : public Shader { public: - OutlineShader(); + OutlineShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/pattern_shader.cpp b/src/mbgl/shader/pattern_shader.cpp index d872e8d976..4f52df59fb 100644 --- a/src/mbgl/shader/pattern_shader.cpp +++ b/src/mbgl/shader/pattern_shader.cpp @@ -7,10 +7,11 @@ using namespace mbgl; -PatternShader::PatternShader() +PatternShader::PatternShader(gl::GLObjectStore& glObjectStore) : Shader( "pattern", - shaders::pattern::vertex, shaders::pattern::fragment + shaders::pattern::vertex, shaders::pattern::fragment, + glObjectStore ) { } diff --git a/src/mbgl/shader/pattern_shader.hpp b/src/mbgl/shader/pattern_shader.hpp index db7901c578..8692f6ed39 100644 --- a/src/mbgl/shader/pattern_shader.hpp +++ b/src/mbgl/shader/pattern_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class PatternShader : public Shader { public: - PatternShader(); + PatternShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/plain_shader.cpp b/src/mbgl/shader/plain_shader.cpp index 1408a42c62..1b5a7819b3 100644 --- a/src/mbgl/shader/plain_shader.cpp +++ b/src/mbgl/shader/plain_shader.cpp @@ -7,7 +7,8 @@ using namespace mbgl; -PlainShader::PlainShader() : Shader("plain", shaders::plain::vertex, shaders::plain::fragment) { +PlainShader::PlainShader(gl::GLObjectStore& glObjectStore) + : Shader("plain", shaders::plain::vertex, shaders::plain::fragment, glObjectStore) { } void PlainShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/plain_shader.hpp b/src/mbgl/shader/plain_shader.hpp index f9b8c41a63..34ee4dcdf7 100644 --- a/src/mbgl/shader/plain_shader.hpp +++ b/src/mbgl/shader/plain_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class PlainShader : public Shader { public: - PlainShader(); + PlainShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/raster_shader.cpp b/src/mbgl/shader/raster_shader.cpp index 4b7c0077b3..77bcf40008 100644 --- a/src/mbgl/shader/raster_shader.cpp +++ b/src/mbgl/shader/raster_shader.cpp @@ -7,8 +7,8 @@ using namespace mbgl; -RasterShader::RasterShader() - : Shader("raster", shaders::raster::vertex, shaders::raster::fragment) { +RasterShader::RasterShader(gl::GLObjectStore& glObjectStore) + : Shader("raster", shaders::raster::vertex, shaders::raster::fragment, glObjectStore) { } void RasterShader::bind(GLbyte* offset) { diff --git a/src/mbgl/shader/raster_shader.hpp b/src/mbgl/shader/raster_shader.hpp index 60b283fc2a..6a2e2ecf3e 100644 --- a/src/mbgl/shader/raster_shader.hpp +++ b/src/mbgl/shader/raster_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class RasterShader : public Shader { public: - RasterShader(); + RasterShader(gl::GLObjectStore&); void bind(GLbyte *offset) final; diff --git a/src/mbgl/shader/sdf_shader.cpp b/src/mbgl/shader/sdf_shader.cpp index e613863041..a972849d3d 100644 --- a/src/mbgl/shader/sdf_shader.cpp +++ b/src/mbgl/shader/sdf_shader.cpp @@ -7,7 +7,8 @@ using namespace mbgl; -SDFShader::SDFShader() : Shader("sdf", shaders::sdf::vertex, shaders::sdf::fragment) { +SDFShader::SDFShader(gl::GLObjectStore& glObjectStore) + : Shader("sdf", shaders::sdf::vertex, shaders::sdf::fragment, glObjectStore) { a_offset = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_offset")); a_data1 = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data1")); a_data2 = MBGL_CHECK_ERROR(glGetAttribLocation(getID(), "a_data2")); diff --git a/src/mbgl/shader/sdf_shader.hpp b/src/mbgl/shader/sdf_shader.hpp index 29dbfea047..402168de0c 100644 --- a/src/mbgl/shader/sdf_shader.hpp +++ b/src/mbgl/shader/sdf_shader.hpp @@ -8,7 +8,7 @@ namespace mbgl { class SDFShader : public Shader { public: - SDFShader(); + SDFShader(gl::GLObjectStore&); UniformMatrix<4> u_matrix = {"u_matrix", *this}; UniformMatrix<4> u_exmatrix = {"u_exmatrix", *this}; @@ -32,11 +32,13 @@ protected: class SDFGlyphShader : public SDFShader { public: + SDFGlyphShader(gl::GLObjectStore& glObjectStore) : SDFShader(glObjectStore) {} void bind(GLbyte *offset) final; }; class SDFIconShader : public SDFShader { public: + SDFIconShader(gl::GLObjectStore& glObjectStore) : SDFShader(glObjectStore) {} void bind(GLbyte *offset) final; }; diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp index 998edfb970..8216de5b4d 100644 --- a/src/mbgl/shader/shader.cpp +++ b/src/mbgl/shader/shader.cpp @@ -13,19 +13,19 @@ namespace mbgl { -Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSource) +Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSource, gl::GLObjectStore& glObjectStore) : name(name_) { util::stopwatch stopwatch("shader compilation", Event::Shader); - program.create(); - vertexShader.create(); + program.create(glObjectStore); + vertexShader.create(glObjectStore); if (!compileShader(vertexShader, &vertSource)) { Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertSource); throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile"); } - fragmentShader.create(); + fragmentShader.create(glObjectStore); if (!compileShader(fragmentShader, &fragSource)) { Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragSource); throw util::ShaderException(std::string { "Fragment shader " } + name + " failed to compile"); diff --git a/src/mbgl/shader/shader.hpp b/src/mbgl/shader/shader.hpp index c63aa6714c..b543f73a6f 100644 --- a/src/mbgl/shader/shader.hpp +++ b/src/mbgl/shader/shader.hpp @@ -9,7 +9,7 @@ namespace mbgl { class Shader : private util::noncopyable { public: - Shader(const GLchar *name, const GLchar *vertex, const GLchar *fragment); + Shader(const GLchar *name, const GLchar *vertex, const GLchar *fragment, gl::GLObjectStore&); ~Shader(); const GLchar *name; diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp index 7137e6d1fc..12d12a53cb 100644 --- a/src/mbgl/sprite/sprite_atlas.cpp +++ b/src/mbgl/sprite/sprite_atlas.cpp @@ -143,9 +143,9 @@ void SpriteAtlas::copy(const Holder& holder, const bool wrap) { dirty = true; } -void SpriteAtlas::upload() { +void SpriteAtlas::upload(gl::GLObjectStore& glObjectStore) { if (dirty) { - bind(); + bind(false, glObjectStore); } } @@ -180,13 +180,13 @@ void SpriteAtlas::updateDirty() { } } -void SpriteAtlas::bind(bool linear) { +void SpriteAtlas::bind(bool linear, gl::GLObjectStore& glObjectStore) { if (!data) { return; // Empty atlas } if (!texture) { - texture.create(); + texture.create(glObjectStore); MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); #ifndef GL_ES_VERSION_2_0 MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); @@ -246,12 +246,7 @@ void SpriteAtlas::bind(bool linear) { } }; -SpriteAtlas::~SpriteAtlas() { - std::lock_guard<std::recursive_mutex> lock(mtx); - if (texture) { - mbgl::util::ThreadContext::getGLObjectStore()->abandon(std::move(texture)); - } -} +SpriteAtlas::~SpriteAtlas() = default; SpriteAtlas::Holder::Holder(const std::shared_ptr<const SpriteImage>& spriteImage_, const Rect<dimension>& pos_) diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp index ff9cb44e4d..ba592c5acb 100644 --- a/src/mbgl/sprite/sprite_atlas.hpp +++ b/src/mbgl/sprite/sprite_atlas.hpp @@ -52,14 +52,14 @@ public: optional<SpriteAtlasPosition> getPosition(const std::string& name, bool repeating = false); // Binds the atlas texture to the GPU, and uploads data if it is out of date. - void bind(bool linear = false); + void bind(bool linear, gl::GLObjectStore&); // Updates sprites in the atlas texture that may have changed in the source SpriteStore object. void updateDirty(); // Uploads the texture to the GPU to be available when we need it. This is a lazy operation; // the texture is only bound when the data is out of date (=dirty). - void upload(); + void upload(gl::GLObjectStore&); inline dimension getWidth() const { return width; } inline dimension getHeight() const { return height; } diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp index 49c013ba08..a74b73a016 100644 --- a/src/mbgl/util/raster.cpp +++ b/src/mbgl/util/raster.cpp @@ -37,14 +37,14 @@ void Raster::load(PremultipliedImage image) { } -void Raster::bind(bool linear) { +void Raster::bind(bool linear, gl::GLObjectStore& glObjectStore) { if (!width || !height) { Log::Error(Event::OpenGL, "trying to bind texture without dimension"); return; } if (img.data && !textured) { - upload(); + upload(glObjectStore); } else if (textured) { MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID)); } @@ -57,9 +57,9 @@ void Raster::bind(bool linear) { } } -void Raster::upload() { +void Raster::upload(gl::GLObjectStore& glObjectStore) { if (img.data && !textured) { - textureID = texturePool.getTextureID(); + textureID = texturePool.getTextureID(glObjectStore); MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID)); #ifndef GL_ES_VERSION_2_0 MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); diff --git a/src/mbgl/util/raster.hpp b/src/mbgl/util/raster.hpp index e47fe665f6..0a275a197c 100644 --- a/src/mbgl/util/raster.hpp +++ b/src/mbgl/util/raster.hpp @@ -21,10 +21,10 @@ public: void load(PremultipliedImage); // bind current texture - void bind(bool linear = false); + void bind(bool linear, gl::GLObjectStore&); // uploads the texture if it hasn't been uploaded yet. - void upload(); + void upload(gl::GLObjectStore&); // loaded status bool isLoaded() const; diff --git a/src/mbgl/util/thread_context.cpp b/src/mbgl/util/thread_context.cpp index a60f2c9ab5..d6ddda2e8e 100644 --- a/src/mbgl/util/thread_context.cpp +++ b/src/mbgl/util/thread_context.cpp @@ -44,22 +44,6 @@ ThreadPriority ThreadContext::getPriority() { } } -gl::GLObjectStore* ThreadContext::getGLObjectStore() { - if (current.get() != nullptr) { - return current.get()->glObjectStore; - } else { - return nullptr; - } -} - -void ThreadContext::setGLObjectStore(gl::GLObjectStore* glObjectStore) { - if (current.get() != nullptr) { - current.get()->glObjectStore = glObjectStore; - } else { - throw std::runtime_error("Current thread has no current ThreadContext."); - } -} - class MainThreadContextRegistrar { public: MainThreadContextRegistrar() : context("Main", ThreadType::Main, ThreadPriority::Regular) { diff --git a/src/mbgl/util/thread_context.hpp b/src/mbgl/util/thread_context.hpp index 7558400184..dea98fe3fa 100644 --- a/src/mbgl/util/thread_context.hpp +++ b/src/mbgl/util/thread_context.hpp @@ -6,9 +6,6 @@ #include <thread> namespace mbgl { - -namespace gl { class GLObjectStore; } - namespace util { enum class ThreadPriority : bool { @@ -33,14 +30,9 @@ public: static std::string getName(); static ThreadPriority getPriority(); - static gl::GLObjectStore* getGLObjectStore(); - static void setGLObjectStore(gl::GLObjectStore* glObjectStore); - std::string name; ThreadType type; ThreadPriority priority; - - gl::GLObjectStore* glObjectStore = nullptr; }; } // namespace util |