aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2017-06-09 10:28:50 -0400
committerDrew DeVault <sir@cmpwn.com>2017-06-09 10:28:50 -0400
commit2b909e1729a5913098dcb67c46404a9ab93221e2 (patch)
treeca25b5e3922c95d2239e0efe169919e1282ac3e6
parent63c3faa006dd477faba635eb5c9962077058ffb3 (diff)
Add error "handling" to gles3 backend
-rw-r--r--include/render/gles3.h8
-rw-r--r--render/CMakeLists.txt1
-rw-r--r--render/gles3/renderer.c66
-rw-r--r--render/gles3/surface.c17
-rw-r--r--render/gles3/util.c38
5 files changed, 87 insertions, 43 deletions
diff --git a/include/render/gles3.h b/include/render/gles3.h
index 91b738a6..5efb197e 100644
--- a/include/render/gles3.h
+++ b/include/render/gles3.h
@@ -1,6 +1,8 @@
#ifndef _WLR_RENDER_GLES2_INTERNAL_H
#define _WLR_RENDER_GLES2_INTERNAL_H
#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
#include <GLES3/gl3.h>
#include <wlr/render.h>
@@ -15,4 +17,10 @@ extern const GLchar vertex_src[];
extern const GLchar fragment_src_RGB[];
extern const GLchar fragment_src_RGBA[];
+bool _gles3_flush_errors(const char *file, int line);
+#define gles3_flush_errors(...) \
+ _gles3_flush_errors(__FILE__ + strlen(WLR_SRC_DIR) + 1, __LINE__)
+
+#define GL_CALL(func) func; gles3_flush_errors()
+
#endif
diff --git a/render/CMakeLists.txt b/render/CMakeLists.txt
index aabf42d8..7b863d64 100644
--- a/render/CMakeLists.txt
+++ b/render/CMakeLists.txt
@@ -5,4 +5,5 @@ add_library(wlr-render STATIC
gles3/shaders.c
gles3/renderer.c
gles3/surface.c
+ gles3/util.c
)
diff --git a/render/gles3/renderer.c b/render/gles3/renderer.c
index 8f602fcf..74754d1b 100644
--- a/render/gles3/renderer.c
+++ b/render/gles3/renderer.c
@@ -17,17 +17,17 @@ static struct {
static GLuint vao, vbo, ebo;
static bool compile_shader(GLuint type, const GLchar *src, GLuint *shader) {
- *shader = glCreateShader(type);
+ *shader = GL_CALL(glCreateShader(type));
int len = strlen(src);
- glShaderSource(*shader, 1, &src, &len);
- glCompileShader(*shader);
+ GL_CALL(glShaderSource(*shader, 1, &src, &len));
+ GL_CALL(glCompileShader(*shader));
GLint success;
- glGetShaderiv(*shader, GL_COMPILE_STATUS, &success);
+ GL_CALL(glGetShaderiv(*shader, GL_COMPILE_STATUS, &success));
if (success == GL_FALSE) {
GLint loglen;
- glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &loglen);
+ GL_CALL(glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &loglen));
GLchar msg[loglen];
- glGetShaderInfoLog(*shader, loglen, &loglen, msg);
+ GL_CALL(glGetShaderInfoLog(*shader, loglen, &loglen, msg));
return false;
}
return true;
@@ -43,12 +43,10 @@ static bool compile_program(const GLchar *vert_src,
glDeleteProgram(vertex);
return false;
}
- *program = glCreateProgram();
- glAttachShader(*program, vertex);
- glAttachShader(*program, fragment);
- glLinkProgram(*program);
- glDeleteProgram(vertex);
- glDeleteProgram(fragment);
+ *program = GL_CALL(glCreateProgram());
+ GL_CALL(glAttachShader(*program, vertex));
+ GL_CALL(glAttachShader(*program, fragment));
+ GL_CALL(glLinkProgram(*program));
return true;
}
@@ -79,21 +77,21 @@ static void init_default_quad() {
1, 2, 3,
};
- glGenVertexArrays(1, &vao);
- glGenBuffers(1, &vbo);
+ GL_CALL(glGenVertexArrays(1, &vao));
+ GL_CALL(glGenBuffers(1, &vbo));
- glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ GL_CALL(glBindVertexArray(vao));
+ GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)(2 * sizeof(GLfloat)));
- glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW);
+ GL_CALL(glEnableVertexAttribArray(0));
+ GL_CALL(glEnableVertexAttribArray(1));
+ GL_CALL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)0));
+ GL_CALL(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)(2 * sizeof(GLfloat))));
+ GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW));
- glGenBuffers(1, &ebo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW);
+ GL_CALL(glGenBuffers(1, &ebo));
+ GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo));
+ GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW));
}
static void init_globals() {
@@ -104,11 +102,11 @@ static void init_globals() {
static void wlr_gles3_begin(struct wlr_renderer_state *state,
struct wlr_output *output) {
// TODO: let users customize the clear color?
- glClearColor(0.25f, 0.25f, 0.25f, 1);
- glClear(GL_COLOR_BUFFER_BIT);
+ GL_CALL(glClearColor(0.25f, 0.25f, 0.25f, 1));
+ GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
int32_t width = output->width;
int32_t height = output->height;
- glViewport(0, 0, width, height);
+ GL_CALL(glViewport(0, 0, width, height));
// Note: maybe we should save output projection and remove some of the need
// for users to sling matricies themselves
}
@@ -126,20 +124,20 @@ static bool wlr_gles3_render_surface(struct wlr_renderer_state *state,
assert(surface && surface->valid);
switch (surface->format) {
case GL_RGB:
- glUseProgram(shaders.rgb);
+ GL_CALL(glUseProgram(shaders.rgb));
break;
case GL_RGBA:
- glUseProgram(shaders.rgba);
+ GL_CALL(glUseProgram(shaders.rgba));
break;
default:
return false;
}
- glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
+ GL_CALL(glBindVertexArray(vao));
+ GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));
+ GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo));
wlr_surface_bind(surface);
- glUniformMatrix4fv(0, 1, GL_TRUE, *matrix);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ GL_CALL(glUniformMatrix4fv(0, 1, GL_TRUE, *matrix));
+ GL_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0));
return true;
}
diff --git a/render/gles3/surface.c b/render/gles3/surface.c
index 09d78715..c1fef48e 100644
--- a/render/gles3/surface.c
+++ b/render/gles3/surface.c
@@ -15,11 +15,10 @@ static bool gles3_surface_attach_pixels(struct wlr_surface_state *surface,
surface->wlr_surface->width = width;
surface->wlr_surface->height = height;
surface->wlr_surface->format = format;
- // TODO: Error handling
- glGenTextures(1, &surface->tex_id);
- glBindTexture(GL_TEXTURE_2D, surface->tex_id);
- glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
- format, GL_UNSIGNED_BYTE, pixels);
+ GL_CALL(glGenTextures(1, &surface->tex_id));
+ GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id));
+ GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
+ format, GL_UNSIGNED_BYTE, pixels));
surface->wlr_surface->valid = true;
return true;
}
@@ -37,10 +36,10 @@ static void gles3_surface_get_matrix(struct wlr_surface_state *surface,
}
static void gles3_surface_bind(struct wlr_surface_state *surface) {
- glActiveTexture(GL_TEXTURE0 + 1);
- glBindTexture(GL_TEXTURE_2D, surface->tex_id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ GL_CALL(glActiveTexture(GL_TEXTURE0 + 1));
+ GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id));
+ GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
}
static void gles3_surface_destroy(struct wlr_surface_state *surface) {
diff --git a/render/gles3/util.c b/render/gles3/util.c
new file mode 100644
index 00000000..1f216182
--- /dev/null
+++ b/render/gles3/util.c
@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include <stdbool.h>
+#include <GLES3/gl3.h>
+#include "common/log.h"
+#include "render/gles3.h"
+
+const char *gles3_strerror(GLenum err) {
+ switch (err) {
+ case GL_INVALID_ENUM:
+ return "Invalid enum";
+ case GL_INVALID_VALUE:
+ return "Invalid value";
+ case GL_INVALID_OPERATION:
+ return "Invalid operation";
+ case GL_OUT_OF_MEMORY:
+ return "Out of memory";
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ return "Invalid framebuffer operation";
+ default:
+ return "Unknown error";
+ }
+}
+
+bool _gles3_flush_errors(const char *file, int line) {
+ GLenum err;
+ bool failure = false;
+ while ((err = glGetError()) != GL_NO_ERROR) {
+ failure = true;
+ if (err == GL_OUT_OF_MEMORY) {
+ // The OpenGL context is now undefined
+ _wlr_log(L_ERROR, "[%s:%d] Fatal GL error: out of memory", file, line);
+ exit(1);
+ } else {
+ _wlr_log(L_ERROR, "[%s:%d] GL error %d %s", file, line, err, gles3_strerror(err));
+ }
+ }
+ return failure;
+}