[gl] Added mbgl::gl::ProgramHolder
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -4,15 +4,40 @@
|
||||
#include <mbgl/gl/gl.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
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:
|
||||
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:
|
||||
GLObjectStore() = default;
|
||||
|
||||
// Mark OpenGL objects for deletion
|
||||
void abandonVAO(GLuint vao);
|
||||
void abandonBuffer(GLuint buffer);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user