[core] introduces types for GL objects

This commit is contained in:
Konstantin Käfer
2016-09-29 12:15:36 +02:00
committed by John Firebaugh
parent d1a84d9b51
commit 15aece8a30
15 changed files with 101 additions and 60 deletions

View File

@@ -22,6 +22,7 @@ typedef XID GLXPbuffer;
#include <mbgl/mbgl.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/types.hpp>
#include <memory>
#include <thread>
@@ -89,9 +90,9 @@ private:
std::function<void(MapChange)> mapChangeCallback;
GLuint fbo = 0;
GLuint fboDepthStencil = 0;
GLuint fboColor = 0;
gl::FramebufferID fbo = 0;
gl::RenderbufferID fboDepthStencil = 0;
gl::RenderbufferID fboColor = 0;
};
} // namespace mbgl

View File

@@ -70,7 +70,7 @@ public:
}
}
GLuint getID() const {
gl::BufferID getID() const {
return buffer ? *buffer : 0;
}

View File

@@ -28,8 +28,10 @@ void VertexArrayObject::bindVertexArrayObject(gl::Context& context) {
context.vertexArrayObject = *vertexArray;
}
void VertexArrayObject::verifyBinding(Shader& shader, GLuint vertexBuffer, GLuint elementsBuffer,
GLbyte *offset) {
void VertexArrayObject::verifyBinding(Shader& shader,
gl::BufferID vertexBuffer,
gl::BufferID elementsBuffer,
GLbyte* offset) {
if (bound_shader != shader.getID()) {
throw std::runtime_error(std::string("trying to rebind VAO to another shader from " +
util::toString(bound_shader) + "(" + bound_shader_name + ") to " +
@@ -43,8 +45,10 @@ void VertexArrayObject::verifyBinding(Shader& shader, GLuint vertexBuffer, GLuin
}
}
void VertexArrayObject::storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer,
GLbyte *offset) {
void VertexArrayObject::storeBinding(Shader& shader,
gl::BufferID vertexBuffer,
gl::BufferID elementsBuffer,
GLbyte* offset) {
bound_shader = shader.getID();
bound_shader_name = shader.name;
bound_offset = offset;

View File

@@ -51,23 +51,29 @@ public:
}
}
GLuint getID() const {
gl::VertexArrayID getID() const {
return *vertexArray;
}
private:
void bindVertexArrayObject(gl::Context&);
void storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset);
void verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset);
void storeBinding(Shader& shader,
gl::BufferID vertexBuffer,
gl::BufferID elementsBuffer,
GLbyte* offset);
void verifyBinding(Shader& shader,
gl::BufferID vertexBuffer,
gl::BufferID elementsBuffer,
GLbyte* offset);
mbgl::optional<gl::UniqueVertexArray> vertexArray;
// For debug reasons, we're storing the bind information so that we can
// detect errors and report
GLuint bound_shader = 0;
gl::ProgramID bound_shader = 0;
const char* bound_shader_name = "";
GLuint bound_vertex_buffer = 0;
GLuint bound_elements_buffer = 0;
gl::BufferID bound_vertex_buffer = 0;
gl::BufferID bound_elements_buffer = 0;
GLbyte *bound_offset = nullptr;
};

View File

@@ -3,6 +3,14 @@
namespace mbgl {
namespace gl {
static_assert(std::is_same<ProgramID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<ShaderID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<BufferID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<TextureID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<VertexArrayID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<FramebufferID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<RenderbufferID, GLuint>::value, "OpenGL type mismatch");
Context::~Context() {
reset();
}
@@ -60,7 +68,7 @@ void Context::setDirtyState() {
}
void Context::performCleanup() {
for (GLuint id : abandonedPrograms) {
for (auto id : abandonedPrograms) {
if (program == id) {
program.setDirty();
}
@@ -68,7 +76,7 @@ void Context::performCleanup() {
}
abandonedPrograms.clear();
for (GLuint id : abandonedShaders) {
for (auto id : abandonedShaders) {
MBGL_CHECK_ERROR(glDeleteShader(id));
}
abandonedShaders.clear();

View File

@@ -21,12 +21,16 @@ public:
return UniqueProgram { MBGL_CHECK_ERROR(glCreateProgram()), { this } };
}
UniqueShader createShader(GLenum type) {
return UniqueShader { MBGL_CHECK_ERROR(glCreateShader(type)), { this } };
UniqueShader createVertexShader() {
return UniqueShader { MBGL_CHECK_ERROR(glCreateShader(GL_VERTEX_SHADER)), { this } };
}
UniqueShader createFragmentShader() {
return UniqueShader { MBGL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER)), { this } };
}
UniqueBuffer createBuffer() {
GLuint id = 0;
BufferID id = 0;
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
return UniqueBuffer { std::move(id), { this } };
}
@@ -37,19 +41,19 @@ public:
MBGL_CHECK_ERROR(glGenTextures(TextureMax, pooledTextures.data()));
}
GLuint id = pooledTextures.back();
TextureID id = pooledTextures.back();
pooledTextures.pop_back();
return UniqueTexture { std::move(id), { this } };
}
UniqueVertexArray createVertexArray() {
GLuint id = 0;
VertexArrayID id = 0;
MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id));
return UniqueVertexArray { std::move(id), { this } };
}
UniqueFramebuffer createFramebuffer() {
GLuint id = 0;
FramebufferID id = 0;
MBGL_CHECK_ERROR(glGenFramebuffers(1, &id));
return UniqueFramebuffer { std::move(id), { this } };
}
@@ -113,14 +117,14 @@ private:
friend detail::VertexArrayDeleter;
friend detail::FramebufferDeleter;
std::vector<GLuint> pooledTextures;
std::vector<TextureID> pooledTextures;
std::vector<GLuint> abandonedPrograms;
std::vector<GLuint> abandonedShaders;
std::vector<GLuint> abandonedBuffers;
std::vector<GLuint> abandonedTextures;
std::vector<GLuint> abandonedVertexArrays;
std::vector<GLuint> abandonedFramebuffers;
std::vector<ProgramID> abandonedPrograms;
std::vector<ShaderID> abandonedShaders;
std::vector<BufferID> abandonedBuffers;
std::vector<TextureID> abandonedTextures;
std::vector<VertexArrayID> abandonedVertexArrays;
std::vector<FramebufferID> abandonedFramebuffers;
};
} // namespace gl

