summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/core-files.cmake9
-rw-r--r--platform/glfw/glfw_view.cpp2
-rw-r--r--src/mbgl/gl/context.cpp79
-rw-r--r--src/mbgl/gl/context.hpp30
-rw-r--r--src/mbgl/gl/debugging.cpp194
-rw-r--r--src/mbgl/gl/debugging.hpp24
-rw-r--r--src/mbgl/gl/debugging_extension.cpp55
-rw-r--r--src/mbgl/gl/debugging_extension.hpp120
-rw-r--r--src/mbgl/gl/extension.cpp40
-rw-r--r--src/mbgl/gl/extension.hpp20
-rw-r--r--src/mbgl/gl/program_binary.cpp24
-rw-r--r--src/mbgl/gl/program_binary.hpp27
-rw-r--r--src/mbgl/gl/program_binary_extension.hpp44
-rw-r--r--src/mbgl/gl/segment.hpp5
-rw-r--r--src/mbgl/gl/state.hpp36
-rw-r--r--src/mbgl/gl/value.cpp15
-rw-r--r--src/mbgl/gl/value.hpp7
-rw-r--r--src/mbgl/gl/vertex_array.cpp22
-rw-r--r--src/mbgl/gl/vertex_array.hpp14
-rw-r--r--src/mbgl/gl/vertex_array_extension.hpp37
-rw-r--r--src/mbgl/map/backend.cpp4
-rw-r--r--src/mbgl/renderer/painter.cpp22
-rw-r--r--src/mbgl/renderer/painter_debug.cpp2
23 files changed, 453 insertions, 379 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index e98f999116..8fc71bf280 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -58,10 +58,11 @@ set(MBGL_CORE_FILES
src/mbgl/gl/context.hpp
src/mbgl/gl/debugging.cpp
src/mbgl/gl/debugging.hpp
+ src/mbgl/gl/debugging_extension.cpp
+ src/mbgl/gl/debugging_extension.hpp
src/mbgl/gl/depth_mode.cpp
src/mbgl/gl/depth_mode.hpp
src/mbgl/gl/draw_mode.hpp
- src/mbgl/gl/extension.cpp
src/mbgl/gl/extension.hpp
src/mbgl/gl/features.hpp
src/mbgl/gl/framebuffer.hpp
@@ -71,8 +72,7 @@ set(MBGL_CORE_FILES
src/mbgl/gl/object.hpp
src/mbgl/gl/primitives.hpp
src/mbgl/gl/program.hpp
- src/mbgl/gl/program_binary.cpp
- src/mbgl/gl/program_binary.hpp
+ src/mbgl/gl/program_binary_extension.hpp
src/mbgl/gl/renderbuffer.hpp
src/mbgl/gl/segment.cpp
src/mbgl/gl/segment.hpp
@@ -85,8 +85,7 @@ set(MBGL_CORE_FILES
src/mbgl/gl/uniform.hpp
src/mbgl/gl/value.cpp
src/mbgl/gl/value.hpp
- src/mbgl/gl/vertex_array.cpp
- src/mbgl/gl/vertex_array.hpp
+ src/mbgl/gl/vertex_array_extension.hpp
src/mbgl/gl/vertex_buffer.hpp
# layout
diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp
index 812b0e32af..82f075fd6f 100644
--- a/platform/glfw/glfw_view.cpp
+++ b/platform/glfw/glfw_view.cpp
@@ -459,7 +459,7 @@ void GLFWView::run() {
if (dirty) {
const double started = glfwGetTime();
- glfwMakeContextCurrent(window);
+ activate();
mbgl::BackendScope scope { *this, mbgl::BackendScope::ScopeType::Implicit };
updateViewBinding();
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();
}
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index 10ff4360d3..14af299baa 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -30,11 +30,23 @@ class View;
namespace gl {
constexpr size_t TextureMax = 64;
+using ProcAddress = void (*)();
+
+namespace extension {
+class VertexArray;
+class Debugging;
+class ProgramBinary;
+} // namespace extension
class Context : private util::noncopyable {
public:
+ Context();
~Context();
+ void initializeExtensions(const std::function<gl::ProcAddress(const char*)>&);
+
+ void enableDebugging();
+
UniqueShader createShader(ShaderType type, const std::string& source);
UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader);
UniqueProgram createProgram(BinaryProgramFormat binaryFormat, const std::string& binaryProgram);
@@ -164,11 +176,27 @@ public:
void setDirtyState();
+ extension::Debugging* getDebuggingExtension() const {
+ return debugging.get();
+ }
+
+ extension::VertexArray* getVertexArrayExtension() const {
+ return vertexArray.get();
+ }
+
+private:
+ std::unique_ptr<extension::Debugging> debugging;
+ std::unique_ptr<extension::VertexArray> vertexArray;
+#if MBGL_HAS_BINARY_PROGRAMS
+ std::unique_ptr<extension::ProgramBinary> programBinary;
+#endif
+
+public:
State<value::ActiveTexture> activeTexture;
State<value::BindFramebuffer> bindFramebuffer;
State<value::Viewport> viewport;
std::array<State<value::BindTexture>, 2> texture;
- State<value::BindVertexArray> vertexArrayObject;
+ State<value::BindVertexArray, const Context&> vertexArrayObject { *this };
State<value::Program> program;
State<value::BindVertexBuffer> vertexBuffer;
State<value::BindElementBuffer> elementBuffer;
diff --git a/src/mbgl/gl/debugging.cpp b/src/mbgl/gl/debugging.cpp
index 5ce3e606ee..0d69d58be5 100644
--- a/src/mbgl/gl/debugging.cpp
+++ b/src/mbgl/gl/debugging.cpp
@@ -1,193 +1,33 @@
#include <mbgl/gl/debugging.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/gl/extension.hpp>
-#include <mbgl/util/event.hpp>
-#include <mbgl/util/logging.hpp>
-
-#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
-#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
-#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
-#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
-#define GL_DEBUG_SOURCE_API 0x8246
-#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
-#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
-#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
-#define GL_DEBUG_SOURCE_APPLICATION 0x824A
-#define GL_DEBUG_SOURCE_OTHER 0x824B
-#define GL_DEBUG_TYPE_ERROR 0x824C
-#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
-#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
-#define GL_DEBUG_TYPE_PORTABILITY 0x824F
-#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
-#define GL_DEBUG_TYPE_OTHER 0x8251
-#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
-#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
-#define GL_DEBUG_LOGGED_MESSAGES 0x9145
-#define GL_DEBUG_SEVERITY_HIGH 0x9146
-#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
-#define GL_DEBUG_SEVERITY_LOW 0x9148
-#define GL_DEBUG_TYPE_MARKER 0x8268
-#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
-#define GL_DEBUG_TYPE_POP_GROUP 0x826A
-#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
-#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
-#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
-#define GL_BUFFER 0x82E0
-#define GL_SHADER 0x82E1
-#define GL_PROGRAM 0x82E2
-#define GL_QUERY 0x82E3
-#define GL_PROGRAM_PIPELINE 0x82E4
-#define GL_SAMPLER 0x82E6
-#define GL_MAX_LABEL_LENGTH 0x82E8
-#define GL_DEBUG_OUTPUT 0x92E0
-#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
-#define GL_DISPLAY_LIST 0x82E7
-#define GL_VERTEX_ARRAY 0x8074
-#define GL_TRANSFORM_FEEDBACK 0x8E22
-#define GL_TEXTURE 0x1702
-#define GL_RENDERBUFFER 0x8D41
-#define GL_FRAMEBUFFER 0x8D40
+#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/debugging_extension.hpp>
namespace mbgl {
namespace gl {
-namespace debugging {
-
-typedef void (*GLDEBUGPROC)(GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- GLsizei length,
- const GLchar *message,
- const void *userParam);
-
-static ExtensionFunction<
- void (GLenum source,
- GLenum type,
- GLenum severity,
- GLsizei count,
- const GLuint *ids,
- GLboolean enabled)>
- DebugMessageControl({
- {"GL_KHR_debug", "glDebugMessageControl"},
- {"GL_ARB_debug_output", "glDebugMessageControlARB"}
- });
-
-static ExtensionFunction<
- void (GLDEBUGPROC callback,
- const void *userParam)>
- DebugMessageCallback({
- {"GL_KHR_debug", "glDebugMessageCallback"},
- {"GL_ARB_debug_output", "glDebugMessageCallbackARB"}
- });
-
-void debugCallback(GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- GLsizei /*length*/,
- const GLchar* message,
- const void* /*userParam*/)
-{
- std::string strSource;
- switch (source) {
- case GL_DEBUG_SOURCE_API: strSource = "DEBUG_SOURCE_API"; break;
- case GL_DEBUG_SOURCE_WINDOW_SYSTEM: strSource = "DEBUG_SOURCE_WINDOW_SYSTEM"; break;
- case GL_DEBUG_SOURCE_SHADER_COMPILER: strSource = "DEBUG_SOURCE_SHADER_COMPILER"; break;
- case GL_DEBUG_SOURCE_THIRD_PARTY: strSource = "DEBUG_SOURCE_THIRD_PARTY"; break;
- case GL_DEBUG_SOURCE_APPLICATION: strSource = "DEBUG_SOURCE_APPLICATION"; break;
- case GL_DEBUG_SOURCE_OTHER: strSource = "DEBUG_SOURCE_OTHER"; break;
- default: strSource = "(unknown)"; break;
- }
-
- std::string strType;
- switch (type) {
- case GL_DEBUG_TYPE_ERROR: strType = "DEBUG_TYPE_ERROR"; break;
- case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: strType = "DEBUG_TYPE_DEPRECATED_BEHAVIOR"; break;
- case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: strType = "DEBUG_TYPE_UNDEFINED_BEHAVIOR"; break;
- case GL_DEBUG_TYPE_PERFORMANCE: strType = "DEBUG_TYPE_PERFORMANCE"; break;
- case GL_DEBUG_TYPE_PORTABILITY: strType = "DEBUG_TYPE_PORTABILITY"; break;
- case GL_DEBUG_TYPE_OTHER: strType = "DEBUG_TYPE_OTHER"; break;
- case GL_DEBUG_TYPE_MARKER: strType = "DEBUG_TYPE_MARKER"; break;
- case GL_DEBUG_TYPE_PUSH_GROUP: strType = "DEBUG_TYPE_OTHER"; break;
- case GL_DEBUG_TYPE_POP_GROUP: strType = "DEBUG_TYPE_POP_GROUP"; break;
- default: strSource = "(unknown)"; break;
- }
-
- std::string strSeverity;
- mbgl::EventSeverity evtSeverity;
- switch (severity) {
- case GL_DEBUG_SEVERITY_HIGH: strSeverity = "DEBUG_SEVERITY_HIGH"; evtSeverity = mbgl::EventSeverity::Error; break;
- case GL_DEBUG_SEVERITY_MEDIUM: strSeverity = "DEBUG_SEVERITY_MEDIUM"; evtSeverity = mbgl::EventSeverity::Warning; break;
- case GL_DEBUG_SEVERITY_LOW: strSeverity = "DEBUG_SEVERITY_LOW"; evtSeverity = mbgl::EventSeverity::Info; break;
- case GL_DEBUG_SEVERITY_NOTIFICATION: strSeverity = "DEBUG_SEVERITY_NOTIFICATION"; evtSeverity = mbgl::EventSeverity::Debug; break;
- default: strSource = "(unknown)"; evtSeverity = mbgl::EventSeverity::Debug; break;
- }
-
- mbgl::Log::Record(evtSeverity, mbgl::Event::OpenGL, "GL_%s GL_%s %u GL_%s - %s", strSource.c_str(), strType.c_str(), id, strSeverity.c_str(), message);
-}
-
-void enable() {
- if (!DebugMessageControl || !DebugMessageCallback) {
- return;
- }
-
- // This will enable all messages including performance hints
- // MBGL_CHECK_ERROR(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(DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE));
- MBGL_CHECK_ERROR(DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE));
- MBGL_CHECK_ERROR(DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE));
-
- MBGL_CHECK_ERROR(DebugMessageCallback(debugCallback, nullptr));
-}
#ifndef NDEBUG
-static ExtensionFunction<
- void (GLenum source,
- GLuint id,
- GLsizei length,
- const GLchar *message)>
- PushDebugGroup({
- {"GL_KHR_debug", "glPushDebugGroup"}
- });
-
-static ExtensionFunction<
- void ()>
- PopDebugGroup({
- {"GL_KHR_debug", "glPopDebugGroup"}
- });
-
-static ExtensionFunction<
- void (GLsizei length,
- const GLchar *marker)>
- PushGroupMarkerEXT({
- {"GL_EXT_debug_marker", "glPushGroupMarkerEXT"}
- });
-static ExtensionFunction<
- void ()>
- PopGroupMarkerEXT({
- {"GL_EXT_debug_marker", "glPopGroupMarkerEXT"}
- });
-
-group::group(const std::string& str) {
- if (PushDebugGroup) {
- PushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, GLsizei(str.size()), str.c_str());
- } else if (PushGroupMarkerEXT) {
- PushGroupMarkerEXT(GLsizei(str.size() + 1), str.c_str());
+DebugGroup::DebugGroup(const Context& context_, const std::string& name) : context(context_) {
+ if (auto debugging = context.getDebuggingExtension()) {
+ if (debugging->pushDebugGroup) {
+ debugging->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, GLsizei(name.size()), name.c_str());
+ } else if (debugging->pushGroupMarkerEXT) {
+ debugging->pushGroupMarkerEXT(GLsizei(name.size() + 1), name.c_str());
+ }
}
}
-group::~group() {
- if (PopDebugGroup) {
- PopDebugGroup();
- } else if (PopGroupMarkerEXT) {
- PopGroupMarkerEXT();
+DebugGroup::~DebugGroup() {
+ if (auto debugging = context.getDebuggingExtension()) {
+ if (debugging->popDebugGroup) {
+ debugging->popDebugGroup();
+ } else if (debugging->popGroupMarkerEXT) {
+ debugging->popGroupMarkerEXT();
+ }
}
}
+
#endif
-} // namespace debugging
} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/gl/debugging.hpp b/src/mbgl/gl/debugging.hpp
index fe363701ad..d24b727295 100644
--- a/src/mbgl/gl/debugging.hpp
+++ b/src/mbgl/gl/debugging.hpp
@@ -1,26 +1,34 @@
#pragma once
+#include <mbgl/util/noncopyable.hpp>
+
#include <string>
namespace mbgl {
namespace gl {
-namespace debugging {
-void enable();
+class Context;
#ifndef NDEBUG
-struct group {
- group(const std::string&);
- ~group();
+
+class DebugGroup : private util::noncopyable {
+public:
+ DebugGroup(const Context&, const std::string&);
+ ~DebugGroup();
+
+private:
+ const Context& context;
};
#define __MBGL_DEBUG_GROUP_NAME2(counter) __MBGL_DEBUG_GROUP_##counter
#define __MBGL_DEBUG_GROUP_NAME(counter) __MBGL_DEBUG_GROUP_NAME2(counter)
-#define MBGL_DEBUG_GROUP(string) ::mbgl::gl::debugging::group __MBGL_DEBUG_GROUP_NAME(__LINE__)(string);
+#define MBGL_DEBUG_GROUP(context, name) const ::mbgl::gl::DebugGroup __MBGL_DEBUG_GROUP_NAME(__LINE__)(context, name);
+
#else
-#define MBGL_DEBUG_GROUP(string)
+
+#define MBGL_DEBUG_GROUP(context, name)
+
#endif
-} // namespace debugging
} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/gl/debugging_extension.cpp b/src/mbgl/gl/debugging_extension.cpp
new file mode 100644
index 0000000000..5afa4f50fc
--- /dev/null
+++ b/src/mbgl/gl/debugging_extension.cpp
@@ -0,0 +1,55 @@
+#include <mbgl/gl/debugging_extension.hpp>
+#include <mbgl/util/logging.hpp>
+
+namespace mbgl {
+namespace gl {
+namespace extension {
+
+void Debugging::DebugCallback(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei /* length */,
+ const GLchar* message,
+ const void* /* userParam */) {
+ std::string strSource;
+ switch (source) {
+ case GL_DEBUG_SOURCE_API: strSource = "DEBUG_SOURCE_API"; break;
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM: strSource = "DEBUG_SOURCE_WINDOW_SYSTEM"; break;
+ case GL_DEBUG_SOURCE_SHADER_COMPILER: strSource = "DEBUG_SOURCE_SHADER_COMPILER"; break;
+ case GL_DEBUG_SOURCE_THIRD_PARTY: strSource = "DEBUG_SOURCE_THIRD_PARTY"; break;
+ case GL_DEBUG_SOURCE_APPLICATION: strSource = "DEBUG_SOURCE_APPLICATION"; break;
+ case GL_DEBUG_SOURCE_OTHER: strSource = "DEBUG_SOURCE_OTHER"; break;
+ default: strSource = "(unknown)"; break;
+ }
+
+ std::string strType;
+ switch (type) {
+ case GL_DEBUG_TYPE_ERROR: strType = "DEBUG_TYPE_ERROR"; break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: strType = "DEBUG_TYPE_DEPRECATED_BEHAVIOR"; break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: strType = "DEBUG_TYPE_UNDEFINED_BEHAVIOR"; break;
+ case GL_DEBUG_TYPE_PERFORMANCE: strType = "DEBUG_TYPE_PERFORMANCE"; break;
+ case GL_DEBUG_TYPE_PORTABILITY: strType = "DEBUG_TYPE_PORTABILITY"; break;
+ case GL_DEBUG_TYPE_OTHER: strType = "DEBUG_TYPE_OTHER"; break;
+ case GL_DEBUG_TYPE_MARKER: strType = "DEBUG_TYPE_MARKER"; break;
+ case GL_DEBUG_TYPE_PUSH_GROUP: strType = "DEBUG_TYPE_OTHER"; break;
+ case GL_DEBUG_TYPE_POP_GROUP: strType = "DEBUG_TYPE_POP_GROUP"; break;
+ default: strSource = "(unknown)"; break;
+ }
+
+ std::string strSeverity;
+ mbgl::EventSeverity evtSeverity;
+ switch (severity) {
+ case GL_DEBUG_SEVERITY_HIGH: strSeverity = "DEBUG_SEVERITY_HIGH"; evtSeverity = mbgl::EventSeverity::Error; break;
+ case GL_DEBUG_SEVERITY_MEDIUM: strSeverity = "DEBUG_SEVERITY_MEDIUM"; evtSeverity = mbgl::EventSeverity::Warning; break;
+ case GL_DEBUG_SEVERITY_LOW: strSeverity = "DEBUG_SEVERITY_LOW"; evtSeverity = mbgl::EventSeverity::Info; break;
+ case GL_DEBUG_SEVERITY_NOTIFICATION: strSeverity = "DEBUG_SEVERITY_NOTIFICATION"; evtSeverity = mbgl::EventSeverity::Debug; break;
+ default: strSource = "(unknown)"; evtSeverity = mbgl::EventSeverity::Debug; break;
+ }
+
+ mbgl::Log::Record(evtSeverity, mbgl::Event::OpenGL, "GL_%s GL_%s %u GL_%s - %s", strSource.c_str(), strType.c_str(), id, strSeverity.c_str(), message);
+}
+
+} // namespace extension
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/debugging_extension.hpp b/src/mbgl/gl/debugging_extension.hpp
new file mode 100644
index 0000000000..c1835cfcdd
--- /dev/null
+++ b/src/mbgl/gl/debugging_extension.hpp
@@ -0,0 +1,120 @@
+#pragma once
+
+#include <mbgl/gl/extension.hpp>
+#include <mbgl/gl/gl.hpp>
+
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_BUFFER 0x82E0
+#define GL_SHADER 0x82E1
+#define GL_PROGRAM 0x82E2
+#define GL_QUERY 0x82E3
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_SAMPLER 0x82E6
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_DISPLAY_LIST 0x82E7
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TEXTURE 0x1702
+#define GL_RENDERBUFFER 0x8D41
+#define GL_FRAMEBUFFER 0x8D40
+
+namespace mbgl {
+namespace gl {
+namespace extension {
+
+class Debugging {
+public:
+ typedef void (*Callback)(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message,
+ const void* userParam);
+
+ static void DebugCallback(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei /* length */,
+ const GLchar* message,
+ const void* /* userParam */);
+
+ template <typename Fn>
+ Debugging(const Fn& loadExtension)
+ :
+#ifndef NDEBUG
+ pushDebugGroup(
+ loadExtension({ { "GL_KHR_debug", "glPushDebugGroup" } })),
+ popDebugGroup(
+ loadExtension({ { "GL_KHR_debug", "glPopDebugGroup" } })),
+ pushGroupMarkerEXT(
+ loadExtension({ { "GL_EXT_debug_marker", "glPushGroupMarkerEXT" } })),
+ popGroupMarkerEXT(
+ loadExtension({ { "GL_EXT_debug_marker", "glPopGroupMarkerEXT" } })),
+#endif
+ debugMessageControl(
+ loadExtension({ { "GL_KHR_debug", "glDebugMessageControl" },
+ { "GL_ARB_debug_output", "glDebugMessageControlARB" } })),
+ debugMessageCallback(
+ loadExtension({ { "GL_KHR_debug", "glDebugMessageCallback" },
+ { "GL_ARB_debug_output", "glDebugMessageCallbackARB" } })) {
+ }
+
+#ifndef NDEBUG
+ const ExtensionFunction<void(GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar* message)> pushDebugGroup;
+
+ const ExtensionFunction<void()> popDebugGroup;
+
+ const ExtensionFunction<void(GLsizei length,
+ const GLchar* marker)> pushGroupMarkerEXT;
+
+ const ExtensionFunction<void()> popGroupMarkerEXT;
+#endif
+
+ const ExtensionFunction<void(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint* ids,
+ GLboolean enabled)> debugMessageControl;
+
+ const ExtensionFunction<void(Callback callback,
+ const void* userParam)> debugMessageCallback;
+};
+
+} // namespace extension
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/extension.cpp b/src/mbgl/gl/extension.cpp
deleted file mode 100644
index 41a5ea175e..0000000000
--- a/src/mbgl/gl/extension.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <mbgl/gl/extension.hpp>
-#include <mbgl/gl/gl.hpp>
-
-#include <string>
-#include <vector>
-#include <cstring>
-
-namespace mbgl {
-namespace gl {
-namespace detail {
-
-using Probes = std::vector<ExtensionFunctionBase::Probe>;
-using ExtensionFunctions = std::vector<std::pair<ProcAddress*, Probes>>;
-ExtensionFunctions& extensionFunctions() {
- static ExtensionFunctions functions;
- return functions;
-}
-
-ExtensionFunctionBase::ExtensionFunctionBase(std::initializer_list<Probe> probes) {
- extensionFunctions().emplace_back(&ptr, probes);
-}
-
-} // namespace detail
-
-void initializeExtensions(const std::function<ProcAddress(const char*)>& getProcAddress) {
- if (const char* extensions =
- reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS)))) {
- for (auto fn : detail::extensionFunctions()) {
- for (auto probe : fn.second) {
- if (strstr(extensions, probe.first) != nullptr) {
- *fn.first = getProcAddress(probe.second);
- break;
- }
- }
- }
- }
-}
-
-} // namespace gl
-} // namespace mbgl
diff --git a/src/mbgl/gl/extension.hpp b/src/mbgl/gl/extension.hpp
index 7d1d9a4d7d..8710314ef2 100644
--- a/src/mbgl/gl/extension.hpp
+++ b/src/mbgl/gl/extension.hpp
@@ -8,26 +8,15 @@ namespace mbgl {
namespace gl {
using ProcAddress = void (*)();
-void initializeExtensions(const std::function<ProcAddress(const char*)>&);
-
-namespace detail {
-
-class ExtensionFunctionBase {
-public:
- using Probe = std::pair<const char*, const char*>;
- ExtensionFunctionBase(std::initializer_list<Probe>);
- ProcAddress ptr;
-};
-
-} // namespace detail
template <class>
class ExtensionFunction;
template <class R, class... Args>
-class ExtensionFunction<R(Args...)> : protected detail::ExtensionFunctionBase {
+class ExtensionFunction<R(Args...)> {
public:
- using detail::ExtensionFunctionBase::ExtensionFunctionBase;
+ ExtensionFunction(const ProcAddress ptr_) : ptr(ptr_) {
+ }
explicit operator bool() const {
return ptr;
@@ -36,6 +25,9 @@ public:
R operator()(Args... args) const {
return (*reinterpret_cast<R (*)(Args...)>(ptr))(std::forward<Args>(args)...);
}
+
+private:
+ const ProcAddress ptr;
};
} // namespace gl
diff --git a/src/mbgl/gl/program_binary.cpp b/src/mbgl/gl/program_binary.cpp
deleted file mode 100644
index ad147c819f..0000000000
--- a/src/mbgl/gl/program_binary.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <mbgl/gl/program_binary.hpp>
-
-#if MBGL_HAS_BINARY_PROGRAMS
-
-namespace mbgl {
-namespace gl {
-
-ExtensionFunction<
- void(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)>
- GetProgramBinary({
- { "GL_OES_get_program_binary", "glGetProgramBinaryOES" },
- { "GL_ARB_get_program_binary", "glGetProgramBinary" },
- });
-
-ExtensionFunction<void(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length)>
- ProgramBinary({
- { "GL_OES_get_program_binary", "glProgramBinaryOES" },
- { "GL_ARB_get_program_binary", "glProgramBinary" },
- });
-
-} // namespace gl
-} // namespace mbgl
-
-#endif
diff --git a/src/mbgl/gl/program_binary.hpp b/src/mbgl/gl/program_binary.hpp
deleted file mode 100644
index e888ed3d4a..0000000000
--- a/src/mbgl/gl/program_binary.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/features.hpp>
-#include <mbgl/gl/extension.hpp>
-#include <mbgl/gl/gl.hpp>
-
-#if MBGL_HAS_BINARY_PROGRAMS
-
-#define GL_PROGRAM_BINARY_LENGTH 0x8741
-#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
-#define GL_PROGRAM_BINARY_FORMATS 0x87FF
-
-namespace mbgl {
-namespace gl {
-
-extern ExtensionFunction<void(
- GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)>
- GetProgramBinary;
-
-extern ExtensionFunction<void(
- GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length)>
- ProgramBinary;
-
-} // namespace gl
-} // namespace mbgl
-
-#endif
diff --git a/src/mbgl/gl/program_binary_extension.hpp b/src/mbgl/gl/program_binary_extension.hpp
new file mode 100644
index 0000000000..a4aa1eeefc
--- /dev/null
+++ b/src/mbgl/gl/program_binary_extension.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <mbgl/gl/features.hpp>
+#include <mbgl/gl/extension.hpp>
+#include <mbgl/gl/gl.hpp>
+
+#if MBGL_HAS_BINARY_PROGRAMS
+
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+
+namespace mbgl {
+namespace gl {
+namespace extension {
+
+class ProgramBinary {
+public:
+ template <typename Fn>
+ ProgramBinary(const Fn& loadExtension)
+ : getProgramBinary(loadExtension({
+ { "GL_OES_get_program_binary", "glGetProgramBinaryOES" },
+ { "GL_ARB_get_program_binary", "glGetProgramBinary" },
+ })),
+ programBinary(loadExtension({
+ { "GL_OES_get_program_binary", "glProgramBinaryOES" },
+ { "GL_ARB_get_program_binary", "glProgramBinary" },
+ })) {
+ }
+
+ const ExtensionFunction<void(
+ GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)>
+ getProgramBinary;
+
+ const ExtensionFunction<void(
+ GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length)>
+ programBinary;
+};
+
+} // namespace extension
+} // namespace gl
+} // namespace mbgl
+
+#endif
diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp
index bd4926476f..45c81973f2 100644
--- a/src/mbgl/gl/segment.hpp
+++ b/src/mbgl/gl/segment.hpp
@@ -5,7 +5,6 @@
#include <mbgl/util/optional.hpp>
#include <mbgl/util/logging.hpp>
-#include <mutex>
#include <cstddef>
#include <vector>
@@ -47,10 +46,6 @@ public:
}
} else {
// No VAO support. Force attributes to be rebound.
- static std::once_flag reportedOnce;
- std::call_once(reportedOnce, [] {
- Log::Warning(Event::OpenGL, "Not using Vertex Array Objects");
- });
context.elementBuffer = indexBuffer_;
variableBindings = {};
}
diff --git a/src/mbgl/gl/state.hpp b/src/mbgl/gl/state.hpp
index efe869e5b9..f3268229d1 100644
--- a/src/mbgl/gl/state.hpp
+++ b/src/mbgl/gl/state.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <tuple>
+
namespace mbgl {
namespace gl {
@@ -12,13 +14,16 @@ namespace gl {
// static void Set(const Type& value);
// static Type Get();
// };
-template <typename T>
+template <typename T, typename... Args>
class State {
public:
+ State(Args&&... args) : params(std::forward_as_tuple(::std::forward<Args>(args)...)) {
+ }
+
void operator=(const typename T::Type& value) {
if (*this != value) {
setCurrentValue(value);
- T::Set(currentValue);
+ set(std::index_sequence_for<Args...>{});
}
}
@@ -50,22 +55,43 @@ public:
}
private:
+ template <std::size_t... I>
+ void set(std::index_sequence<I...>) {
+ T::Set(currentValue, std::get<I>(params)...);
+ }
+
+private:
typename T::Type currentValue = T::Default;
bool dirty = true;
+ const std::tuple<Args...> params;
};
// Helper struct that stores the current state and restores it upon destruction. You should not use
// this code normally, except for debugging purposes.
-template <typename T>
+template <typename T, typename... Args>
class PreserveState {
public:
- PreserveState() : value(T::Get()) {
+ PreserveState(Args&&... args)
+ : params(std::forward_as_tuple(std::forward<Args>(args)...)),
+ value(get(std::index_sequence_for<Args...>{})) {
}
~PreserveState() {
- T::Set(value);
+ set(std::index_sequence_for<Args...>{});
+ }
+
+private:
+ template <std::size_t... I>
+ typename T::Type get(std::index_sequence<I...>) {
+ return T::Get(std::get<I>(params)...);
+ }
+
+ template <std::size_t... I>
+ void set(std::index_sequence<I...>) {
+ T::Set(value, std::get<I>(params)...);
}
private:
+ const std::tuple<Args...> params;
const typename T::Type value;
};
diff --git a/src/mbgl/gl/value.cpp b/src/mbgl/gl/value.cpp
index 603d82dfd5..c081c941f5 100644
--- a/src/mbgl/gl/value.cpp
+++ b/src/mbgl/gl/value.cpp
@@ -1,6 +1,7 @@
#include <mbgl/gl/value.hpp>
#include <mbgl/gl/gl.hpp>
-#include <mbgl/gl/vertex_array.hpp>
+#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/vertex_array_extension.hpp>
namespace mbgl {
namespace gl {
@@ -328,15 +329,17 @@ BindElementBuffer::Type BindElementBuffer::Get() {
const constexpr BindVertexArray::Type BindVertexArray::Default;
-void BindVertexArray::Set(const Type& value) {
- if (gl::BindVertexArray) {
- MBGL_CHECK_ERROR(gl::BindVertexArray(value));
+void BindVertexArray::Set(const Type& value, const Context& context) {
+ if (auto vertexArray = context.getVertexArrayExtension()) {
+ if (vertexArray->bindVertexArray) {
+ MBGL_CHECK_ERROR(vertexArray->bindVertexArray(value));
+ }
}
}
-BindVertexArray::Type BindVertexArray::Get() {
+BindVertexArray::Type BindVertexArray::Get(const Context& context) {
GLint binding = 0;
- if (gl::BindVertexArray) {
+ if (context.getVertexArrayExtension()) {
#ifdef GL_VERTEX_ARRAY_BINDING
MBGL_CHECK_ERROR(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &binding));
#elif GL_VERTEX_ARRAY_BINDING_OES
diff --git a/src/mbgl/gl/value.hpp b/src/mbgl/gl/value.hpp
index eccd3e7373..aa5cca6fec 100644
--- a/src/mbgl/gl/value.hpp
+++ b/src/mbgl/gl/value.hpp
@@ -10,6 +10,9 @@
namespace mbgl {
namespace gl {
+
+class Context;
+
namespace value {
struct ClearDepth {
@@ -225,8 +228,8 @@ struct BindElementBuffer {
struct BindVertexArray {
using Type = gl::VertexArrayID;
static const constexpr Type Default = 0;
- static void Set(const Type&);
- static Type Get();
+ static void Set(const Type&, const Context&);
+ static Type Get(const Context&);
};
#if not MBGL_USE_GLES2
diff --git a/src/mbgl/gl/vertex_array.cpp b/src/mbgl/gl/vertex_array.cpp
deleted file mode 100644
index df63bbc4b7..0000000000
--- a/src/mbgl/gl/vertex_array.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <mbgl/gl/vertex_array.hpp>
-
-namespace mbgl {
-namespace gl {
-
-ExtensionFunction<void(GLuint array)>
- BindVertexArray({ { "GL_ARB_vertex_array_object", "glBindVertexArray" },
- { "GL_OES_vertex_array_object", "glBindVertexArrayOES" },
- { "GL_APPLE_vertex_array_object", "glBindVertexArrayAPPLE" } });
-
-ExtensionFunction<void(GLsizei n, const GLuint* arrays)>
- DeleteVertexArrays({ { "GL_ARB_vertex_array_object", "glDeleteVertexArrays" },
- { "GL_OES_vertex_array_object", "glDeleteVertexArraysOES" },
- { "GL_APPLE_vertex_array_object", "glDeleteVertexArraysAPPLE" } });
-
-ExtensionFunction<void(GLsizei n, GLuint* arrays)>
- GenVertexArrays({ { "GL_ARB_vertex_array_object", "glGenVertexArrays" },
- { "GL_OES_vertex_array_object", "glGenVertexArraysOES" },
- { "GL_APPLE_vertex_array_object", "glGenVertexArraysAPPLE" } });
-
-} // namespace gl
-} // namespace mbgl
diff --git a/src/mbgl/gl/vertex_array.hpp b/src/mbgl/gl/vertex_array.hpp
deleted file mode 100644
index 6b6e11324f..0000000000
--- a/src/mbgl/gl/vertex_array.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/extension.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-namespace gl {
-
-extern ExtensionFunction<void(GLuint array)> BindVertexArray;
-extern ExtensionFunction<void(GLsizei n, const GLuint* arrays)> DeleteVertexArrays;
-extern ExtensionFunction<void(GLsizei n, GLuint* arrays)> GenVertexArrays;
-
-} // namespace gl
-} // namespace mbgl
diff --git a/src/mbgl/gl/vertex_array_extension.hpp b/src/mbgl/gl/vertex_array_extension.hpp
new file mode 100644
index 0000000000..707a20e6f0
--- /dev/null
+++ b/src/mbgl/gl/vertex_array_extension.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <mbgl/gl/extension.hpp>
+#include <mbgl/gl/gl.hpp>
+
+namespace mbgl {
+namespace gl {
+namespace extension {
+
+class VertexArray {
+public:
+ template <typename Fn>
+ VertexArray(const Fn& loadExtension)
+ : bindVertexArray(
+ loadExtension({ { "GL_ARB_vertex_array_object", "glBindVertexArray" },
+ { "GL_OES_vertex_array_object", "glBindVertexArrayOES" },
+ { "GL_APPLE_vertex_array_object", "glBindVertexArrayAPPLE" } })),
+ deleteVertexArrays(
+ loadExtension({ { "GL_ARB_vertex_array_object", "glDeleteVertexArrays" },
+ { "GL_OES_vertex_array_object", "glDeleteVertexArraysOES" },
+ { "GL_APPLE_vertex_array_object", "glDeleteVertexArraysAPPLE" } })),
+ genVertexArrays(
+ loadExtension({ { "GL_ARB_vertex_array_object", "glGenVertexArrays" },
+ { "GL_OES_vertex_array_object", "glGenVertexArraysOES" },
+ { "GL_APPLE_vertex_array_object", "glGenVertexArraysAPPLE" } })) {
+ }
+
+ const ExtensionFunction<void(GLuint array)> bindVertexArray;
+
+ const ExtensionFunction<void(GLsizei n, const GLuint* arrays)> deleteVertexArrays;
+
+ const ExtensionFunction<void(GLsizei n, GLuint* arrays)> genVertexArrays;
+};
+
+} // namespace extension
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/map/backend.cpp b/src/mbgl/map/backend.cpp
index 29f7522e4f..c228719ba6 100644
--- a/src/mbgl/map/backend.cpp
+++ b/src/mbgl/map/backend.cpp
@@ -14,8 +14,8 @@ gl::Context& Backend::getContext() {
assert(BackendScope::exists());
std::call_once(initialized, [this] {
context = std::make_unique<gl::Context>();
- gl::debugging::enable();
- gl::initializeExtensions(
+ context->enableDebugging();
+ context->initializeExtensions(
std::bind(&Backend::initializeExtension, this, std::placeholders::_1));
});
return *context;
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 73a084c8c6..f7a498ecae 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -150,7 +150,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
// - UPLOAD PASS -------------------------------------------------------------------------------
// Uploads all required buffers and images before we do any actual rendering.
{
- MBGL_DEBUG_GROUP("upload");
+ MBGL_DEBUG_GROUP(context, "upload");
spriteAtlas->upload(context, 0);
@@ -170,7 +170,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
// Renders the backdrop of the OpenGL view. This also paints in areas where we don't have any
// tiles whatsoever.
{
- MBGL_DEBUG_GROUP("clear");
+ MBGL_DEBUG_GROUP(context, "clear");
view.bind();
context.clear(paintMode() == PaintMode::Overdraw
? Color::black()
@@ -182,7 +182,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
// - CLIPPING MASKS ----------------------------------------------------------------------------
// Draws the clipping masks to the stencil buffer.
{
- MBGL_DEBUG_GROUP("clip");
+ MBGL_DEBUG_GROUP(context, "clip");
// Update all clipping IDs.
algorithm::ClipIDGenerator generator;
@@ -190,10 +190,10 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
source->baseImpl->startRender(generator, projMatrix, state);
}
- MBGL_DEBUG_GROUP("clipping masks");
+ MBGL_DEBUG_GROUP(context, "clipping masks");
for (const auto& stencil : generator.getStencils()) {
- MBGL_DEBUG_GROUP(std::string{ "mask: " } + util::toString(stencil.first));
+ MBGL_DEBUG_GROUP(context, std::string{ "mask: " } + util::toString(stencil.first));
renderClippingMask(stencil.first, stencil.second);
}
}
@@ -230,7 +230,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
// - DEBUG PASS --------------------------------------------------------------------------------
// Renders debug overlays.
{
- MBGL_DEBUG_GROUP("debug");
+ MBGL_DEBUG_GROUP(context, "debug");
// Finalize the rendering, e.g. by calling debug render calls per tile.
// This guarantees that we have at least one function per tile called.
@@ -250,7 +250,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
// TODO: Find a better way to unbind VAOs after we're done with them without introducing
// unnecessary bind(0)/bind(N) sequences.
{
- MBGL_DEBUG_GROUP("cleanup");
+ MBGL_DEBUG_GROUP(context, "cleanup");
context.activeTexture = 1;
context.texture[1] = 0;
@@ -268,7 +268,7 @@ void Painter::renderPass(PaintParameters& parameters,
uint32_t i, int8_t increment) {
pass = pass_;
- MBGL_DEBUG_GROUP(pass == RenderPass::Opaque ? "opaque" : "translucent");
+ MBGL_DEBUG_GROUP(context, pass == RenderPass::Opaque ? "opaque" : "translucent");
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s {", indent++ * 4, "",
@@ -285,10 +285,10 @@ void Painter::renderPass(PaintParameters& parameters,
continue;
if (layer.is<BackgroundLayer>()) {
- MBGL_DEBUG_GROUP("background");
+ MBGL_DEBUG_GROUP(context, "background");
renderBackground(parameters, *layer.as<BackgroundLayer>());
} else if (layer.is<CustomLayer>()) {
- MBGL_DEBUG_GROUP(layer.baseImpl->id + " - custom");
+ MBGL_DEBUG_GROUP(context, layer.baseImpl->id + " - custom");
// Reset GL state to a known state so the CustomLayer always has a clean slate.
context.vertexArrayObject = 0;
@@ -303,7 +303,7 @@ void Painter::renderPass(PaintParameters& parameters,
parameters.view.bind();
context.setDirtyState();
} else {
- MBGL_DEBUG_GROUP(layer.baseImpl->id + " - " + util::toString(item.tile->id));
+ MBGL_DEBUG_GROUP(context, layer.baseImpl->id + " - " + util::toString(item.tile->id));
item.bucket->render(*this, parameters, layer, *item.tile);
}
}
diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp
index 5b347884bf..37fa3bcb12 100644
--- a/src/mbgl/renderer/painter_debug.cpp
+++ b/src/mbgl/renderer/painter_debug.cpp
@@ -18,7 +18,7 @@ void Painter::renderTileDebug(const RenderTile& renderTile) {
if (frame.debugOptions == MapDebugOptions::NoDebug)
return;
- MBGL_DEBUG_GROUP(std::string { "debug " } + util::toString(renderTile.id));
+ MBGL_DEBUG_GROUP(context, std::string { "debug " } + util::toString(renderTile.id));
static const style::PaintProperties<>::Evaluated properties {};
static const DebugProgram::PaintPropertyBinders paintAttibuteData(properties, 0);