diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-02-14 17:55:39 +0200 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-02-18 13:27:35 +0200 |
commit | 69fa8fe3c0cc2a53b9ba4bb9d31cdabd2cbd373e (patch) | |
tree | 8d13a986c49d3005c3bb397930ca191024c5fbeb /src | |
parent | bfafc360a7257f57999edbcbd484a0e18b40798a (diff) | |
download | qtlocation-mapboxgl-69fa8fe3c0cc2a53b9ba4bb9d31cdabd2cbd373e.tar.gz |
[gl] Added mbgl::gl::ProgramHolder
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/gl/gl_object_store.cpp | 15 | ||||
-rw-r--r-- | src/mbgl/gl/gl_object_store.hpp | 29 | ||||
-rw-r--r-- | src/mbgl/shader/shader.cpp | 34 | ||||
-rw-r--r-- | src/mbgl/shader/shader.hpp | 11 |
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; }; |