summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2018-02-19 18:34:32 +0200
committerTobrun <tobrun@mapbox.com>2018-03-01 11:46:04 +0100
commit7fc676ed417ab509374f59a1e081605495cadcb3 (patch)
tree0d264ead6ede89bd549e5d651c0c604c796f3912
parentc84670e683f2e58aaa74fe3c236f6368950e2dab (diff)
downloadqtlocation-mapboxgl-7fc676ed417ab509374f59a1e081605495cadcb3.tar.gz
[android] custom layer example - add error checking to debug issues more easily
-rw-r--r--platform/android/src/example_custom_layer.cpp170
1 files changed, 142 insertions, 28 deletions
diff --git a/platform/android/src/example_custom_layer.cpp b/platform/android/src/example_custom_layer.cpp
index 4467cd5e23..4d1954f095 100644
--- a/platform/android/src/example_custom_layer.cpp
+++ b/platform/android/src/example_custom_layer.cpp
@@ -2,8 +2,111 @@
#include <GLES2/gl2.h>
#include <mbgl/util/logging.hpp>
-
+#include <mbgl/util/string.hpp>
#include <mbgl/style/layers/custom_layer.hpp>
+#include <vector>
+
+// DEBUGGING
+
+const char* stringFromError(GLenum err) {
+ switch (err) {
+ case GL_INVALID_ENUM:
+ return "GL_INVALID_ENUM";
+
+ case GL_INVALID_VALUE:
+ return "GL_INVALID_VALUE";
+
+ case GL_INVALID_OPERATION:
+ return "GL_INVALID_OPERATION";
+
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ return "GL_INVALID_FRAMEBUFFER_OPERATION";
+
+ case GL_OUT_OF_MEMORY:
+ return "GL_OUT_OF_MEMORY";
+
+#ifdef GL_TABLE_TOO_LARGE
+ case GL_TABLE_TOO_LARGE:
+ return "GL_TABLE_TOO_LARGE";
+#endif
+
+#ifdef GL_STACK_OVERFLOW
+ case GL_STACK_OVERFLOW:
+ return "GL_STACK_OVERFLOW";
+#endif
+
+#ifdef GL_STACK_UNDERFLOW
+ case GL_STACK_UNDERFLOW:
+ return "GL_STACK_UNDERFLOW";
+#endif
+
+#ifdef GL_CONTEXT_LOST
+ case GL_CONTEXT_LOST:
+ return "GL_CONTEXT_LOST";
+#endif
+
+ default:
+ return "GL_UNKNOWN";
+ }
+}
+
+struct Error : std::runtime_error {
+ using std::runtime_error::runtime_error;
+};
+
+void checkError(const char *cmd, const char *file, int line) {
+
+ GLenum err = GL_NO_ERROR;
+ if ((err = glGetError()) != GL_NO_ERROR) {
+ std::string message = std::string(cmd) + ": Error " + stringFromError(err);
+
+ // Check for further errors
+ while ((err = glGetError()) != GL_NO_ERROR) {
+ message += ", ";
+ message += stringFromError(err);
+ }
+
+ mbgl::Log::Error(mbgl::Event::General, message + " at " + file + ":" + mbgl::util::toString(line));
+ throw Error(message + " at " + file + ":" + mbgl::util::toString(line));
+ }
+}
+
+#ifndef NDEBUG
+#define GL_CHECK_ERROR(cmd) ([&]() { struct __MBGL_C_E { ~__MBGL_C_E() noexcept(false) { checkError(#cmd, __FILE__, __LINE__); } } __MBGL_C_E; return cmd; }())
+#else
+#define GL_CHECK_ERROR(cmd) (cmd)
+#endif
+
+void checkLinkStatus(GLuint program) {
+ GLint isLinked = 0;
+ glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
+ if (isLinked == GL_FALSE) {
+ GLint maxLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
+ GLchar infoLog[maxLength];
+ glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
+ mbgl::Log::Info(mbgl::Event::General, &infoLog[0]);
+ throw Error(infoLog);
+ }
+
+}
+
+void checkCompileStatus(GLuint shader) {
+ GLint isCompiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
+ if (isCompiled == GL_FALSE) {
+ GLint maxLength = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
+
+ // The maxLength includes the NULL character
+ GLchar errorLog[maxLength];
+ glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]);
+ mbgl::Log::Error(mbgl::Event::General, &errorLog[0]);
+ throw Error(errorLog);
+ }
+}
+
+// /DEBUGGING
static const GLchar * vertexShaderSource = "attribute vec2 a_pos; void main() { gl_Position = vec4(a_pos, 0, 1); }";
static const GLchar * fragmentShaderSource = "uniform highp vec4 fill_color; void main() { gl_FragColor = fill_color; }";
@@ -24,37 +127,48 @@ public:
void initialize() {
mbgl::Log::Info(mbgl::Event::General, "Initialize");
- program = glCreateProgram();
- vertexShader = glCreateShader(GL_VERTEX_SHADER);
- fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
-
- glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
- glCompileShader(vertexShader);
- glAttachShader(program, vertexShader);
- glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
- glCompileShader(fragmentShader);
- glAttachShader(program, fragmentShader);
- glLinkProgram(program);
- a_pos = glGetAttribLocation(program, "a_pos");
- fill_color = glGetUniformLocation(program, "fill_color");
-
- GLfloat background[] = { -1,-1, 1,-1, -1,1, 1,1 };
- glGenBuffers(1, &buffer);
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
- glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), background, GL_STATIC_DRAW);
+
+ // Debug info
+ int maxAttrib;
+ GL_CHECK_ERROR(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrib));
+ mbgl::Log::Info(mbgl::Event::General, "Max vertex attributes: %i", maxAttrib);
+
+ program = GL_CHECK_ERROR(glCreateProgram());
+ vertexShader = GL_CHECK_ERROR(glCreateShader(GL_VERTEX_SHADER));
+ fragmentShader = GL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER));
+
+ GL_CHECK_ERROR(glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr));
+ GL_CHECK_ERROR(glCompileShader(vertexShader));
+ checkCompileStatus(vertexShader);
+ GL_CHECK_ERROR(glAttachShader(program, vertexShader));
+ GL_CHECK_ERROR(glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr));
+ GL_CHECK_ERROR(glCompileShader(fragmentShader));
+ checkCompileStatus(fragmentShader);
+ GL_CHECK_ERROR(glAttachShader(program, fragmentShader));
+ GL_CHECK_ERROR(glLinkProgram(program));
+ checkLinkStatus(program);
+
+ a_pos = GL_CHECK_ERROR(glGetAttribLocation(program, "a_pos"));
+ fill_color = GL_CHECK_ERROR(glGetUniformLocation(program, "fill_color"));
+
+ GLfloat background[] = { -1, -1, 1, -1, -1, 1, 1, 1 };
+ GL_CHECK_ERROR(glGenBuffers(1, &buffer));
+ GL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, buffer));
+ GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), background, GL_STATIC_DRAW));
}
void render() {
mbgl::Log::Info(mbgl::Event::General, "Render");
- glUseProgram(program);
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
- glEnableVertexAttribArray(a_pos);
- glVertexAttribPointer(a_pos, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
- glUniform4fv(fill_color, 1, color);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ GL_CHECK_ERROR(glUseProgram(program));
+ GL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, buffer));
+ GL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
+ GL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_FLOAT, GL_FALSE, 0, NULL));
+ GL_CHECK_ERROR(glDisable(GL_STENCIL_TEST));
+ GL_CHECK_ERROR(glDisable(GL_DEPTH_TEST));
+ GL_CHECK_ERROR(glUniform4fv(fill_color, 1, color));
+ GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+
}
GLuint program = 0;