mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 12:55:58 +01:00
Add error "handling" to gles3 backend
This commit is contained in:
parent
63c3faa006
commit
2b909e1729
5 changed files with 87 additions and 43 deletions
|
@ -1,6 +1,8 @@
|
||||||
#ifndef _WLR_RENDER_GLES2_INTERNAL_H
|
#ifndef _WLR_RENDER_GLES2_INTERNAL_H
|
||||||
#define _WLR_RENDER_GLES2_INTERNAL_H
|
#define _WLR_RENDER_GLES2_INTERNAL_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <wlr/render.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_RGB[];
|
||||||
extern const GLchar fragment_src_RGBA[];
|
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
|
#endif
|
||||||
|
|
|
@ -5,4 +5,5 @@ add_library(wlr-render STATIC
|
||||||
gles3/shaders.c
|
gles3/shaders.c
|
||||||
gles3/renderer.c
|
gles3/renderer.c
|
||||||
gles3/surface.c
|
gles3/surface.c
|
||||||
|
gles3/util.c
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,17 +17,17 @@ static struct {
|
||||||
static GLuint vao, vbo, ebo;
|
static GLuint vao, vbo, ebo;
|
||||||
|
|
||||||
static bool compile_shader(GLuint type, const GLchar *src, GLuint *shader) {
|
static bool compile_shader(GLuint type, const GLchar *src, GLuint *shader) {
|
||||||
*shader = glCreateShader(type);
|
*shader = GL_CALL(glCreateShader(type));
|
||||||
int len = strlen(src);
|
int len = strlen(src);
|
||||||
glShaderSource(*shader, 1, &src, &len);
|
GL_CALL(glShaderSource(*shader, 1, &src, &len));
|
||||||
glCompileShader(*shader);
|
GL_CALL(glCompileShader(*shader));
|
||||||
GLint success;
|
GLint success;
|
||||||
glGetShaderiv(*shader, GL_COMPILE_STATUS, &success);
|
GL_CALL(glGetShaderiv(*shader, GL_COMPILE_STATUS, &success));
|
||||||
if (success == GL_FALSE) {
|
if (success == GL_FALSE) {
|
||||||
GLint loglen;
|
GLint loglen;
|
||||||
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &loglen);
|
GL_CALL(glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &loglen));
|
||||||
GLchar msg[loglen];
|
GLchar msg[loglen];
|
||||||
glGetShaderInfoLog(*shader, loglen, &loglen, msg);
|
GL_CALL(glGetShaderInfoLog(*shader, loglen, &loglen, msg));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -43,12 +43,10 @@ static bool compile_program(const GLchar *vert_src,
|
||||||
glDeleteProgram(vertex);
|
glDeleteProgram(vertex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*program = glCreateProgram();
|
*program = GL_CALL(glCreateProgram());
|
||||||
glAttachShader(*program, vertex);
|
GL_CALL(glAttachShader(*program, vertex));
|
||||||
glAttachShader(*program, fragment);
|
GL_CALL(glAttachShader(*program, fragment));
|
||||||
glLinkProgram(*program);
|
GL_CALL(glLinkProgram(*program));
|
||||||
glDeleteProgram(vertex);
|
|
||||||
glDeleteProgram(fragment);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,21 +77,21 @@ static void init_default_quad() {
|
||||||
1, 2, 3,
|
1, 2, 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
glGenVertexArrays(1, &vao);
|
GL_CALL(glGenVertexArrays(1, &vao));
|
||||||
glGenBuffers(1, &vbo);
|
GL_CALL(glGenBuffers(1, &vbo));
|
||||||
|
|
||||||
glBindVertexArray(vao);
|
GL_CALL(glBindVertexArray(vao));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
GL_CALL(glEnableVertexAttribArray(0));
|
||||||
glEnableVertexAttribArray(1);
|
GL_CALL(glEnableVertexAttribArray(1));
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)0);
|
GL_CALL(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)));
|
GL_CALL(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(glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW));
|
||||||
|
|
||||||
glGenBuffers(1, &ebo);
|
GL_CALL(glGenBuffers(1, &ebo));
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo));
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW);
|
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_globals() {
|
static void init_globals() {
|
||||||
|
@ -104,11 +102,11 @@ static void init_globals() {
|
||||||
static void wlr_gles3_begin(struct wlr_renderer_state *state,
|
static void wlr_gles3_begin(struct wlr_renderer_state *state,
|
||||||
struct wlr_output *output) {
|
struct wlr_output *output) {
|
||||||
// TODO: let users customize the clear color?
|
// TODO: let users customize the clear color?
|
||||||
glClearColor(0.25f, 0.25f, 0.25f, 1);
|
GL_CALL(glClearColor(0.25f, 0.25f, 0.25f, 1));
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
|
||||||
int32_t width = output->width;
|
int32_t width = output->width;
|
||||||
int32_t height = output->height;
|
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
|
// Note: maybe we should save output projection and remove some of the need
|
||||||
// for users to sling matricies themselves
|
// 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);
|
assert(surface && surface->valid);
|
||||||
switch (surface->format) {
|
switch (surface->format) {
|
||||||
case GL_RGB:
|
case GL_RGB:
|
||||||
glUseProgram(shaders.rgb);
|
GL_CALL(glUseProgram(shaders.rgb));
|
||||||
break;
|
break;
|
||||||
case GL_RGBA:
|
case GL_RGBA:
|
||||||
glUseProgram(shaders.rgba);
|
GL_CALL(glUseProgram(shaders.rgba));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
glBindVertexArray(vao);
|
GL_CALL(glBindVertexArray(vao));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo));
|
||||||
wlr_surface_bind(surface);
|
wlr_surface_bind(surface);
|
||||||
glUniformMatrix4fv(0, 1, GL_TRUE, *matrix);
|
GL_CALL(glUniformMatrix4fv(0, 1, GL_TRUE, *matrix));
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
GL_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,10 @@ static bool gles3_surface_attach_pixels(struct wlr_surface_state *surface,
|
||||||
surface->wlr_surface->width = width;
|
surface->wlr_surface->width = width;
|
||||||
surface->wlr_surface->height = height;
|
surface->wlr_surface->height = height;
|
||||||
surface->wlr_surface->format = format;
|
surface->wlr_surface->format = format;
|
||||||
// TODO: Error handling
|
GL_CALL(glGenTextures(1, &surface->tex_id));
|
||||||
glGenTextures(1, &surface->tex_id);
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id));
|
||||||
glBindTexture(GL_TEXTURE_2D, surface->tex_id);
|
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
|
format, GL_UNSIGNED_BYTE, pixels));
|
||||||
format, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
surface->wlr_surface->valid = true;
|
surface->wlr_surface->valid = true;
|
||||||
return 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) {
|
static void gles3_surface_bind(struct wlr_surface_state *surface) {
|
||||||
glActiveTexture(GL_TEXTURE0 + 1);
|
GL_CALL(glActiveTexture(GL_TEXTURE0 + 1));
|
||||||
glBindTexture(GL_TEXTURE_2D, surface->tex_id);
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id));
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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) {
|
static void gles3_surface_destroy(struct wlr_surface_state *surface) {
|
||||||
|
|
38
render/gles3/util.c
Normal file
38
render/gles3/util.c
Normal file
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in a new issue