summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-02-18 11:19:24 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-02-18 15:15:24 -0800
commit9c26f063187b129218910dbb86eb21215a2cdf40 (patch)
tree189f84f90cef341a0a084fefde40f4f07da117cb
parent7b39ce95210ceb6640b3a3399dacd1d0e826ac1f (diff)
downloadqtlocation-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.
-rw-r--r--src/mbgl/geometry/buffer.hpp11
-rw-r--r--src/mbgl/geometry/glyph_atlas.cpp8
-rw-r--r--src/mbgl/geometry/glyph_atlas.hpp4
-rw-r--r--src/mbgl/geometry/line_atlas.cpp16
-rw-r--r--src/mbgl/geometry/line_atlas.hpp8
-rw-r--r--src/mbgl/geometry/vao.cpp6
-rw-r--r--src/mbgl/geometry/vao.hpp16
-rw-r--r--src/mbgl/gl/gl_object_store.cpp100
-rw-r--r--src/mbgl/gl/gl_object_store.hpp58
-rw-r--r--src/mbgl/gl/texture_pool.cpp8
-rw-r--r--src/mbgl/gl/texture_pool.hpp6
-rw-r--r--src/mbgl/map/map_context.cpp4
-rw-r--r--src/mbgl/renderer/bucket.hpp6
-rw-r--r--src/mbgl/renderer/circle_bucket.cpp10
-rw-r--r--src/mbgl/renderer/circle_bucket.hpp4
-rw-r--r--src/mbgl/renderer/debug_bucket.cpp8
-rw-r--r--src/mbgl/renderer/debug_bucket.hpp8
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp20
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp8
-rw-r--r--src/mbgl/renderer/line_bucket.cpp18
-rw-r--r--src/mbgl/renderer/line_bucket.hpp8
-rw-r--r--src/mbgl/renderer/painter.cpp52
-rw-r--r--src/mbgl/renderer/painter.hpp10
-rw-r--r--src/mbgl/renderer/painter_circle.cpp2
-rw-r--r--src/mbgl/renderer/painter_clipping.cpp2
-rw-r--r--src/mbgl/renderer/painter_debug.cpp8
-rw-r--r--src/mbgl/renderer/painter_fill.cpp10
-rw-r--r--src/mbgl/renderer/painter_line.cpp14
-rw-r--r--src/mbgl/renderer/painter_raster.cpp2
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp14
-rw-r--r--src/mbgl/renderer/raster_bucket.cpp10
-rw-r--r--src/mbgl/renderer/raster_bucket.hpp4
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp26
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp10
-rw-r--r--src/mbgl/shader/box_shader.cpp4
-rw-r--r--src/mbgl/shader/box_shader.hpp2
-rw-r--r--src/mbgl/shader/circle_shader.cpp4
-rw-r--r--src/mbgl/shader/circle_shader.hpp2
-rw-r--r--src/mbgl/shader/dot_shader.cpp3
-rw-r--r--src/mbgl/shader/dot_shader.hpp2
-rw-r--r--src/mbgl/shader/icon_shader.cpp3
-rw-r--r--src/mbgl/shader/icon_shader.hpp2
-rw-r--r--src/mbgl/shader/line_shader.cpp3
-rw-r--r--src/mbgl/shader/line_shader.hpp2
-rw-r--r--src/mbgl/shader/linepattern_shader.cpp4
-rw-r--r--src/mbgl/shader/linepattern_shader.hpp2
-rw-r--r--src/mbgl/shader/linesdf_shader.cpp4
-rw-r--r--src/mbgl/shader/linesdf_shader.hpp2
-rw-r--r--src/mbgl/shader/outline_shader.cpp4
-rw-r--r--src/mbgl/shader/outline_shader.hpp2
-rw-r--r--src/mbgl/shader/pattern_shader.cpp5
-rw-r--r--src/mbgl/shader/pattern_shader.hpp2
-rw-r--r--src/mbgl/shader/plain_shader.cpp3
-rw-r--r--src/mbgl/shader/plain_shader.hpp2
-rw-r--r--src/mbgl/shader/raster_shader.cpp4
-rw-r--r--src/mbgl/shader/raster_shader.hpp2
-rw-r--r--src/mbgl/shader/sdf_shader.cpp3
-rw-r--r--src/mbgl/shader/sdf_shader.hpp4
-rw-r--r--src/mbgl/shader/shader.cpp8
-rw-r--r--src/mbgl/shader/shader.hpp2
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp15
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp4
-rw-r--r--src/mbgl/util/raster.cpp8
-rw-r--r--src/mbgl/util/raster.hpp4
-rw-r--r--src/mbgl/util/thread_context.cpp16
-rw-r--r--src/mbgl/util/thread_context.hpp8
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