diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2017-02-27 18:33:16 +0100 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2017-03-23 14:50:11 -0700 |
commit | e67abfbe67d7c08e90fdbd8727c4e9ed17dfa1ed (patch) | |
tree | 8bf1a6ae813afdfe44bd8d6210337141acd53bae /src/mbgl/gl/context.cpp | |
parent | 234384ece9c70f2a803ed2b1d1eb55b248ec43d1 (diff) | |
download | qtlocation-mapboxgl-e67abfbe67d7c08e90fdbd8727c4e9ed17dfa1ed.tar.gz |
[core] Refactor OpenGL extension loading mechanism
Previously, we initialized global variables that held pointers to the extension functions. While this seemed to work, the spec doesn't guarantee that the function pointers are identical for different OpenGL contexts. Therefore, we are now making them a member variable of the Context object.
Diffstat (limited to 'src/mbgl/gl/context.cpp')
-rw-r--r-- | src/mbgl/gl/context.cpp | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 97ebf687f9..75931dc9de 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -1,8 +1,9 @@ #include <mbgl/map/view.hpp> #include <mbgl/gl/context.hpp> #include <mbgl/gl/gl.hpp> -#include <mbgl/gl/vertex_array.hpp> -#include <mbgl/gl/program_binary.hpp> +#include <mbgl/gl/debugging_extension.hpp> +#include <mbgl/gl/vertex_array_extension.hpp> +#include <mbgl/gl/program_binary_extension.hpp> #include <mbgl/util/traits.hpp> #include <mbgl/util/std.hpp> #include <mbgl/util/logging.hpp> @@ -37,10 +38,58 @@ static_assert(underlying_type(TextureFormat::Alpha) == GL_ALPHA, "OpenGL type mi static_assert(std::is_same<BinaryProgramFormat, GLenum>::value, "OpenGL type mismatch"); +Context::Context() = default; + Context::~Context() { reset(); } +void Context::initializeExtensions(const std::function<gl::ProcAddress(const char*)>& getProcAddress) { + if (const char* extensions = + reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS)))) { + + auto fn = [&]( + std::initializer_list<std::pair<const char*, const char*>> probes) -> ProcAddress { + for (auto probe : probes) { + if (strstr(extensions, probe.first) != nullptr) { + if (ProcAddress ptr = getProcAddress(probe.second)) { + return ptr; + } + } + } + return nullptr; + }; + + debugging = std::make_unique<extension::Debugging>(fn); + if (!disableVAOExtension) { + vertexArray = std::make_unique<extension::VertexArray>(fn); + } +#if MBGL_HAS_BINARY_PROGRAMS + programBinary = std::make_unique<extension::ProgramBinary>(fn); +#endif + + if (!supportsVertexArrays()) { + Log::Warning(Event::OpenGL, "Not using Vertex Array Objects"); + } + } +} + +void Context::enableDebugging() { + if (!debugging || !debugging->debugMessageControl || !debugging->debugMessageCallback) { + return; + } + + // This will enable all messages including performance hints + // MBGL_CHECK_ERROR(debugging->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE)); + + // This will only enable high and medium severity messages + MBGL_CHECK_ERROR(debugging->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE)); + MBGL_CHECK_ERROR(debugging->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE)); + MBGL_CHECK_ERROR(debugging->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE)); + + MBGL_CHECK_ERROR(debugging->debugMessageCallback(extension::Debugging::DebugCallback, nullptr)); +} + UniqueShader Context::createShader(ShaderType type, const std::string& source) { UniqueShader result { MBGL_CHECK_ERROR(glCreateShader(static_cast<GLenum>(type))), { this } }; @@ -78,9 +127,11 @@ UniqueProgram Context::createProgram(ShaderID vertexShader, ShaderID fragmentSha #if MBGL_HAS_BINARY_PROGRAMS UniqueProgram Context::createProgram(BinaryProgramFormat binaryFormat, const std::string& binaryProgram) { + assert(supportsProgramBinaries()); UniqueProgram result{ MBGL_CHECK_ERROR(glCreateProgram()), { this } }; - MBGL_CHECK_ERROR(ProgramBinary(result, static_cast<GLenum>(binaryFormat), binaryProgram.data(), - static_cast<GLint>(binaryProgram.size()))); + MBGL_CHECK_ERROR(programBinary->programBinary(result, static_cast<GLenum>(binaryFormat), + binaryProgram.data(), + static_cast<GLint>(binaryProgram.size()))); verifyProgramLinkage(result); return result; } @@ -144,15 +195,15 @@ UniqueTexture Context::createTexture() { } bool Context::supportsVertexArrays() const { - return gl::GenVertexArrays && - gl::BindVertexArray && - gl::DeleteVertexArrays && - !disableVAOExtension; + return vertexArray && + vertexArray->genVertexArrays && + vertexArray->bindVertexArray && + vertexArray->deleteVertexArrays; } #if MBGL_HAS_BINARY_PROGRAMS bool Context::supportsProgramBinaries() const { - return gl::ProgramBinary && gl::GetProgramBinary; + return programBinary && programBinary->programBinary && programBinary->getProgramBinary; } optional<std::pair<BinaryProgramFormat, std::string>> @@ -165,8 +216,8 @@ Context::getBinaryProgram(ProgramID program_) const { std::string binary; binary.resize(binaryLength); GLenum binaryFormat; - MBGL_CHECK_ERROR(GetProgramBinary(program_, binaryLength, &binaryLength, &binaryFormat, - const_cast<char*>(binary.data()))); + MBGL_CHECK_ERROR(programBinary->getProgramBinary( + program_, binaryLength, &binaryLength, &binaryFormat, const_cast<char*>(binary.data()))); if (size_t(binaryLength) != binary.size()) { return {}; } @@ -181,7 +232,7 @@ optional<std::pair<BinaryProgramFormat, std::string>> Context::getBinaryProgram( UniqueVertexArray Context::createVertexArray() { assert(supportsVertexArrays()); VertexArrayID id = 0; - MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id)); + MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); return UniqueVertexArray(std::move(id), { this }); } @@ -584,8 +635,8 @@ void Context::performCleanup() { vertexArrayObject.setDirty(); } } - MBGL_CHECK_ERROR(gl::DeleteVertexArrays(int(abandonedVertexArrays.size()), - abandonedVertexArrays.data())); + MBGL_CHECK_ERROR(vertexArray->deleteVertexArrays(int(abandonedVertexArrays.size()), + abandonedVertexArrays.data())); abandonedVertexArrays.clear(); } |