Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Use unique_resource for GL objects
Browse files Browse the repository at this point in the history
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 #5141 (comment).
  • Loading branch information
brunoabinader committed Jun 1, 2016
1 parent 2038a21 commit 1b0683b
Show file tree
Hide file tree
Showing 17 changed files with 175 additions and 234 deletions.
17 changes: 9 additions & 8 deletions src/mbgl/geometry/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -36,11 +37,11 @@ class Buffer : private util::noncopyable {

// 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;
Expand All @@ -60,20 +61,20 @@ class Buffer : private util::noncopyable {
}

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);
}
}

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) {
Expand Down Expand Up @@ -114,7 +115,7 @@ class Buffer : private util::noncopyable {
size_t length = 0;

// GL buffer object handle.
gl::BufferHolder buffer;
mbgl::optional<gl::UniqueBuffer> buffer;
};

} // namespace mbgl
10 changes: 5 additions & 5 deletions src/mbgl/geometry/glyph_atlas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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));
}
};
3 changes: 2 additions & 1 deletion src/mbgl/geometry/glyph_atlas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -53,7 +54,7 @@ class GlyphAtlas : public util::noncopyable {
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
8 changes: 4 additions & 4 deletions src/mbgl/geometry/line_atlas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/geometry/line_atlas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/object_store.hpp>
#include <mbgl/util/optional.hpp>

#include <vector>
#include <map>
Expand Down Expand Up @@ -35,7 +36,7 @@ class LineAtlas {
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;
};
Expand Down
6 changes: 3 additions & 3 deletions src/mbgl/geometry/vao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 5 additions & 4 deletions src/mbgl/geometry/vao.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -24,7 +25,7 @@ class VertexArrayObject : public util::noncopyable {
if (bound_shader == 0) {
vertexBuffer.bind(store);
shader.bind(offset);
if (vao.created()) {
if (vao) {
storeBinding(shader, vertexBuffer.getID(), 0, offset);
}
} else {
Expand All @@ -39,7 +40,7 @@ class VertexArrayObject : public util::noncopyable {
vertexBuffer.bind(store);
elementsBuffer.bind(store);
shader.bind(offset);
if (vao.created()) {
if (vao) {
storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
}
} else {
Expand All @@ -48,15 +49,15 @@ class VertexArrayObject : public util::noncopyable {
}

GLuint getID() const {
return vao.getID();
return *vao;
}

private:
void bindVertexArrayObject(gl::ObjectStore&);
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
Expand Down
84 changes: 22 additions & 62 deletions src/mbgl/gl/object_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
Loading

0 comments on commit 1b0683b

Please sign in to comment.