View File

@@ -7,22 +7,22 @@ namespace mbgl {
namespace gl {
namespace detail {
void ProgramDeleter::operator()(GLuint id) const {
void ProgramDeleter::operator()(ProgramID id) const {
assert(context);
context->abandonedPrograms.push_back(id);
}
void ShaderDeleter::operator()(GLuint id) const {
void ShaderDeleter::operator()(ShaderID id) const {
assert(context);
context->abandonedShaders.push_back(id);
}
void BufferDeleter::operator()(GLuint id) const {
void BufferDeleter::operator()(BufferID id) const {
assert(context);
context->abandonedBuffers.push_back(id);
}
void TextureDeleter::operator()(GLuint id) const {
void TextureDeleter::operator()(TextureID id) const {
assert(context);
if (context->pooledTextures.size() >= TextureMax) {
context->abandonedTextures.push_back(id);
@@ -31,12 +31,12 @@ void TextureDeleter::operator()(GLuint id) const {
}
}
void VertexArrayDeleter::operator()(GLuint id) const {
void VertexArrayDeleter::operator()(VertexArrayID id) const {
assert(context);
context->abandonedVertexArrays.push_back(id);
}
void FramebufferDeleter::operator()(GLuint id) const {
void FramebufferDeleter::operator()(FramebufferID id) const {
assert(context);
context->abandonedFramebuffers.push_back(id);
}

View File

@@ -1,6 +1,6 @@
#pragma once
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/types.hpp>
#include <unique_resource.hpp>
@@ -13,42 +13,42 @@ namespace detail {
struct ProgramDeleter {
Context* context;
void operator()(GLuint) const;
void operator()(ProgramID) const;
};
struct ShaderDeleter {
Context* context;
void operator()(GLuint) const;
void operator()(ShaderID) const;
};
struct BufferDeleter {
Context* context;
void operator()(GLuint) const;
void operator()(BufferID) const;
};
struct TextureDeleter {
Context* context;
void operator()(GLuint) const;
void operator()(TextureID) const;
};
struct VertexArrayDeleter {
Context* context;
void operator()(GLuint) const;
void operator()(VertexArrayID) const;
};
struct FramebufferDeleter {
Context* context;
void operator()(GLuint) const;
void operator()(FramebufferID) const;
};
} // namespace detail
using UniqueProgram = std_experimental::unique_resource<GLuint, detail::ProgramDeleter>;
using UniqueShader = std_experimental::unique_resource<GLuint, detail::ShaderDeleter>;
using UniqueBuffer = std_experimental::unique_resource<GLuint, detail::BufferDeleter>;
using UniqueTexture = std_experimental::unique_resource<GLuint, detail::TextureDeleter>;
using UniqueVertexArray = std_experimental::unique_resource<GLuint, detail::VertexArrayDeleter>;
using UniqueFramebuffer = std_experimental::unique_resource<GLuint, detail::FramebufferDeleter>;
using UniqueProgram = std_experimental::unique_resource<ProgramID, detail::ProgramDeleter>;
using UniqueShader = std_experimental::unique_resource<ShaderID, detail::ShaderDeleter>;
using UniqueBuffer = std_experimental::unique_resource<BufferID, detail::BufferDeleter>;
using UniqueTexture = std_experimental::unique_resource<TextureID, detail::TextureDeleter>;
using UniqueVertexArray = std_experimental::unique_resource<VertexArrayID, detail::VertexArrayDeleter>;
using UniqueFramebuffer = std_experimental::unique_resource<FramebufferID, detail::FramebufferDeleter>;
} // namespace gl
} // namespace mbgl

17
src/mbgl/gl/types.hpp Normal file
View File

@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
namespace mbgl {
namespace gl {
using ProgramID = uint32_t;
using ShaderID = uint32_t;
using BufferID = uint32_t;
using TextureID = uint32_t;
using VertexArrayID = uint32_t;
using FramebufferID = uint32_t;
using RenderbufferID = uint32_t;
} // namespace gl
} // namespace mbgl

View File

@@ -6,6 +6,7 @@
#include <cassert>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/types.hpp>
#include <mbgl/util/color.hpp>
namespace mbgl {
@@ -234,7 +235,7 @@ struct BlendColor {
};
struct Program {
using Type = GLuint;
using Type = gl::ProgramID;
static const constexpr Type Default = 0;
static void Set(const Type& value) {
MBGL_CHECK_ERROR(glUseProgram(value));
@@ -333,7 +334,7 @@ struct RasterPos {
#endif // GL_ES_VERSION_2_0
struct BindTexture {
using Type = GLuint;
using Type = gl::TextureID;
static const constexpr Type Default = 0;
static void Set(const Type& value) {
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, value));
@@ -341,7 +342,7 @@ struct BindTexture {
static Type Get() {
GLint texture;
MBGL_CHECK_ERROR(glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture));
return texture;
return static_cast<Type>(texture);
}
};
@@ -349,7 +350,7 @@ template <GLenum target>
struct BindBuffer {
static_assert(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER,
"target must be one of GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER");
using Type = GLuint;
using Type = gl::BufferID;
static const constexpr Type Default = 0;
static void Set(const Type& value) {
MBGL_CHECK_ERROR(glBindBuffer(target, value));
@@ -359,7 +360,7 @@ struct BindBuffer {
MBGL_CHECK_ERROR(glGetIntegerv(target == GL_ARRAY_BUFFER ? GL_ARRAY_BUFFER_BINDING
: GL_ELEMENT_ARRAY_BUFFER_BINDING,
&binding));
return binding;
return static_cast<Type>(binding);
}
};
@@ -367,7 +368,7 @@ template <GLenum target>
const typename BindBuffer<target>::Type BindBuffer<target>::Default;
struct BindVertexArray {
using Type = GLuint;
using Type = gl::VertexArrayID;
static const constexpr Type Default = 0;
static void Set(const Type& value) {
if (gl::BindVertexArray) {

View File

@@ -23,8 +23,8 @@ Shader::Shader(const char* name_,
Defines defines)
: name(name_),
program(context.createProgram()),
vertexShader(context.createShader(GL_VERTEX_SHADER)),
fragmentShader(context.createShader(GL_FRAGMENT_SHADER)) {
vertexShader(context.createVertexShader()),
fragmentShader(context.createFragmentShader()) {
util::stopwatch stopwatch("shader compilation", Event::Shader);
if (!compileShader(vertexShader, vertexSource)) {

View File

@@ -16,7 +16,7 @@ public:
~Shader();
const char* name;
GLuint getID() const {
gl::ProgramID getID() const {
return program.get();
}

View File

@@ -14,7 +14,7 @@ bool Raster::isLoaded() const {
return loaded;
}
GLuint Raster::getID() const {
gl::TextureID Raster::getID() const {
return texture ? *texture : 0;
}

View File

@@ -34,7 +34,7 @@ public:
bool isLoaded() const;
// returns the OpenGL texture ID
GLuint getID() const;
gl::TextureID getID() const;
// size of uploaded image.
std::array<uint16_t, 2> getSize() const;

View File

@@ -80,7 +80,7 @@ TEST(GLObject, Store) {
context.performCleanup();
EXPECT_TRUE(context.empty());
mbgl::gl::UniqueShader shader = context.createShader(GL_VERTEX_SHADER);
mbgl::gl::UniqueShader shader = context.createVertexShader();
EXPECT_NE(shader.get(), 0u);
shader.reset();
EXPECT_FALSE(context.empty());