summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-02-14 17:55:39 +0200
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-02-18 13:27:35 +0200
commit69fa8fe3c0cc2a53b9ba4bb9d31cdabd2cbd373e (patch)
tree8d13a986c49d3005c3bb397930ca191024c5fbeb /src
parentbfafc360a7257f57999edbcbd484a0e18b40798a (diff)
downloadqtlocation-mapboxgl-69fa8fe3c0cc2a53b9ba4bb9d31cdabd2cbd373e.tar.gz
[gl] Added mbgl::gl::ProgramHolder
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/gl/gl_object_store.cpp15
-rw-r--r--src/mbgl/gl/gl_object_store.hpp29
-rw-r--r--src/mbgl/shader/shader.cpp34
-rw-r--r--src/mbgl/shader/shader.hpp11
4 files changed, 59 insertions, 30 deletions
diff --git a/src/mbgl/gl/gl_object_store.cpp b/src/mbgl/gl/gl_object_store.cpp
index a830b6d73e..52cf03d04b 100644
--- a/src/mbgl/gl/gl_object_store.cpp
+++ b/src/mbgl/gl/gl_object_store.cpp
@@ -1,5 +1,5 @@
#include <mbgl/gl/gl_object_store.hpp>
-
+#include <mbgl/util/thread_context.hpp>
#include <mbgl/util/thread.hpp>
#include <mbgl/geometry/vao.hpp>
#include <mbgl/gl/gl.hpp>
@@ -9,6 +9,19 @@
namespace mbgl {
namespace gl {
+void ProgramHolder::create() {
+ if (id) return;
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ id = MBGL_CHECK_ERROR(glCreateProgram());
+}
+
+void ProgramHolder::reset() {
+ if (!id) return;
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ MBGL_CHECK_ERROR(glDeleteProgram(id));
+ id = 0;
+}
+
void GLObjectStore::abandonVAO(GLuint vao) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
abandonedVAOs.emplace_back(vao);
diff --git a/src/mbgl/gl/gl_object_store.hpp b/src/mbgl/gl/gl_object_store.hpp
index ac8ddd2748..be25728660 100644
--- a/src/mbgl/gl/gl_object_store.hpp
+++ b/src/mbgl/gl/gl_object_store.hpp
@@ -4,15 +4,40 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <memory>
#include <vector>
namespace mbgl {
namespace gl {
-class GLObjectStore : private util::noncopyable {
+class GLHolder : private util::noncopyable {
+public:
+ GLHolder() {}
+
+ GLHolder(GLHolder&& o) noexcept : id(o.id) { o.id = 0; }
+ GLHolder& operator=(GLHolder&& o) noexcept { id = o.id; o.id = 0; return *this; }
+
+ explicit operator bool() const { return id; }
+ GLuint getID() const { return id; }
+
+protected:
+ GLuint id = 0;
+};
+
+class ProgramHolder : public GLHolder {
public:
- GLObjectStore() = default;
+ 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();
+ void reset();
+};
+class GLObjectStore : private util::noncopyable {
+public:
// Mark OpenGL objects for deletion
void abandonVAO(GLuint vao);
void abandonBuffer(GLuint buffer);
diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp
index fbf758d3bf..c0757b749a 100644
--- a/src/mbgl/shader/shader.cpp
+++ b/src/mbgl/shader/shader.cpp
@@ -15,16 +15,14 @@ using namespace mbgl;
Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSource)
: name(name_)
- , program(0)
{
util::stopwatch stopwatch("shader compilation", Event::Shader);
- program = MBGL_CHECK_ERROR(glCreateProgram());
+ program.create();
if (!compileShader(&vertShader, GL_VERTEX_SHADER, &vertSource)) {
Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertSource);
- MBGL_CHECK_ERROR(glDeleteProgram(program));
- program = 0;
+ program.reset();
throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile");
}
@@ -32,27 +30,26 @@ Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSo
Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragSource);
MBGL_CHECK_ERROR(glDeleteShader(vertShader));
vertShader = 0;
- MBGL_CHECK_ERROR(glDeleteProgram(program));
- program = 0;
+ program.reset();
throw util::ShaderException(std::string { "Fragment shader " } + name + " failed to compile");
}
// Attach shaders
- MBGL_CHECK_ERROR(glAttachShader(program, vertShader));
- MBGL_CHECK_ERROR(glAttachShader(program, fragShader));
+ MBGL_CHECK_ERROR(glAttachShader(program.getID(), vertexShader));
+ MBGL_CHECK_ERROR(glAttachShader(program.getID(), fragmentShader));
{
// Link program
GLint status;
- MBGL_CHECK_ERROR(glLinkProgram(program));
+ MBGL_CHECK_ERROR(glLinkProgram(program.getID()));
- MBGL_CHECK_ERROR(glGetProgramiv(program, GL_LINK_STATUS, &status));
+ MBGL_CHECK_ERROR(glGetProgramiv(program.getID(), GL_LINK_STATUS, &status));
if (status == 0) {
GLint logLength;
- MBGL_CHECK_ERROR(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength));
+ MBGL_CHECK_ERROR(glGetProgramiv(program.getID(), GL_INFO_LOG_LENGTH, &logLength));
const auto log = std::make_unique<GLchar[]>(logLength);
if (logLength > 0) {
- MBGL_CHECK_ERROR(glGetProgramInfoLog(program, logLength, &logLength, log.get()));
+ MBGL_CHECK_ERROR(glGetProgramInfoLog(program.getID(), logLength, &logLength, log.get()));
Log::Error(Event::Shader, "Program failed to link: %s", log.get());
}
@@ -60,13 +57,12 @@ Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSo
vertShader = 0;
MBGL_CHECK_ERROR(glDeleteShader(fragShader));
fragShader = 0;
- MBGL_CHECK_ERROR(glDeleteProgram(program));
- program = 0;
- throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get());
+ program.reset();
+ throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get());
}
}
- a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_pos"));
+ a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program.getID(), "a_pos"));
}
@@ -107,10 +103,8 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source[])
Shader::~Shader() {
if (program) {
- MBGL_CHECK_ERROR(glDetachShader(program, vertShader));
- MBGL_CHECK_ERROR(glDetachShader(program, fragShader));
- MBGL_CHECK_ERROR(glDeleteProgram(program));
- program = 0;
+ MBGL_CHECK_ERROR(glDetachShader(program.getID(), vertexShader));
+ MBGL_CHECK_ERROR(glDetachShader(program.getID(), fragmentShader));
MBGL_CHECK_ERROR(glDeleteShader(vertShader));
vertShader = 0;
MBGL_CHECK_ERROR(glDeleteShader(fragShader));
diff --git a/src/mbgl/shader/shader.hpp b/src/mbgl/shader/shader.hpp
index 0570b1c642..b3d694a04f 100644
--- a/src/mbgl/shader/shader.hpp
+++ b/src/mbgl/shader/shader.hpp
@@ -2,12 +2,9 @@
#define MBGL_RENDERER_SHADER
#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <cstdint>
-#include <array>
-#include <string>
-
namespace mbgl {
class Shader : private util::noncopyable {
@@ -16,10 +13,9 @@ public:
~Shader();
const GLchar *name;
- GLuint program;
- inline GLuint getID() const {
- return program;
+ inline const GLuint& getID() const {
+ return program.getID();
}
virtual void bind(GLbyte *offset) = 0;
@@ -30,6 +26,7 @@ protected:
private:
bool compileShader(GLuint *shader, GLenum type, const GLchar *source[]);
+ gl::ProgramHolder program;
GLuint vertShader = 0;
GLuint fragShader = 0;
};