summaryrefslogtreecommitdiff
path: root/src/mbgl/gl/context.cpp
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2017-02-27 18:33:16 +0100
committerJohn Firebaugh <john.firebaugh@gmail.com>2017-03-23 14:50:11 -0700
commite67abfbe67d7c08e90fdbd8727c4e9ed17dfa1ed (patch)
tree8bf1a6ae813afdfe44bd8d6210337141acd53bae /src/mbgl/gl/context.cpp
parent234384ece9c70f2a803ed2b1d1eb55b248ec43d1 (diff)
downloadqtlocation-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.cpp79
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();
}