summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-02-14 18:45:10 +0200
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-02-18 13:27:35 +0200
commit3397398c1f5f05e22219557e0e81cfe61d693b33 (patch)
tree39f60b3cd5b5c92d2ba783c94274c8f132e5bd3b /src
parenta503233d1c8df79b02e74b93e49a7e02f58f182a (diff)
downloadqtlocation-mapboxgl-3397398c1f5f05e22219557e0e81cfe61d693b33.tar.gz
[gl] Added mbgl::gl::BufferHolder
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/geometry/buffer.hpp20
-rw-r--r--src/mbgl/gl/gl_object_store.cpp25
-rw-r--r--src/mbgl/gl/gl_object_store.hpp18
3 files changed, 43 insertions, 20 deletions
diff --git a/src/mbgl/geometry/buffer.hpp b/src/mbgl/geometry/buffer.hpp
index df4c6a322d..a84af91e2e 100644
--- a/src/mbgl/geometry/buffer.hpp
+++ b/src/mbgl/geometry/buffer.hpp
@@ -2,11 +2,12 @@
#define MBGL_GEOMETRY_BUFFER
#include <mbgl/gl/gl.hpp>
-#include <mbgl/platform/log.hpp>
#include <mbgl/gl/gl_object_store.hpp>
+#include <mbgl/platform/log.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/thread_context.hpp>
+#include <memory>
#include <cstdlib>
#include <cassert>
#include <stdexcept>
@@ -23,9 +24,8 @@ class Buffer : private util::noncopyable {
public:
~Buffer() {
cleanup();
- if (buffer != 0) {
- util::ThreadContext::getGLObjectStore()->abandonBuffer(buffer);
- buffer = 0;
+ if (buffer) {
+ util::ThreadContext::getGLObjectStore()->abandon(std::move(buffer));
}
}
@@ -44,7 +44,7 @@ public:
if (buffer) {
MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID()));
} else {
- MBGL_CHECK_ERROR(glGenBuffers(1, &buffer));
+ buffer.create();
MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID()));
if (array == nullptr) {
Log::Debug(Event::OpenGL, "Buffer doesn't contain elements");
@@ -64,8 +64,8 @@ public:
}
}
- inline GLuint getID() const {
- return buffer;
+ GLuint getID() const {
+ return buffer.getID();
}
// Uploads the buffer to the GPU to be available when we need it.
@@ -78,7 +78,7 @@ public:
protected:
// increase the buffer size by at least /required/ bytes.
inline void *addElement() {
- if (buffer != 0) {
+ if (buffer) {
throw std::runtime_error("Can't add elements after buffer was bound to GPU");
}
if (length < pos + itemSize) {
@@ -118,8 +118,8 @@ private:
// Number of bytes that are valid in this buffer.
size_t length = 0;
- // GL buffer ID
- GLuint buffer = 0;
+ // GL buffer object handle.
+ gl::BufferHolder buffer;
};
} // namespace mbgl
diff --git a/src/mbgl/gl/gl_object_store.cpp b/src/mbgl/gl/gl_object_store.cpp
index 7a6037d505..68d743cd95 100644
--- a/src/mbgl/gl/gl_object_store.cpp
+++ b/src/mbgl/gl/gl_object_store.cpp
@@ -35,15 +35,28 @@ void ShaderHolder::reset() {
id = 0;
}
+void BufferHolder::create() {
+ if (id) return;
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ 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));
+ id = 0;
+}
+
void GLObjectStore::abandonVAO(GLuint vao) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
abandonedVAOs.emplace_back(vao);
}
-void GLObjectStore::abandonBuffer(GLuint buffer) {
+void GLObjectStore::abandon(BufferHolder&& buffer) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
- abandonedBuffers.emplace_back(buffer);
+ abandonedBuffers.push_back(std::move(buffer));
}
void GLObjectStore::abandonTexture(GLuint texture) {
@@ -60,17 +73,13 @@ void GLObjectStore::performCleanup() {
abandonedVAOs.clear();
}
+ abandonedBuffers.clear();
+
if (!abandonedTextures.empty()) {
MBGL_CHECK_ERROR(glDeleteTextures(static_cast<GLsizei>(abandonedTextures.size()),
abandonedTextures.data()));
abandonedTextures.clear();
}
-
- if (!abandonedBuffers.empty()) {
- MBGL_CHECK_ERROR(glDeleteBuffers(static_cast<GLsizei>(abandonedBuffers.size()),
- abandonedBuffers.data()));
- abandonedBuffers.clear();
- }
}
} // namespace gl
diff --git a/src/mbgl/gl/gl_object_store.hpp b/src/mbgl/gl/gl_object_store.hpp
index 6c7f3c92f2..7b9409f329 100644
--- a/src/mbgl/gl/gl_object_store.hpp
+++ b/src/mbgl/gl/gl_object_store.hpp
@@ -51,11 +51,23 @@ private:
GLenum type = 0;
};
+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();
+ void reset();
+};
+
class GLObjectStore : private util::noncopyable {
public:
// Mark OpenGL objects for deletion
void abandonVAO(GLuint vao);
- void abandonBuffer(GLuint buffer);
+ void abandon(BufferHolder&&);
void abandonTexture(GLuint texture);
// Actually remove the objects we marked as abandoned with the above methods.
@@ -63,8 +75,10 @@ public:
void performCleanup();
private:
+ // We split the holder objects in separate containers because each
+ // GLHolder-derived object can vary in size.
std::vector<GLuint> abandonedVAOs;
- std::vector<GLuint> abandonedBuffers;
+ std::vector<BufferHolder> abandonedBuffers;
std::vector<GLuint> abandonedTextures;
};