Merge pull request #670 from mapbox/gl-debug

Use GL debug callbacks
This commit is contained in:
Leith Bade
2014-12-02 19:02:16 +11:00
8 changed files with 221 additions and 12 deletions

View File

@@ -8,11 +8,6 @@
#if TARGET_OS_IPHONE
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
// #define glGenVertexArrays glGenVertexArraysOES
// #define glBindVertexArray glBindVertexArrayOES
// #define glDeleteVertexArrays glDeleteVertexArraysOES
// #define GL_ARB_vertex_array_object 1
// #define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
#elif TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
@@ -34,6 +29,96 @@
namespace mbgl {
namespace gl {
// 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;
#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);
@@ -44,17 +129,25 @@ extern PFNGLGENVERTEXARRAYSPROC GenVertexArrays;
extern PFNGLISVERTEXARRAYPROC IsVertexArray;
// Debug group markers, useful for debuggin on iOS
#if __APPLE__ && defined(DEBUG) && defined(GL_EXT_debug_marker)
// Debug group markers, useful for debugging on iOS
#if defined(DEBUG)
// static int indent = 0;
inline void start_group(const std::string &str) {
glPushGroupMarkerEXT(0, str.c_str());
if (gl::PushDebugGroup != nullptr) {
gl::PushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, str.size(), str.c_str());
} else if (gl::PushGroupMarkerEXT != nullptr) {
gl::PushGroupMarkerEXT(str.size(), str.c_str());
}
// fprintf(stderr, "%s%s\n", std::string(indent * 4, ' ').c_str(), str.c_str());
// indent++;
}
inline void end_group() {
glPopGroupMarkerEXT();
if (gl::PopDebugGroup != nullptr) {
gl::PopDebugGroup();
} else if (gl::PopGroupMarkerEXT != nullptr) {
gl::PopGroupMarkerEXT();
}
// indent--;
}
#else

View File

@@ -73,6 +73,38 @@ void GLFWView::initialize(mbgl::Map *map_) {
{
using namespace mbgl;
if (extensions.find("GL_KHR_debug") != std::string::npos) {
gl::DebugMessageControl = (gl::PFNGLDEBUGMESSAGECONTROLPROC)glfwGetProcAddress("glDebugMessageControl");
gl::DebugMessageInsert = (gl::PFNGLDEBUGMESSAGEINSERTPROC)glfwGetProcAddress("glDebugMessageInsert");
gl::DebugMessageCallback = (gl::PFNGLDEBUGMESSAGECALLBACKPROC)glfwGetProcAddress("glDebugMessageCallback");
gl::GetDebugMessageLog = (gl::PFNGLGETDEBUGMESSAGELOGPROC)glfwGetProcAddress("glGetDebugMessageLog");
gl::GetPointerv = (gl::PFNGLGETPOINTERVPROC)glfwGetProcAddress("glGetPointerv");
gl::PushDebugGroup = (gl::PFNGLPUSHDEBUGGROUPPROC)glfwGetProcAddress("glPushDebugGroup");
gl::PopDebugGroup = (gl::PFNGLPOPDEBUGGROUPPROC)glfwGetProcAddress("glPopDebugGroup");
gl::ObjectLabel = (gl::PFNGLOBJECTLABELPROC)glfwGetProcAddress("glObjectLabel");
gl::GetObjectLabel = (gl::PFNGLGETOBJECTLABELPROC)glfwGetProcAddress("glGetObjectLabel");
gl::ObjectPtrLabel = (gl::PFNGLOBJECTPTRLABELPROC)glfwGetProcAddress("glObjectPtrLabel");
gl::GetObjectPtrLabel = (gl::PFNGLGETOBJECTPTRLABELPROC)glfwGetProcAddress("glGetObjectPtrLabel");
} else {
if (extensions.find("GL_ARB_debug_output") != std::string::npos) {
gl::DebugMessageControl = (gl::PFNGLDEBUGMESSAGECONTROLPROC)glfwGetProcAddress("glDebugMessageControlARB");
gl::DebugMessageInsert = (gl::PFNGLDEBUGMESSAGEINSERTPROC)glfwGetProcAddress("glDebugMessageInsertARB");
gl::DebugMessageCallback = (gl::PFNGLDEBUGMESSAGECALLBACKPROC)glfwGetProcAddress("glDebugMessageCallbackARB");
gl::GetDebugMessageLog = (gl::PFNGLGETDEBUGMESSAGELOGPROC)glfwGetProcAddress("glGetDebugMessageLogARB");
gl::GetPointerv = (gl::PFNGLGETPOINTERVPROC)glfwGetProcAddress("glGetPointerv");
}
if (extensions.find("GL_EXT_debug_marker") != std::string::npos) {
gl::InsertEventMarkerEXT = (gl::PFNGLINSERTEVENTMARKEREXTPROC)glfwGetProcAddress("glInsertEventMarkerEXT");
gl::PushGroupMarkerEXT = (gl::PFNGLPUSHGROUPMARKEREXTPROC)glfwGetProcAddress("glPushGroupMarkerEXT");
gl::PopGroupMarkerEXT = (gl::PFNGLPOPGROUPMARKEREXTPROC)glfwGetProcAddress("glPopGroupMarkerEXT");
}
if (extensions.find("GL_EXT_debug_label") != std::string::npos) {
gl::LabelObjectEXT = (gl::PFNGLLABELOBJECTEXTPROC)glfwGetProcAddress("glLabelObjectEXT");
gl::GetObjectLabelEXT = (gl::PFNGLGETOBJECTLABELEXTPROC)glfwGetProcAddress("glGetObjectLabelEXT");
}
}
if (extensions.find("GL_ARB_vertex_array_object") != std::string::npos) {
gl::BindVertexArray = (gl::PFNGLBINDVERTEXARRAYPROC)glfwGetProcAddress("glBindVertexArray");

View File

@@ -143,6 +143,9 @@ void GlyphAtlas::bind() {
if (!texture) {
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
#ifndef GL_ES_VERSION_2_0
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View File

@@ -201,6 +201,9 @@ void SpriteAtlas::bind(bool linear) {
if (!texture) {
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
#ifndef GL_ES_VERSION_2_0
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
first = true;

View File

@@ -1,4 +1,5 @@
#include <mbgl/platform/gl.hpp>
#include <mbgl/platform/log.hpp>
#include <iostream>
@@ -6,6 +7,64 @@
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);
}
PFNGLINSERTEVENTMARKEREXTPROC InsertEventMarkerEXT = nullptr;
PFNGLPUSHGROUPMARKEREXTPROC PushGroupMarkerEXT = nullptr;
PFNGLPOPGROUPMARKEREXTPROC PopGroupMarkerEXT = nullptr;
PFNGLLABELOBJECTEXTPROC LabelObjectEXT = nullptr;
PFNGLGETOBJECTLABELEXTPROC GetObjectLabelEXT = nullptr;
PFNGLBINDVERTEXARRAYPROC BindVertexArray = nullptr;
PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays = nullptr;
PFNGLGENVERTEXARRAYSPROC GenVertexArrays = nullptr;
@@ -27,9 +86,10 @@ void _CHECK_GL_ERROR(const char *cmd, const char *file, int line) {
case GL_INVALID_VALUE: error = "INVALID_VALUE"; break;
case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break;
default: error = "(unknown)"; break;
}
std::cerr << "GL_" << error.c_str() << " - " << file << ":" << line << std::endl;
mbgl::Log::Error(mbgl::Event::OpenGL, "GL_%s (0x%04X) - %s:%i", error.c_str(), file, line, err);
exit(1);
}
}
}

View File

@@ -42,6 +42,19 @@ void Painter::setup() {
#if defined(DEBUG)
util::stopwatch stopwatch("painter setup");
#endif
// Enable GL debugging
if ((gl::DebugMessageControl != nullptr) && (gl::DebugMessageCallback != nullptr)) {
// This will enable all messages including performance hints
gl::DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
// This will only enable high and medium severity messages
//gl::DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);
//gl::DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE);
gl::DebugMessageCallback(gl::debug_callback, nullptr);
}
setupShaders();
assert(iconShader);

View File

@@ -37,6 +37,9 @@ void PrerenderedTexture::bindFramebuffer() {
if (texture == 0) {
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
#ifndef GL_ES_VERSION_2_0
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View File

@@ -48,6 +48,9 @@ void Raster::bind(bool linear) {
if (img && !textured) {
texture = texturepool.getTextureID();
glBindTexture(GL_TEXTURE_2D, texture);
#ifndef GL_ES_VERSION_2_0
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->getData());
@@ -101,4 +104,3 @@ void Raster::updateTransitions(timestamp now) {
fade_transition = nullptr;
}
}