summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-05-27 18:33:32 +0300
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-06-01 13:53:39 +0300
commit1b0683b94c070d14bc9f2cf357e551cdbbf3043a (patch)
treeef8557e284a9a0edb860a49ce3565b7bf622de2d
parent2038a21cb5d67890acafbd34bc55e365ed0043fe (diff)
downloadqtlocation-mapboxgl-1b0683b94c070d14bc9f2cf357e551cdbbf3043a.tar.gz
[core] Use unique_resource for GL objects
Source: https://github.com/okdshin/unique_resource These replace the complexity of manually handling moveable-RAII objects with a type specific for that purpose. As suggested in https://github.com/mapbox/mapbox-gl-native/pull/5141#issuecomment-221719872.
-rw-r--r--src/mbgl/geometry/buffer.hpp17
-rw-r--r--src/mbgl/geometry/glyph_atlas.cpp10
-rw-r--r--src/mbgl/geometry/glyph_atlas.hpp3
-rw-r--r--src/mbgl/geometry/line_atlas.cpp8
-rw-r--r--src/mbgl/geometry/line_atlas.hpp3
-rw-r--r--src/mbgl/geometry/vao.cpp6
-rw-r--r--src/mbgl/geometry/vao.hpp9
-rw-r--r--src/mbgl/gl/object_store.cpp84
-rw-r--r--src/mbgl/gl/object_store.hpp177
-rw-r--r--src/mbgl/gl/texture_pool.cpp6
-rw-r--r--src/mbgl/gl/texture_pool.hpp7
-rw-r--r--src/mbgl/renderer/frame_history.cpp10
-rw-r--r--src/mbgl/renderer/frame_history.hpp3
-rw-r--r--src/mbgl/shader/shader.cpp40
-rw-r--r--src/mbgl/shader/shader.hpp10
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp14
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp2
17 files changed, 175 insertions, 234 deletions
diff --git a/src/mbgl/geometry/buffer.hpp b/src/mbgl/geometry/buffer.hpp
index 2c4601eec1..1712ca9887 100644
--- a/src/mbgl/geometry/buffer.hpp
+++ b/src/mbgl/geometry/buffer.hpp
@@ -4,6 +4,7 @@
#include <mbgl/gl/object_store.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/optional.hpp>
#include <memory>
#include <cstdlib>
@@ -36,11 +37,11 @@ public:
// Transfers this buffer to the GPU and binds the buffer to the GL context.
void bind(gl::ObjectStore& store) {
- if (buffer.created()) {
- MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID()));
+ if (buffer) {
+ MBGL_CHECK_ERROR(glBindBuffer(bufferType, *buffer));
} else {
- buffer.create(store);
- MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID()));
+ buffer = store.createBuffer();
+ MBGL_CHECK_ERROR(glBindBuffer(bufferType, *buffer));
if (array == nullptr) {
Log::Debug(Event::OpenGL, "Buffer doesn't contain elements");
pos = 0;
@@ -60,12 +61,12 @@ public:
}
GLuint getID() const {
- return buffer.getID();
+ return buffer ? *buffer : 0;
}
// Uploads the buffer to the GPU to be available when we need it.
inline void upload(gl::ObjectStore& store) {
- if (!buffer.created()) {
+ if (!buffer) {
bind(store);
}
}
@@ -73,7 +74,7 @@ public:
protected:
// increase the buffer size by at least /required/ bytes.
inline void *addElement() {
- if (buffer.created()) {
+ if (buffer) {
throw std::runtime_error("Can't add elements after buffer was bound to GPU");
}
if (length < pos + itemSize) {
@@ -114,7 +115,7 @@ private:
size_t length = 0;
// GL buffer object handle.
- gl::BufferHolder buffer;
+ mbgl::optional<gl::UniqueBuffer> buffer;
};
} // namespace mbgl
diff --git a/src/mbgl/geometry/glyph_atlas.cpp b/src/mbgl/geometry/glyph_atlas.cpp
index 836155479e..b4687b8e07 100644
--- a/src/mbgl/geometry/glyph_atlas.cpp
+++ b/src/mbgl/geometry/glyph_atlas.cpp
@@ -144,7 +144,7 @@ void GlyphAtlas::removeGlyphs(uintptr_t tileUID) {
void GlyphAtlas::upload(gl::ObjectStore& store) {
if (dirty) {
- const bool first = !texture.created();
+ const bool first = !texture;
bind(store);
std::lock_guard<std::mutex> lock(mtx);
@@ -184,9 +184,9 @@ void GlyphAtlas::upload(gl::ObjectStore& store) {
}
void GlyphAtlas::bind(gl::ObjectStore& store) {
- if (!texture.created()) {
- texture.create(store);
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
+ if (!texture) {
+ texture = store.createTexture();
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
@@ -195,6 +195,6 @@ void GlyphAtlas::bind(gl::ObjectStore& store) {
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
}
};
diff --git a/src/mbgl/geometry/glyph_atlas.hpp b/src/mbgl/geometry/glyph_atlas.hpp
index cfe81f9991..d4a51761a1 100644
--- a/src/mbgl/geometry/glyph_atlas.hpp
+++ b/src/mbgl/geometry/glyph_atlas.hpp
@@ -3,6 +3,7 @@
#include <mbgl/geometry/binpack.hpp>
#include <mbgl/text/glyph_store.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/optional.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/object_store.hpp>
@@ -53,7 +54,7 @@ private:
std::unordered_map<FontStack, std::map<uint32_t, GlyphValue>, FontStackHash> index;
const std::unique_ptr<uint8_t[]> data;
std::atomic<bool> dirty;
- gl::TextureHolder texture;
+ mbgl::optional<gl::UniqueTexture> texture;
};
} // namespace mbgl
diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp
index 7069b5f678..830640f780 100644
--- a/src/mbgl/geometry/line_atlas.cpp
+++ b/src/mbgl/geometry/line_atlas.cpp
@@ -129,16 +129,16 @@ void LineAtlas::upload(gl::ObjectStore& store) {
void LineAtlas::bind(gl::ObjectStore& store) {
bool first = false;
- if (!texture.created()) {
- texture.create(store);
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
+ if (!texture) {
+ texture = store.createTexture();
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
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));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
first = true;
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
}
if (dirty) {
diff --git a/src/mbgl/geometry/line_atlas.hpp b/src/mbgl/geometry/line_atlas.hpp
index 8cff19eacf..0ca5e95a23 100644
--- a/src/mbgl/geometry/line_atlas.hpp
+++ b/src/mbgl/geometry/line_atlas.hpp
@@ -2,6 +2,7 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/object_store.hpp>
+#include <mbgl/util/optional.hpp>
#include <vector>
#include <map>
@@ -35,7 +36,7 @@ public:
private:
const std::unique_ptr<GLbyte[]> data;
bool dirty;
- gl::TextureHolder texture;
+ mbgl::optional<gl::UniqueTexture> texture;
int nextRow = 0;
std::map<size_t, LinePatternPos> positions;
};
diff --git a/src/mbgl/geometry/vao.cpp b/src/mbgl/geometry/vao.cpp
index 4bfe6b4909..46f10cb48c 100644
--- a/src/mbgl/geometry/vao.cpp
+++ b/src/mbgl/geometry/vao.cpp
@@ -26,10 +26,10 @@ void VertexArrayObject::bindVertexArrayObject(gl::ObjectStore& store) {
return;
}
- if (!vao.created()) {
- vao.create(store);
+ if (!vao) {
+ vao = store.createVAO();
}
- MBGL_CHECK_ERROR(gl::BindVertexArray(vao.getID()));
+ MBGL_CHECK_ERROR(gl::BindVertexArray(*vao));
}
void VertexArrayObject::verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer,
diff --git a/src/mbgl/geometry/vao.hpp b/src/mbgl/geometry/vao.hpp
index 8c1edb4d29..150a6badbd 100644
--- a/src/mbgl/geometry/vao.hpp
+++ b/src/mbgl/geometry/vao.hpp
@@ -4,6 +4,7 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/object_store.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/optional.hpp>
#include <stdexcept>
@@ -24,7 +25,7 @@ public:
if (bound_shader == 0) {
vertexBuffer.bind(store);
shader.bind(offset);
- if (vao.created()) {
+ if (vao) {
storeBinding(shader, vertexBuffer.getID(), 0, offset);
}
} else {
@@ -39,7 +40,7 @@ public:
vertexBuffer.bind(store);
elementsBuffer.bind(store);
shader.bind(offset);
- if (vao.created()) {
+ if (vao) {
storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
}
} else {
@@ -48,7 +49,7 @@ public:
}
GLuint getID() const {
- return vao.getID();
+ return *vao;
}
private:
@@ -56,7 +57,7 @@ private:
void storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset);
void verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset);
- gl::VAOHolder vao;
+ mbgl::optional<gl::UniqueVAO> vao;
// For debug reasons, we're storing the bind information so that we can
// detect errors and report
diff --git a/src/mbgl/gl/object_store.cpp b/src/mbgl/gl/object_store.cpp
index f52cc26f85..3072296a1e 100644
--- a/src/mbgl/gl/object_store.cpp
+++ b/src/mbgl/gl/object_store.cpp
@@ -5,79 +5,39 @@
namespace mbgl {
namespace gl {
-void ProgramHolder::create(ObjectStore& objectStore_) {
- if (created()) return;
- objectStore = &objectStore_;
- id = MBGL_CHECK_ERROR(glCreateProgram());
+void ProgramDeleter::operator()(GLuint id) const {
+ assert(store);
+ store->abandonedPrograms.push_back(id);
}
-void ProgramHolder::reset() {
- if (!created()) return;
- objectStore->abandonedPrograms.push_back(id);
- id = 0;
+void ShaderDeleter::operator()(GLuint id) const {
+ assert(store);
+ store->abandonedShaders.push_back(id);
}
-void ShaderHolder::create(ObjectStore& objectStore_) {
- if (created()) return;
- objectStore = &objectStore_;
- id = MBGL_CHECK_ERROR(glCreateShader(type));
+void BufferDeleter::operator()(GLuint id) const {
+ assert(store);
+ store->abandonedBuffers.push_back(id);
}
-void ShaderHolder::reset() {
- if (!created()) return;
- objectStore->abandonedShaders.push_back(id);
- id = 0;
+void TextureDeleter::operator()(GLuint id) const {
+ assert(store);
+ store->abandonedTextures.push_back(id);
}
-void BufferHolder::create(ObjectStore& objectStore_) {
- if (created()) return;
- objectStore = &objectStore_;
- MBGL_CHECK_ERROR(glGenBuffers(1, &id));
+void VAODeleter::operator()(GLuint id) const {
+ assert(store);
+ store->abandonedVAOs.push_back(id);
}
-void BufferHolder::reset() {
- if (!created()) return;
- objectStore->abandonedBuffers.push_back(id);
- id = 0;
-}
-
-void TextureHolder::create(ObjectStore& objectStore_) {
- if (created()) return;
- objectStore = &objectStore_;
- MBGL_CHECK_ERROR(glGenTextures(1, &id));
-}
-
-void TextureHolder::reset() {
- if (!created()) return;
- objectStore->abandonedTextures.push_back(id);
- id = 0;
-}
-
-void TexturePoolHolder::create(ObjectStore& objectStore_) {
- if (created()) return;
- objectStore = &objectStore_;
- MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data()));
-}
-
-void TexturePoolHolder::reset() {
- if (!created()) return;
+void TexturePoolDeleter::operator()(ObjectPool ids) const {
+ assert(store);
for (GLuint& id : ids) {
- if (id == 0) continue;
- objectStore->abandonedTextures.push_back(id);
- id = 0;
- };
-}
-
-void VAOHolder::create(ObjectStore& objectStore_) {
- if (created()) return;
- objectStore = &objectStore_;
- MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id));
-}
-
-void VAOHolder::reset() {
- if (!created()) return;
- objectStore->abandonedVAOs.push_back(id);
- id = 0;
+ if (id) {
+ store->abandonedTextures.push_back(id);
+ id = 0;
+ };
+ }
}
ObjectStore::~ObjectStore() {
diff --git a/src/mbgl/gl/object_store.hpp b/src/mbgl/gl/object_store.hpp
index a92f082b76..8c798f1688 100644
--- a/src/mbgl/gl/object_store.hpp
+++ b/src/mbgl/gl/object_store.hpp
@@ -3,6 +3,8 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <unique_resource.hpp>
+
#include <array>
#include <algorithm>
#include <memory>
@@ -11,127 +13,102 @@
namespace mbgl {
namespace gl {
-class ObjectStore : private util::noncopyable {
-public:
- ~ObjectStore();
-
- // 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();
+constexpr GLsizei TextureMax = 64;
-private:
- friend class ProgramHolder;
- friend class ShaderHolder;
- friend class BufferHolder;
- friend class TextureHolder;
- friend class TexturePoolHolder;
- friend class VAOHolder;
+class ObjectStore;
- std::vector<GLuint> abandonedPrograms;
- std::vector<GLuint> abandonedShaders;
- std::vector<GLuint> abandonedBuffers;
- std::vector<GLuint> abandonedTextures;
- std::vector<GLuint> abandonedVAOs;
+struct ProgramDeleter {
+ ObjectStore* store;
+ void operator()(GLuint id) const;
};
-class GLHolder : private util::noncopyable {
-public:
- GLHolder() {}
-
- GLHolder(GLHolder&& o) noexcept : id(o.id), objectStore(o.objectStore) { o.id = 0; }
- GLHolder& operator=(GLHolder&& o) noexcept { id = o.id; objectStore = o.objectStore; o.id = 0; return *this; }
-
- bool created() const { return id; }
- GLuint getID() const { return id; }
-
-protected:
- GLuint id = 0;
- ObjectStore* objectStore = nullptr;
+struct ShaderDeleter {
+ ObjectStore* store;
+ void operator()(GLuint id) const;
};
-class ProgramHolder : public GLHolder {
-public:
- ProgramHolder() = default;
- ~ProgramHolder() { reset(); }
-
- ProgramHolder(ProgramHolder&& o) noexcept : GLHolder(std::move(o)) {}
- ProgramHolder& operator=(ProgramHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
-
- void create(ObjectStore&);
- void reset();
+struct BufferDeleter {
+ ObjectStore* store;
+ void operator()(GLuint id) const;
};
-class ShaderHolder : public GLHolder {
-public:
- ShaderHolder(GLenum type_) : type(type_) {}
- ~ShaderHolder() { reset(); }
-
- 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(ObjectStore&);
- void reset();
-
-private:
- GLenum type = 0;
+struct TextureDeleter {
+ ObjectStore* store;
+ void operator()(GLuint id) const;
};
-class BufferHolder : public GLHolder {
-public:
- BufferHolder() = default;
- ~BufferHolder() { reset(); }
-
- BufferHolder(BufferHolder&& o) noexcept : GLHolder(std::move(o)) {}
- BufferHolder& operator=(BufferHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
-
- void create(ObjectStore&);
- void reset();
+struct VAODeleter {
+ ObjectStore* store;
+ void operator()(GLuint id) const;
};
-class TextureHolder : public GLHolder {
-public:
- TextureHolder() = default;
- ~TextureHolder() { reset(); }
-
- TextureHolder(TextureHolder&& o) noexcept : GLHolder(std::move(o)) {}
- TextureHolder& operator=(TextureHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
+using ObjectPool = std::array<GLuint, TextureMax>;
- void create(ObjectStore&);
- void reset();
+struct TexturePoolDeleter {
+ ObjectStore* store;
+ void operator()(ObjectPool ids) const;
};
-class TexturePoolHolder : private util::noncopyable {
-public:
- static const GLsizei TextureMax = 64;
-
- TexturePoolHolder() { ids.fill(0); }
- ~TexturePoolHolder() { reset(); }
+using UniqueProgram = std_experimental::unique_resource<GLuint, ProgramDeleter>;
+using UniqueShader = std_experimental::unique_resource<GLuint, ShaderDeleter>;
+using UniqueBuffer = std_experimental::unique_resource<GLuint, BufferDeleter>;
+using UniqueTexture = std_experimental::unique_resource<GLuint, TextureDeleter>;
+using UniqueVAO = std_experimental::unique_resource<GLuint, VAODeleter>;
+using UniqueTexturePool = std_experimental::unique_resource<ObjectPool, TexturePoolDeleter>;
- TexturePoolHolder(TexturePoolHolder&& o) noexcept : ids(std::move(o.ids)), objectStore(o.objectStore) { o.ids.fill(0); }
- TexturePoolHolder& operator=(TexturePoolHolder&& o) noexcept { ids = std::move(o.ids); objectStore = o.objectStore; o.ids.fill(0); return *this; }
+class ObjectStore : private util::noncopyable {
+public:
+ ~ObjectStore();
- bool created() const { return std::any_of(ids.begin(), ids.end(), [](int id) { return id; }); }
- const std::array<GLuint, TextureMax>& getIDs() const { return ids; }
- const GLuint& operator[](size_t pos) { return ids[pos]; }
+ UniqueProgram createProgram() {
+ return UniqueProgram(MBGL_CHECK_ERROR(glCreateProgram()), { this });
+ }
+
+ UniqueShader createShader(GLenum type) {
+ return UniqueShader(MBGL_CHECK_ERROR(glCreateShader(type)), { this });
+ }
+
+ UniqueBuffer createBuffer() {
+ GLuint id = 0;
+ MBGL_CHECK_ERROR(glGenBuffers(1, &id));
+ return UniqueBuffer(std::move(id), { this });
+ }
+
+ UniqueTexture createTexture() {
+ GLuint id = 0;
+ MBGL_CHECK_ERROR(glGenTextures(1, &id));
+ return UniqueTexture(std::move(id), { this });
+ }
+
+ UniqueVAO createVAO() {
+ GLuint id = 0;
+ MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id));
+ return UniqueVAO(std::move(id), { this });
+ }
+
+ UniqueTexturePool createTexturePool() {
+ ObjectPool ids;
+ MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data()));
+ return UniqueTexturePool(std::move(ids), { this });
+ }
- void create(ObjectStore&);
- void reset();
+ // 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:
- std::array<GLuint, TextureMax> ids;
- ObjectStore* objectStore = nullptr;
-};
-
-class VAOHolder : public GLHolder {
-public:
- VAOHolder() = default;
- ~VAOHolder() { reset(); }
+ friend ProgramDeleter;
+ friend ShaderDeleter;
+ friend BufferDeleter;
+ friend TextureDeleter;
+ friend VAODeleter;
+ friend TexturePoolDeleter;
- VAOHolder(VAOHolder&& o) noexcept : GLHolder(std::move(o)) {}
- VAOHolder& operator=(VAOHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
-
- void create(ObjectStore&);
- void reset();
+ std::vector<GLuint> abandonedPrograms;
+ std::vector<GLuint> abandonedShaders;
+ std::vector<GLuint> abandonedBuffers;
+ std::vector<GLuint> abandonedTextures;
+ std::vector<GLuint> abandonedVAOs;
};
} // namespace gl
diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp
index c04f781daa..915e73f82a 100644
--- a/src/mbgl/gl/texture_pool.cpp
+++ b/src/mbgl/gl/texture_pool.cpp
@@ -25,10 +25,10 @@ GLuint TexturePool::getTextureID(gl::ObjectStore& store) {
void TexturePool::releaseTextureID(GLuint id) {
for (auto it = pools.begin(); it != pools.end(); ++it) {
- for (GLsizei i = 0; i < gl::TexturePoolHolder::TextureMax; ++i) {
- if (it->pool[i] == id) {
+ for (GLsizei i = 0; i < gl::TextureMax; ++i) {
+ if (it->pool.get()[i] == id) {
it->ids.push_back(id);
- if (GLsizei(it->ids.size()) == gl::TexturePoolHolder::TextureMax) {
+ if (GLsizei(it->ids.size()) == gl::TextureMax) {
pools.erase(it);
}
return;
diff --git a/src/mbgl/gl/texture_pool.hpp b/src/mbgl/gl/texture_pool.hpp
index 2c5610cf4a..549b5ce144 100644
--- a/src/mbgl/gl/texture_pool.hpp
+++ b/src/mbgl/gl/texture_pool.hpp
@@ -19,15 +19,14 @@ public:
private:
class Impl : private util::noncopyable {
public:
- Impl(gl::ObjectStore& store) : ids(gl::TexturePoolHolder::TextureMax) {
- pool.create(store);
- std::copy(pool.getIDs().begin(), pool.getIDs().end(), ids.begin());
+ Impl(gl::ObjectStore& store) : pool(store.createTexturePool()), ids(gl::TextureMax) {
+ std::copy(pool.get().begin(), pool.get().end(), ids.begin());
}
Impl(Impl&& o) : pool(std::move(o.pool)), ids(std::move(o.ids)) {}
Impl& operator=(Impl&& o) { pool = std::move(o.pool); ids = std::move(o.ids); return *this; }
- gl::TexturePoolHolder pool;
+ gl::UniqueTexturePool pool;
std::vector<GLuint> ids;
};
diff --git a/src/mbgl/renderer/frame_history.cpp b/src/mbgl/renderer/frame_history.cpp
index 95d971dfde..dbaf8fbf7a 100644
--- a/src/mbgl/renderer/frame_history.cpp
+++ b/src/mbgl/renderer/frame_history.cpp
@@ -60,7 +60,7 @@ bool FrameHistory::needsAnimation(const Duration& duration) const {
void FrameHistory::upload(gl::ObjectStore& store) {
if (changed) {
- const bool first = !texture.created();
+ const bool first = !texture;
bind(store);
if (first) {
@@ -95,9 +95,9 @@ void FrameHistory::upload(gl::ObjectStore& store) {
}
void FrameHistory::bind(gl::ObjectStore& store) {
- if (!texture.created()) {
- texture.create(store);
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
+ if (!texture) {
+ texture = store.createTexture();
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
@@ -106,7 +106,7 @@ void FrameHistory::bind(gl::ObjectStore& store) {
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
}
}
diff --git a/src/mbgl/renderer/frame_history.hpp b/src/mbgl/renderer/frame_history.hpp
index 16f30fe8d0..04ebe23276 100644
--- a/src/mbgl/renderer/frame_history.hpp
+++ b/src/mbgl/renderer/frame_history.hpp
@@ -5,6 +5,7 @@
#include <mbgl/platform/platform.hpp>
#include <mbgl/gl/object_store.hpp>
#include <mbgl/util/chrono.hpp>
+#include <mbgl/util/optional.hpp>
namespace mbgl {
@@ -31,7 +32,7 @@ private:
bool firstFrame = true;
bool changed = true;
- gl::TextureHolder texture;
+ mbgl::optional<gl::UniqueTexture> texture;
};
} // namespace mbgl
diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp
index a4c6719bba..23ea043720 100644
--- a/src/mbgl/shader/shader.cpp
+++ b/src/mbgl/shader/shader.cpp
@@ -15,68 +15,68 @@ namespace mbgl {
Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSource, gl::ObjectStore& store)
: name(name_)
+ , program(store.createProgram())
+ , vertexShader(store.createShader(GL_VERTEX_SHADER))
+ , fragmentShader(store.createShader(GL_FRAGMENT_SHADER))
{
util::stopwatch stopwatch("shader compilation", Event::Shader);
- program.create(store);
- vertexShader.create(store);
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(store);
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");
}
// Attach shaders
- MBGL_CHECK_ERROR(glAttachShader(program.getID(), vertexShader.getID()));
- MBGL_CHECK_ERROR(glAttachShader(program.getID(), fragmentShader.getID()));
+ MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get()));
+ MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get()));
{
// Link program
GLint status;
- MBGL_CHECK_ERROR(glLinkProgram(program.getID()));
+ MBGL_CHECK_ERROR(glLinkProgram(program.get()));
- MBGL_CHECK_ERROR(glGetProgramiv(program.getID(), GL_LINK_STATUS, &status));
+ MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_LINK_STATUS, &status));
if (status == 0) {
GLint logLength;
- MBGL_CHECK_ERROR(glGetProgramiv(program.getID(), GL_INFO_LOG_LENGTH, &logLength));
+ MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &logLength));
const auto log = std::make_unique<GLchar[]>(logLength);
if (logLength > 0) {
- MBGL_CHECK_ERROR(glGetProgramInfoLog(program.getID(), logLength, &logLength, log.get()));
+ MBGL_CHECK_ERROR(glGetProgramInfoLog(program.get(), logLength, &logLength, log.get()));
Log::Error(Event::Shader, "Program failed to link: %s", log.get());
}
throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get());
}
}
- a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program.getID(), "a_pos"));
+ a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program.get(), "a_pos"));
}
-bool Shader::compileShader(gl::ShaderHolder& shader, const GLchar *source[]) {
+bool Shader::compileShader(gl::UniqueShader& shader, const GLchar *source[]) {
GLint status = 0;
const GLsizei lengths = static_cast<GLsizei>(std::strlen(*source));
- MBGL_CHECK_ERROR(glShaderSource(shader.getID(), 1, source, &lengths));
+ MBGL_CHECK_ERROR(glShaderSource(shader.get(), 1, source, &lengths));
- MBGL_CHECK_ERROR(glCompileShader(shader.getID()));
+ MBGL_CHECK_ERROR(glCompileShader(shader.get()));
- MBGL_CHECK_ERROR(glGetShaderiv(shader.getID(), GL_COMPILE_STATUS, &status));
+ MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status));
if (status == 0) {
GLint logLength;
- MBGL_CHECK_ERROR(glGetShaderiv(shader.getID(), GL_INFO_LOG_LENGTH, &logLength));
+ MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_INFO_LOG_LENGTH, &logLength));
if (logLength > 0) {
const auto log = std::make_unique<GLchar[]>(logLength);
- MBGL_CHECK_ERROR(glGetShaderInfoLog(shader.getID(), logLength, &logLength, log.get()));
+ MBGL_CHECK_ERROR(glGetShaderInfoLog(shader.get(), logLength, &logLength, log.get()));
Log::Error(Event::Shader, "Shader failed to compile: %s", log.get());
}
return false;
}
- MBGL_CHECK_ERROR(glGetShaderiv(shader.getID(), GL_COMPILE_STATUS, &status));
+ MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status));
if (status == GL_FALSE) {
Log::Error(Event::Shader, "Shader %s failed to compile.", name);
return false;
@@ -86,9 +86,9 @@ bool Shader::compileShader(gl::ShaderHolder& shader, const GLchar *source[]) {
}
Shader::~Shader() {
- if (program.created()) {
- MBGL_CHECK_ERROR(glDetachShader(program.getID(), vertexShader.getID()));
- MBGL_CHECK_ERROR(glDetachShader(program.getID(), fragmentShader.getID()));
+ if (program.get()) {
+ MBGL_CHECK_ERROR(glDetachShader(program.get(), vertexShader.get()));
+ MBGL_CHECK_ERROR(glDetachShader(program.get(), fragmentShader.get()));
}
}
diff --git a/src/mbgl/shader/shader.hpp b/src/mbgl/shader/shader.hpp
index b9ca09e61b..1cb2a5601f 100644
--- a/src/mbgl/shader/shader.hpp
+++ b/src/mbgl/shader/shader.hpp
@@ -14,7 +14,7 @@ public:
const GLchar *name;
GLuint getID() const {
- return program.getID();
+ return program.get();
}
virtual void bind(GLbyte *offset) = 0;
@@ -23,11 +23,11 @@ protected:
GLint a_pos = -1;
private:
- bool compileShader(gl::ShaderHolder&, const GLchar *source[]);
+ bool compileShader(gl::UniqueShader&, const GLchar *source[]);
- gl::ProgramHolder program;
- gl::ShaderHolder vertexShader = { GL_VERTEX_SHADER };
- gl::ShaderHolder fragmentShader = { GL_FRAGMENT_SHADER };
+ gl::UniqueProgram program;
+ gl::UniqueShader vertexShader;
+ gl::UniqueShader fragmentShader;
};
} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
index d4d462b339..5d7d01deb3 100644
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ b/src/mbgl/sprite/sprite_atlas.cpp
@@ -142,9 +142,9 @@ void SpriteAtlas::copy(const Holder& holder, const bool wrap) {
dirty = true;
}
-void SpriteAtlas::upload(gl::ObjectStore& store) {
+void SpriteAtlas::upload(gl::ObjectStore& objectStore) {
if (dirty) {
- bind(false, store);
+ bind(false, objectStore);
}
}
@@ -179,14 +179,14 @@ void SpriteAtlas::updateDirty() {
}
}
-void SpriteAtlas::bind(bool linear, gl::ObjectStore& store) {
+void SpriteAtlas::bind(bool linear, gl::ObjectStore& objectStore) {
if (!data) {
return; // Empty atlas
}
- if (!texture.created()) {
- texture.create(store);
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
+ if (!texture) {
+ texture = objectStore.createTexture();
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
@@ -196,7 +196,7 @@ void SpriteAtlas::bind(bool linear, gl::ObjectStore& store) {
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
fullUploadRequired = true;
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
}
GLuint filter_val = linear ? GL_LINEAR : GL_NEAREST;
diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp
index 6bbdee190d..249b863c92 100644
--- a/src/mbgl/sprite/sprite_atlas.hpp
+++ b/src/mbgl/sprite/sprite_atlas.hpp
@@ -94,7 +94,7 @@ private:
std::unique_ptr<uint32_t[]> data;
std::atomic<bool> dirty;
bool fullUploadRequired = true;
- gl::TextureHolder texture;
+ mbgl::optional<gl::UniqueTexture> texture;
uint32_t filter = 0;
static const int buffer = 1;
};