diff --git a/android/cpp/native_map_view.cpp b/android/cpp/native_map_view.cpp index 4a2e4099a..4cd1669ef 100644 --- a/android/cpp/native_map_view.cpp +++ b/android/cpp/native_map_view.cpp @@ -585,90 +585,9 @@ EGLConfig NativeMapView::chooseConfig(const EGLConfig configs[], EGLint numConfi } void loadExtensions() { - const GLubyte *str = glGetString(GL_EXTENSIONS); - if (str == nullptr) { - mbgl::Log::Error(mbgl::Event::OpenGL, "glGetString(GL_EXTENSIONS) returned error %d", - glGetError()); - return; - } - - std::string extensions(reinterpret_cast(str)); - - if (extensions.find("GL_OES_vertex_array_object") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_OES_vertex_array_object."); - gl::BindVertexArray = reinterpret_cast( - eglGetProcAddress("glBindVertexArrayOES")); - gl::DeleteVertexArrays = reinterpret_cast( - eglGetProcAddress("glDeleteVertexArraysOES")); - gl::GenVertexArrays = reinterpret_cast( - eglGetProcAddress("glGenVertexArraysOES")); - gl::IsVertexArray = - reinterpret_cast(eglGetProcAddress("glIsVertexArrayOES")); - assert(gl::BindVertexArray != nullptr); - assert(gl::DeleteVertexArrays != nullptr); - assert(gl::GenVertexArrays != nullptr); - assert(gl::IsVertexArray != nullptr); - } - - if (extensions.find("GL_KHR_debug") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_KHR_debug."); - gl::DebugMessageControl = reinterpret_cast( - eglGetProcAddress("glDebugMessageControl")); - gl::DebugMessageInsert = reinterpret_cast( - eglGetProcAddress("glDebugMessageInsert")); - gl::DebugMessageCallback = reinterpret_cast( - eglGetProcAddress("glDebugMessageCallback")); - gl::GetDebugMessageLog = reinterpret_cast( - eglGetProcAddress("glGetDebugMessageLog")); - gl::GetPointerv = - reinterpret_cast(eglGetProcAddress("glGetPointerv")); - gl::PushDebugGroup = - reinterpret_cast(eglGetProcAddress("glPushDebugGroup")); - gl::PopDebugGroup = - reinterpret_cast(eglGetProcAddress("glPopDebugGroup")); - gl::ObjectLabel = - reinterpret_cast(eglGetProcAddress("glObjectLabel")); - gl::GetObjectLabel = - reinterpret_cast(eglGetProcAddress("glGetObjectLabel")); - gl::ObjectPtrLabel = - reinterpret_cast(eglGetProcAddress("glObjectPtrLabel")); - gl::GetObjectPtrLabel = reinterpret_cast( - eglGetProcAddress("glGetObjectPtrLabel")); - assert(gl::DebugMessageControl != nullptr); - assert(gl::DebugMessageInsert != nullptr); - assert(gl::DebugMessageCallback != nullptr); - assert(gl::GetDebugMessageLog != nullptr); - assert(gl::GetPointerv != nullptr); - assert(gl::PushDebugGroup != nullptr); - assert(gl::PopDebugGroup != nullptr); - assert(gl::ObjectLabel != nullptr); - assert(gl::GetObjectLabel != nullptr); - assert(gl::ObjectPtrLabel != nullptr); - assert(gl::GetObjectPtrLabel != nullptr); - } else { - if (extensions.find("GL_EXT_debug_marker") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_EXT_debug_marker."); - gl::InsertEventMarkerEXT = reinterpret_cast( - eglGetProcAddress("glInsertEventMarkerEXT")); - gl::PushGroupMarkerEXT = reinterpret_cast( - eglGetProcAddress("glPushGroupMarkerEXT")); - gl::PopGroupMarkerEXT = reinterpret_cast( - eglGetProcAddress("glPopGroupMarkerEXT")); - assert(gl::InsertEventMarkerEXT != nullptr); - assert(gl::PushGroupMarkerEXT != nullptr); - assert(gl::PopGroupMarkerEXT != nullptr); - } - - if (extensions.find("GL_EXT_debug_label") != std::string::npos) { - mbgl::Log::Info(mbgl::Event::OpenGL, "Using GL_EXT_debug_label."); - gl::LabelObjectEXT = reinterpret_cast( - eglGetProcAddress("glLabelObjectEXT")); - gl::GetObjectLabelEXT = reinterpret_cast( - eglGetProcAddress("glGetObjectLabelEXT")); - assert(gl::LabelObjectEXT != nullptr); - assert(gl::GetObjectLabelEXT != nullptr); - } - } + mbgl::gl::InitializeExtensions([] (const char * name) { + return reinterpret_cast(eglGetProcAddress(name)); + }); } void NativeMapView::pause() { diff --git a/include/mbgl/platform/gl.hpp b/include/mbgl/platform/gl.hpp index 1b842b080..73f0801fa 100644 --- a/include/mbgl/platform/gl.hpp +++ b/include/mbgl/platform/gl.hpp @@ -3,6 +3,7 @@ #include #include +#include #if __APPLE__ #include "TargetConditionals.h" @@ -44,137 +45,37 @@ void checkError(const char *cmd, const char *file, int line); #define MBGL_CHECK_ERROR(cmd) (cmd) #endif -// GL_KHR_debug / GL_ARB_debug_output -#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 -typedef void (* GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); -typedef void (* PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (* PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -typedef void (* PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); -typedef GLuint (* PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -typedef void (* PFNGLGETPOINTERVPROC) (GLenum pname, void **params); -typedef void (* PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); -typedef void (* PFNGLPOPDEBUGGROUPPROC) (void); -typedef void (* PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -typedef void (* PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -typedef void (* PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); -typedef void (* PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -extern PFNGLDEBUGMESSAGECONTROLPROC DebugMessageControl; -extern PFNGLDEBUGMESSAGEINSERTPROC DebugMessageInsert; -extern PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback; -extern PFNGLGETDEBUGMESSAGELOGPROC GetDebugMessageLog; -extern PFNGLGETPOINTERVPROC GetPointerv; -extern PFNGLPUSHDEBUGGROUPPROC PushDebugGroup; -extern PFNGLPOPDEBUGGROUPPROC PopDebugGroup; -extern PFNGLOBJECTLABELPROC ObjectLabel; -extern PFNGLGETOBJECTLABELPROC GetObjectLabel; -extern PFNGLOBJECTPTRLABELPROC ObjectPtrLabel; -extern PFNGLGETOBJECTPTRLABELPROC GetObjectPtrLabel; -void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); - -// GL_EXT_debug_marker -typedef void (* PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (* PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (* PFNGLPOPGROUPMARKEREXTPROC) (void); -extern PFNGLINSERTEVENTMARKEREXTPROC InsertEventMarkerEXT; -extern PFNGLPUSHGROUPMARKEREXTPROC PushGroupMarkerEXT; -extern PFNGLPOPGROUPMARKEREXTPROC PopGroupMarkerEXT; - -// GL_EXT_debug_label -#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F -#define GL_PROGRAM_OBJECT_EXT 0x8B40 -#define GL_SHADER_OBJECT_EXT 0x8B48 -#define GL_BUFFER_OBJECT_EXT 0x9151 -#define GL_QUERY_OBJECT_EXT 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 -typedef void (* PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); -typedef void (* PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); -extern PFNGLLABELOBJECTEXTPROC LabelObjectEXT; -extern PFNGLGETOBJECTLABELEXTPROC GetObjectLabelEXT; - -// GL_ARB_vertex_array_object / GL_OES_vertex_array_object -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -typedef void (* PFNGLBINDVERTEXARRAYPROC) (GLuint array); -typedef void (* PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); -typedef void (* PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); -typedef GLboolean (* PFNGLISVERTEXARRAYPROC) (GLuint array); -extern PFNGLBINDVERTEXARRAYPROC BindVertexArray; -extern PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays; -extern PFNGLGENVERTEXARRAYSPROC GenVertexArrays; -extern PFNGLISVERTEXARRAYPROC IsVertexArray; - -// Debug group markers, useful for debugging on iOS -#if defined(DEBUG) -// static int indent = 0; -inline void start_group(const std::string &str) { - if (gl::PushDebugGroup != nullptr) { - MBGL_CHECK_ERROR(gl::PushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, GLsizei(str.size()), str.c_str())); - } else if (gl::PushGroupMarkerEXT != nullptr) { - MBGL_CHECK_ERROR(gl::PushGroupMarkerEXT(GLsizei(str.size() + 1), str.c_str())); - } - // fprintf(stderr, "%s%s\n", std::string(indent * 4, ' ').c_str(), str.c_str()); - // indent++; -} - -inline void end_group() { - if (gl::PopDebugGroup != nullptr) { - MBGL_CHECK_ERROR(gl::PopDebugGroup()); - } else if (gl::PopGroupMarkerEXT != nullptr) { - MBGL_CHECK_ERROR(gl::PopGroupMarkerEXT()); - } - // indent--; -} -#else -inline void start_group(const std::string &) {} -inline void end_group() {} -#endif - -struct group { - inline group(const std::string &str) { start_group(str); } - ~group() { end_group(); }; +class ExtensionFunctionBase { +public: + static std::vector& functions(); + typedef std::pair Probe; + std::vector probes; + void (*ptr)(); }; +template +class ExtensionFunction; + +template +class ExtensionFunction : protected ExtensionFunctionBase { +public: + ExtensionFunction(std::initializer_list probes_) { + probes = probes_; + ExtensionFunctionBase::functions().push_back(this); + } + + explicit operator bool() const { + return ptr; + } + + R operator()(Args... args) const { + return (*reinterpret_cast(ptr))(std::forward(args)...); + } +}; + +using glProc = void (*)(); +void InitializeExtensions(glProc (*getProcAddress)(const char *)); + } } diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp index fa27c0880..ed499d374 100644 --- a/platform/default/glfw_view.cpp +++ b/platform/default/glfw_view.cpp @@ -14,10 +14,6 @@ void glfwError(int error, const char *description) { } GLFWView::GLFWView(bool fullscreen_) : fullscreen(fullscreen_) { -#ifdef NVIDIA - glDiscardFramebufferEXT = reinterpret_cast(glfwGetProcAddress("glDiscardFramebufferEXT")); -#endif - glfwSetErrorCallback(glfwError); if (!glfwInit()) { @@ -66,82 +62,7 @@ GLFWView::GLFWView(bool fullscreen_) : fullscreen(fullscreen_) { glfwSetKeyCallback(window, onKey); pthread_once(&loadGLExtensions, [] { - const std::string extensions = reinterpret_cast(MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS))); - using namespace mbgl; - - if (extensions.find("GL_KHR_debug") != std::string::npos) { - gl::DebugMessageControl = reinterpret_cast(glfwGetProcAddress("glDebugMessageControl")); - gl::DebugMessageInsert = reinterpret_cast(glfwGetProcAddress("glDebugMessageInsert")); - gl::DebugMessageCallback = reinterpret_cast(glfwGetProcAddress("glDebugMessageCallback")); - gl::GetDebugMessageLog = reinterpret_cast(glfwGetProcAddress("glGetDebugMessageLog")); - gl::GetPointerv = reinterpret_cast(glfwGetProcAddress("glGetPointerv")); - gl::PushDebugGroup = reinterpret_cast(glfwGetProcAddress("glPushDebugGroup")); - gl::PopDebugGroup = reinterpret_cast(glfwGetProcAddress("glPopDebugGroup")); - gl::ObjectLabel = reinterpret_cast(glfwGetProcAddress("glObjectLabel")); - gl::GetObjectLabel = reinterpret_cast(glfwGetProcAddress("glGetObjectLabel")); - gl::ObjectPtrLabel = reinterpret_cast(glfwGetProcAddress("glObjectPtrLabel")); - gl::GetObjectPtrLabel = reinterpret_cast(glfwGetProcAddress("glGetObjectPtrLabel")); - assert(gl::DebugMessageControl != nullptr); - assert(gl::DebugMessageInsert != nullptr); - assert(gl::DebugMessageCallback != nullptr); - assert(gl::GetDebugMessageLog != nullptr); - assert(gl::GetPointerv != nullptr); - assert(gl::PushDebugGroup != nullptr); - assert(gl::PopDebugGroup != nullptr); - assert(gl::ObjectLabel != nullptr); - assert(gl::GetObjectLabel != nullptr); - assert(gl::ObjectPtrLabel != nullptr); - assert(gl::GetObjectPtrLabel != nullptr); - } else { - if (extensions.find("GL_ARB_debug_output") != std::string::npos) { - gl::DebugMessageControl = reinterpret_cast(glfwGetProcAddress("glDebugMessageControlARB")); - gl::DebugMessageInsert = reinterpret_cast(glfwGetProcAddress("glDebugMessageInsertARB")); - gl::DebugMessageCallback = reinterpret_cast(glfwGetProcAddress("glDebugMessageCallbackARB")); - gl::GetDebugMessageLog = reinterpret_cast(glfwGetProcAddress("glGetDebugMessageLogARB")); - gl::GetPointerv = reinterpret_cast(glfwGetProcAddress("glGetPointerv")); - assert(gl::DebugMessageControl != nullptr); - assert(gl::DebugMessageInsert != nullptr); - assert(gl::DebugMessageCallback != nullptr); - assert(gl::GetDebugMessageLog != nullptr); - assert(gl::GetPointerv != nullptr); - } - - if (extensions.find("GL_EXT_debug_marker") != std::string::npos) { - gl::InsertEventMarkerEXT = reinterpret_cast(glfwGetProcAddress("glInsertEventMarkerEXT")); - gl::PushGroupMarkerEXT = reinterpret_cast(glfwGetProcAddress("glPushGroupMarkerEXT")); - gl::PopGroupMarkerEXT = reinterpret_cast(glfwGetProcAddress("glPopGroupMarkerEXT")); - assert(gl::InsertEventMarkerEXT != nullptr); - assert(gl::PushGroupMarkerEXT != nullptr); - assert(gl::PopGroupMarkerEXT != nullptr); - } - - if (extensions.find("GL_EXT_debug_label") != std::string::npos) { - gl::LabelObjectEXT = reinterpret_cast(glfwGetProcAddress("glLabelObjectEXT")); - gl::GetObjectLabelEXT = reinterpret_cast(glfwGetProcAddress("glGetObjectLabelEXT")); - assert(gl::LabelObjectEXT != nullptr); - assert(gl::GetObjectLabelEXT != nullptr); - } - } - - if (extensions.find("GL_ARB_vertex_array_object") != std::string::npos) { - gl::BindVertexArray = reinterpret_cast(glfwGetProcAddress("glBindVertexArray")); - gl::DeleteVertexArrays = reinterpret_cast(glfwGetProcAddress("glDeleteVertexArrays")); - gl::GenVertexArrays = reinterpret_cast(glfwGetProcAddress("glGenVertexArrays")); - gl::IsVertexArray = reinterpret_cast(glfwGetProcAddress("glIsVertexArray")); - assert(gl::BindVertexArray != nullptr); - assert(gl::DeleteVertexArrays != nullptr); - assert(gl::GenVertexArrays != nullptr); - assert(gl::IsVertexArray != nullptr); - } else if (extensions.find("GL_APPLE_vertex_array_object") != std::string::npos) { - gl::BindVertexArray = reinterpret_cast(glfwGetProcAddress("glBindVertexArrayAPPLE")); - gl::DeleteVertexArrays = reinterpret_cast(glfwGetProcAddress("glDeleteVertexArraysAPPLE")); - gl::GenVertexArrays = reinterpret_cast(glfwGetProcAddress("glGenVertexArraysAPPLE")); - gl::IsVertexArray = reinterpret_cast(glfwGetProcAddress("glIsVertexArrayAPPLE")); - assert(gl::BindVertexArray != nullptr); - assert(gl::DeleteVertexArrays != nullptr); - assert(gl::GenVertexArrays != nullptr); - assert(gl::IsVertexArray != nullptr); - } + mbgl::gl::InitializeExtensions(glfwGetProcAddress); }); glfwMakeContextCurrent(nullptr); diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp index 41584b9a9..357c6fac7 100644 --- a/platform/default/headless_view.cpp +++ b/platform/default/headless_view.cpp @@ -17,22 +17,6 @@ pthread_once_t loadGLExtensions = PTHREAD_ONCE_INIT; #ifdef MBGL_USE_CGL #include - -typedef void (* CGLProc)(void); -CGLProc CGLGetProcAddress(const char *proc) { - static CFBundleRef framework = nullptr; - if (!framework) { - framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); - if (!framework) { - throw std::runtime_error("Failed to load OpenGL framework."); - } - } - - CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, proc, kCFStringEncodingASCII); - CGLProc symbol = reinterpret_cast(CFBundleGetFunctionPointerForName(framework, name)); - CFRelease(name); - return symbol; -} #elif MBGL_USE_GLX #include #endif @@ -62,36 +46,25 @@ void HeadlessView::loadExtensions() { } pthread_once(&loadGLExtensions, [] { - const char *extensionPtr = reinterpret_cast(MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS))); - - if (!extensionPtr) { - return; - } - const std::string extensions = extensionPtr; - #ifdef MBGL_USE_CGL - if (extensions.find("GL_APPLE_vertex_array_object") != std::string::npos) { - gl::BindVertexArray = reinterpret_cast(CGLGetProcAddress("glBindVertexArrayAPPLE")); - gl::DeleteVertexArrays = reinterpret_cast(CGLGetProcAddress("glDeleteVertexArraysAPPLE")); - gl::GenVertexArrays = reinterpret_cast(CGLGetProcAddress("glGenVertexArraysAPPLE")); - gl::IsVertexArray = reinterpret_cast(CGLGetProcAddress("glIsVertexArrayAPPLE")); - assert(gl::BindVertexArray != nullptr); - assert(gl::DeleteVertexArrays != nullptr); - assert(gl::GenVertexArrays != nullptr); - assert(gl::IsVertexArray != nullptr); - } + gl::InitializeExtensions([](const char * name) { + static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); + if (!framework) { + throw std::runtime_error("Failed to load OpenGL framework."); + } + + CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII); + void* symbol = CFBundleGetFunctionPointerForName(framework, str); + CFRelease(str); + + return reinterpret_cast(symbol); + }); #endif + #ifdef MBGL_USE_GLX - if (extensions.find("GL_ARB_vertex_array_object") != std::string::npos) { - gl::BindVertexArray = reinterpret_cast(glXGetProcAddress((const GLubyte *)"glBindVertexArray")); - gl::DeleteVertexArrays = reinterpret_cast(glXGetProcAddress((const GLubyte *)"glDeleteVertexArrays")); - gl::GenVertexArrays = reinterpret_cast(glXGetProcAddress((const GLubyte *)"glGenVertexArrays")); - gl::IsVertexArray = reinterpret_cast(glXGetProcAddress((const GLubyte *)"glIsVertexArray")); - assert(gl::BindVertexArray != nullptr); - assert(gl::DeleteVertexArrays != nullptr); - assert(gl::GenVertexArrays != nullptr); - assert(gl::IsVertexArray != nullptr); - } + gl::InitializeExtensions([](const char * name) { + return glXGetProcAddress(reinterpret_cast(name)); + }); #endif }); diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 72f2d420c..a2e55b337 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -235,22 +235,18 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration) // dispatch_once(&loadGLExtensions, ^ { - const std::string extensions = (char *)glGetString(GL_EXTENSIONS); + mbgl::gl::InitializeExtensions([](const char * name) { + static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles")); + if (!framework) { + throw std::runtime_error("Failed to load OpenGL framework."); + } - using namespace mbgl; + CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII); + void* symbol = CFBundleGetFunctionPointerForName(framework, str); + CFRelease(str); - if (extensions.find("GL_OES_vertex_array_object") != std::string::npos) { - gl::BindVertexArray = glBindVertexArrayOES; - gl::DeleteVertexArrays = glDeleteVertexArraysOES; - gl::GenVertexArrays = glGenVertexArraysOES; - gl::IsVertexArray = glIsVertexArrayOES; - } - - if (extensions.find("GL_EXT_debug_marker") != std::string::npos) { - gl::InsertEventMarkerEXT = glInsertEventMarkerEXT; - gl::PushGroupMarkerEXT = glPushGroupMarkerEXT; - gl::PopGroupMarkerEXT = glPopGroupMarkerEXT; - } + return reinterpret_cast(symbol); + }); }); // setup mbgl map diff --git a/src/mbgl/geometry/vao.cpp b/src/mbgl/geometry/vao.cpp index fef74396a..4f6e89332 100644 --- a/src/mbgl/geometry/vao.cpp +++ b/src/mbgl/geometry/vao.cpp @@ -5,11 +5,45 @@ namespace mbgl { +static gl::ExtensionFunction< + void (GLuint array)> + BindVertexArray({ + {"GL_ARB_vertex_array_object", "glBindVertexArray"}, + {"GL_OES_vertex_array_object", "glBindVertexArrayOES"}, + {"GL_APPLE_vertex_array_object", "glBindVertexArrayAPPLE"} + }); + +static gl::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"} + }); + +static gl::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"} + }); + +void VertexArrayObject::Bind(GLuint array) { + MBGL_CHECK_ERROR(BindVertexArray(array)); +} + +void VertexArrayObject::Delete(GLsizei n, const GLuint* arrays) { + MBGL_CHECK_ERROR(DeleteVertexArrays(n, arrays)); +} + VertexArrayObject::VertexArrayObject() { } VertexArrayObject::~VertexArrayObject() { - if (!gl::DeleteVertexArrays) return; + if (!DeleteVertexArrays) return; if (vao) { Environment::Get().abandonVAO(vao); @@ -17,7 +51,7 @@ VertexArrayObject::~VertexArrayObject() { } void VertexArrayObject::bindVertexArrayObject() { - if (!gl::GenVertexArrays || !gl::BindVertexArray) { + if (!GenVertexArrays || !BindVertexArray) { static bool reported = false; if (!reported) { Log::Warning(Event::OpenGL, "Not using Vertex Array Objects"); @@ -27,9 +61,9 @@ void VertexArrayObject::bindVertexArrayObject() { } if (!vao) { - MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &vao)); + MBGL_CHECK_ERROR(GenVertexArrays(1, &vao)); } - MBGL_CHECK_ERROR(gl::BindVertexArray(vao)); + MBGL_CHECK_ERROR(BindVertexArray(vao)); } void VertexArrayObject::verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, diff --git a/src/mbgl/geometry/vao.hpp b/src/mbgl/geometry/vao.hpp index 72bacfd79..e35fcc9bf 100644 --- a/src/mbgl/geometry/vao.hpp +++ b/src/mbgl/geometry/vao.hpp @@ -11,6 +11,9 @@ namespace mbgl { class VertexArrayObject : public util::noncopyable { public: + static void Bind(GLuint array); + static void Delete(GLsizei n, const GLuint* arrays); + VertexArrayObject(); ~VertexArrayObject(); diff --git a/src/mbgl/gl/debugging.cpp b/src/mbgl/gl/debugging.cpp new file mode 100644 index 000000000..5fc90e827 --- /dev/null +++ b/src/mbgl/gl/debugging.cpp @@ -0,0 +1,195 @@ +#include +#include +#include +#include + +#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 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"} + }); + +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"} + }); + +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)); +} + +#if defined(DEBUG) +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()), str.c_str()); + } +} + +group::~group() { + if (PopDebugGroup) { + PopDebugGroup(); + } else if (PopGroupMarkerEXT) { + PopGroupMarkerEXT(); + } +} +#else +group::group(const std::string&) {} +group::~group() = default; +#endif + +} +} +} diff --git a/src/mbgl/gl/debugging.hpp b/src/mbgl/gl/debugging.hpp new file mode 100644 index 000000000..82d08a53f --- /dev/null +++ b/src/mbgl/gl/debugging.hpp @@ -0,0 +1,21 @@ +#ifndef MBGL_GL_DEBUG_MESSAGES +#define MBGL_GL_DEBUG_MESSAGES + +#include + +namespace mbgl { +namespace gl { +namespace debugging { + +void enable(); + +struct group { + group(const std::string&); + ~group(); +}; + +} +} +} + +#endif diff --git a/src/mbgl/map/environment.cpp b/src/mbgl/map/environment.cpp index 327efeecf..d121f9655 100644 --- a/src/mbgl/map/environment.cpp +++ b/src/mbgl/map/environment.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -155,8 +156,8 @@ void Environment::performCleanup() { assert(currentlyOn(ThreadType::Map)); if (!abandonedVAOs.empty()) { - MBGL_CHECK_ERROR(gl::DeleteVertexArrays(static_cast(abandonedVAOs.size()), - abandonedVAOs.data())); + MBGL_CHECK_ERROR(VertexArrayObject::Delete(static_cast(abandonedVAOs.size()), + abandonedVAOs.data())); abandonedVAOs.clear(); } diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp index afe775be3..686b15c24 100644 --- a/src/mbgl/map/source.cpp +++ b/src/mbgl/map/source.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -179,7 +180,7 @@ void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transf void Source::drawClippingMasks(Painter &painter) { for (const auto& pair : tiles) { Tile &tile = *pair.second; - gl::group group(std::string { "mask: " } + std::string(tile.id)); + gl::debugging::group group(std::string { "mask: " } + std::string(tile.id)); painter.drawClippingMask(tile.matrix, tile.clip); } } diff --git a/src/mbgl/platform/gl.cpp b/src/mbgl/platform/gl.cpp index 096ec8393..3d8a237c7 100644 --- a/src/mbgl/platform/gl.cpp +++ b/src/mbgl/platform/gl.cpp @@ -1,74 +1,30 @@ #include -#include - -#include - namespace mbgl { namespace gl { -PFNGLDEBUGMESSAGECONTROLPROC DebugMessageControl = nullptr; -PFNGLDEBUGMESSAGEINSERTPROC DebugMessageInsert = nullptr; -PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback = nullptr; -PFNGLGETDEBUGMESSAGELOGPROC GetDebugMessageLog = nullptr; -PFNGLGETPOINTERVPROC GetPointerv = nullptr; -PFNGLPUSHDEBUGGROUPPROC PushDebugGroup = nullptr; -PFNGLPOPDEBUGGROUPPROC PopDebugGroup = nullptr; -PFNGLOBJECTLABELPROC ObjectLabel = nullptr; -PFNGLGETOBJECTLABELPROC GetObjectLabel = nullptr; -PFNGLOBJECTPTRLABELPROC ObjectPtrLabel = nullptr; -PFNGLGETOBJECTPTRLABELPROC GetObjectPtrLabel = nullptr; - -void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei, const GLchar *message, const void *) { - 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); +std::vector& ExtensionFunctionBase::functions() { + static std::vector functions; + return functions; } -PFNGLINSERTEVENTMARKEREXTPROC InsertEventMarkerEXT = nullptr; -PFNGLPUSHGROUPMARKEREXTPROC PushGroupMarkerEXT = nullptr; -PFNGLPOPGROUPMARKEREXTPROC PopGroupMarkerEXT = nullptr; +void InitializeExtensions(glProc (*getProcAddress)(const char *)) { + const char * extensionsPtr = reinterpret_cast( + MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS))); -PFNGLLABELOBJECTEXTPROC LabelObjectEXT = nullptr; -PFNGLGETOBJECTLABELEXTPROC GetObjectLabelEXT = nullptr; + if (!extensionsPtr) + return; -PFNGLBINDVERTEXARRAYPROC BindVertexArray = nullptr; -PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays = nullptr; -PFNGLGENVERTEXARRAYSPROC GenVertexArrays = nullptr; -PFNGLISVERTEXARRAYPROC IsVertexArray = nullptr; + const std::string extensions = extensionsPtr; + for (auto fn : ExtensionFunctionBase::functions()) { + for (auto probe : fn->probes) { + if (extensions.find(probe.first) != std::string::npos) { + fn->ptr = getProcAddress(probe.second); + break; + } + } + } +} void checkError(const char *cmd, const char *file, int line) { const GLenum err = glGetError(); diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 56d814c03..f306dec2d 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -56,18 +57,7 @@ bool Painter::needsAnimation() const { } void Painter::setup() { - // Enable GL debugging - if ((gl::DebugMessageControl != nullptr) && (gl::DebugMessageCallback != nullptr)) { - // This will enable all messages including performance hints - //MBGL_CHECK_ERROR(gl::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(gl::DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE)); - MBGL_CHECK_ERROR(gl::DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE)); - MBGL_CHECK_ERROR(gl::DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE)); - - MBGL_CHECK_ERROR(gl::DebugMessageCallback(gl::debug_callback, nullptr)); - } + gl::debugging::enable(); setupShaders(); @@ -160,7 +150,7 @@ void Painter::changeMatrix() { } void Painter::clear() { - gl::group group("clear"); + gl::debugging::group group("clear"); config.stencilTest = true; config.stencilMask = 0xFF; config.depthTest = false; @@ -212,7 +202,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time) // - UPLOAD PASS ------------------------------------------------------------------------------- // Uploads all required buffers and images before we do any actual rendering. { - const gl::group upload("upload"); + const gl::debugging::group upload("upload"); tileStencilBuffer.upload(); tileBorderBuffer.upload(); @@ -231,7 +221,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time) // - CLIPPING MASKS ---------------------------------------------------------------------------- // Draws the clipping masks to the stencil buffer. { - const gl::group clip("clip"); + const gl::debugging::group clip("clip"); // Update all clipping IDs. ClipIDGenerator generator; @@ -259,7 +249,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time) // - OPAQUE PASS ------------------------------------------------------------------------------- // Render everything top-to-bottom by using reverse iterators. Render opaque objects first. { - const gl::group _("opaque"); + const gl::debugging::group _("opaque"); if (debug::renderTree) { Log::Info(Event::Render, "%*s%s", indent++ * 4, "", "OPAQUE {"); @@ -270,13 +260,13 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time) const auto& item = *it; if (item.bucket && item.tile) { if (item.hasRenderPass(RenderPass::Opaque)) { - const gl::group group(item.layer.id + " - " + std::string(item.tile->id)); + const gl::debugging::group group(item.layer.id + " - " + std::string(item.tile->id)); setStrata(i * strata_thickness); prepareTile(*item.tile); item.bucket->render(*this, item.layer, item.tile->id, item.tile->matrix); } } else { - const gl::group group("background"); + const gl::debugging::group group("background"); setStrata(i * strata_thickness); renderBackground(item.layer); } @@ -289,7 +279,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time) // - TRANSLUCENT PASS -------------------------------------------------------------------------- // Make a second pass, rendering translucent objects. This time, we render bottom-to-top. { - const gl::group _("translucent"); + const gl::debugging::group _("translucent"); if (debug::renderTree) { Log::Info(Event::Render, "%*s%s", indent++ * 4, "", "TRANSLUCENT {"); @@ -300,7 +290,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time) const auto& item = *it; if (item.bucket && item.tile) { if (item.hasRenderPass(RenderPass::Translucent)) { - const gl::group group(item.layer.id + " - " + std::string(item.tile->id)); + const gl::debugging::group group(item.layer.id + " - " + std::string(item.tile->id)); setStrata(i * strata_thickness); prepareTile(*item.tile); item.bucket->render(*this, item.layer, item.tile->id, item.tile->matrix); @@ -317,7 +307,7 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time) // - DEBUG PASS -------------------------------------------------------------------------------- // Renders debug overlays. { - const gl::group _("debug"); + const gl::debugging::group _("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. @@ -331,10 +321,10 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time) // TODO: Find a better way to unbind VAOs after we're done with them without introducing // unnecessary bind(0)/bind(N) sequences. { - const gl::group _("cleanup"); + const gl::debugging::group _("cleanup"); MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, 0)); - MBGL_CHECK_ERROR(gl::BindVertexArray(0)); + MBGL_CHECK_ERROR(VertexArrayObject::Bind(0)); } } diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index c49535928..c2a8e6f50 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #ifndef BUFFER_OFFSET #define BUFFER_OFFSET(i) ((char *)nullptr + (i)) @@ -10,7 +11,7 @@ using namespace mbgl; void Painter::drawClippingMasks(const std::set& sources) { - gl::group group("clipping masks"); + gl::debugging::group group("clipping masks"); useProgram(plainShader->program); config.stencilTest = true; diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp index b252e2e83..d4306d3e1 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #ifndef BUFFER_OFFSET #define BUFFER_OFFSET(i) ((char *)nullptr + (i)) @@ -12,7 +13,7 @@ using namespace mbgl; void Painter::renderTileDebug(const Tile& tile) { - gl::group group(std::string { "debug " } + std::string(tile.id)); + gl::debugging::group group(std::string { "debug " } + std::string(tile.id)); assert(tile.data); if (debug) { prepareTile(tile); @@ -22,7 +23,7 @@ void Painter::renderTileDebug(const Tile& tile) { } void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) { - gl::group group("debug text"); + gl::debugging::group group("debug text"); config.depthTest = false; @@ -49,7 +50,7 @@ void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) { } void Painter::renderDebugFrame(const mat4 &matrix) { - gl::group group("debug frame"); + gl::debugging::group group("debug frame"); // Disable depth test and don't count this towards the depth buffer, // but *don't* disable stencil test, as we want to clip the red tile border @@ -72,7 +73,7 @@ void Painter::renderDebugText(const std::vector &strings) { return; } - gl::group group("debug text"); + gl::debugging::group group("debug text"); config.depthTest = false; config.stencilTest = true;