aboutsummaryrefslogtreecommitdiff
path: root/render/gles2
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2019-11-10 14:31:33 +0100
committerScott Anderson <scott@anderso.nz>2019-12-20 01:03:34 +0000
commit515679e4fed1c7c762a8c269fca09cbb195a4323 (patch)
tree04e4011d75869e07839c2783efaaf52655cb1dbd /render/gles2
parent774548696c0a5f3164a3ce5a85d893da6c3b18be (diff)
Refactor EGL/GL API loading
Remove glapi.sh code generation, replace it with hand-written loading code that checks extension strings before calling eglGetProcAddress. The GLES2 renderer still uses global state because of: - {PUSH,POP}_GLES2_DEBUG macros - wlr_gles2_texture_from_* taking a wlr_egl instead of the renderer
Diffstat (limited to 'render/gles2')
-rw-r--r--render/gles2/renderer.c79
-rw-r--r--render/gles2/texture.c17
2 files changed, 59 insertions, 37 deletions
diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c
index 8bef5137..b5855d4e 100644
--- a/render/gles2/renderer.c
+++ b/render/gles2/renderer.c
@@ -11,9 +11,10 @@
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/util/log.h>
-#include "glapi.h"
#include "render/gles2.h"
+struct wlr_gles2_procs gles2_procs = {0};
+
static const struct wlr_renderer_impl renderer_impl;
static struct wlr_gles2_renderer *gles2_get_renderer(
@@ -219,13 +220,13 @@ static bool gles2_resource_is_wl_drm_buffer(struct wlr_renderer *wlr_renderer,
struct wl_resource *resource) {
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
- if (!eglQueryWaylandBufferWL) {
+ if (!renderer->egl->exts.bind_wayland_display_wl) {
return false;
}
EGLint fmt;
- return eglQueryWaylandBufferWL(renderer->egl->display, resource,
- EGL_TEXTURE_FORMAT, &fmt);
+ return renderer->egl->procs.eglQueryWaylandBufferWL(renderer->egl->display,
+ resource, EGL_TEXTURE_FORMAT, &fmt);
}
static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
@@ -233,12 +234,14 @@ static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
struct wlr_gles2_renderer *renderer =
gles2_get_renderer(wlr_renderer);
- if (!eglQueryWaylandBufferWL) {
+ if (!renderer->egl->exts.bind_wayland_display_wl) {
return;
}
- eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_WIDTH, width);
- eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_HEIGHT, height);
+ renderer->egl->procs.eglQueryWaylandBufferWL(renderer->egl->display,
+ buffer, EGL_WIDTH, width);
+ renderer->egl->procs.eglQueryWaylandBufferWL(renderer->egl->display,
+ buffer, EGL_HEIGHT, height);
}
static const struct wlr_drm_format_set *gles2_get_dmabuf_formats(
@@ -376,7 +379,7 @@ static void gles2_destroy(struct wlr_renderer *wlr_renderer) {
if (renderer->exts.debug_khr) {
glDisable(GL_DEBUG_OUTPUT_KHR);
- glDebugMessageCallbackKHR(NULL, NULL);
+ gles2_procs.glDebugMessageCallbackKHR(NULL, NULL);
}
free(renderer);
@@ -405,19 +408,19 @@ static const struct wlr_renderer_impl renderer_impl = {
};
void push_gles2_marker(const char *file, const char *func) {
- if (!glPushDebugGroupKHR) {
+ if (!gles2_procs.glPushDebugGroupKHR) {
return;
}
int len = snprintf(NULL, 0, "%s:%s", file, func) + 1;
char str[len];
snprintf(str, len, "%s:%s", file, func);
- glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, 1, -1, str);
+ gles2_procs.glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, 1, -1, str);
}
void pop_gles2_marker(void) {
- if (glPopDebugGroupKHR) {
- glPopDebugGroupKHR();
+ if (gles2_procs.glPopDebugGroupKHR) {
+ gles2_procs.glPopDebugGroupKHR();
}
}
@@ -516,6 +519,15 @@ static bool check_gl_ext(const char *exts, const char *ext) {
return false;
}
+static void load_gl_proc(void *proc_ptr, const char *name) {
+ void *proc = (void *)eglGetProcAddress(name);
+ if (proc == NULL) {
+ wlr_log(WLR_ERROR, "eglGetProcAddress(%s) failed", name);
+ abort();
+ }
+ *(void **)proc_ptr = proc;
+}
+
extern const GLchar quad_vertex_src[];
extern const GLchar quad_fragment_src[];
extern const GLchar ellipse_fragment_src[];
@@ -525,7 +537,9 @@ extern const GLchar tex_fragment_src_rgbx[];
extern const GLchar tex_fragment_src_external[];
struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
- if (!load_glapi()) {
+ const char *exts_str = (const char *)glGetString(GL_EXTENSIONS);
+ if (exts_str == NULL) {
+ wlr_log(WLR_ERROR, "Failed to get GL_EXTENSIONS");
return NULL;
}
@@ -542,37 +556,44 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
return NULL;
}
- renderer->exts_str = (const char *)glGetString(GL_EXTENSIONS);
wlr_log(WLR_INFO, "Using %s", glGetString(GL_VERSION));
wlr_log(WLR_INFO, "GL vendor: %s", glGetString(GL_VENDOR));
wlr_log(WLR_INFO, "GL renderer: %s", glGetString(GL_RENDERER));
- wlr_log(WLR_INFO, "Supported GLES2 extensions: %s", renderer->exts_str);
+ wlr_log(WLR_INFO, "Supported GLES2 extensions: %s", exts_str);
- if (!check_gl_ext(renderer->exts_str, "GL_EXT_texture_format_BGRA8888")) {
+ if (!check_gl_ext(exts_str, "GL_EXT_texture_format_BGRA8888")) {
wlr_log(WLR_ERROR, "BGRA8888 format not supported by GLES2");
free(renderer);
return NULL;
}
renderer->exts.read_format_bgra_ext =
- check_gl_ext(renderer->exts_str, "GL_EXT_read_format_bgra");
- renderer->exts.debug_khr =
- check_gl_ext(renderer->exts_str, "GL_KHR_debug") &&
- glDebugMessageCallbackKHR && glDebugMessageControlKHR;
- renderer->exts.egl_image_external_oes =
- check_gl_ext(renderer->exts_str, "GL_OES_EGL_image_external") &&
- glEGLImageTargetTexture2DOES;
+ check_gl_ext(exts_str, "GL_EXT_read_format_bgra");
+
+ if (check_gl_ext(exts_str, "GL_KHR_debug")) {
+ renderer->exts.debug_khr = true;
+ load_gl_proc(&gles2_procs.glDebugMessageCallbackKHR,
+ "glDebugMessageCallbackKHR");
+ load_gl_proc(&gles2_procs.glDebugMessageControlKHR,
+ "glDebugMessageControlKHR");
+ }
+
+ if (check_gl_ext(exts_str, "GL_OES_EGL_image_external")) {
+ renderer->exts.egl_image_external_oes = true;
+ load_gl_proc(&gles2_procs.glEGLImageTargetTexture2DOES,
+ "glEGLImageTargetTexture2DOES");
+ }
if (renderer->exts.debug_khr) {
glEnable(GL_DEBUG_OUTPUT_KHR);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
- glDebugMessageCallbackKHR(gles2_log, NULL);
+ gles2_procs.glDebugMessageCallbackKHR(gles2_log, NULL);
// Silence unwanted message types
- glDebugMessageControlKHR(GL_DONT_CARE, GL_DEBUG_TYPE_POP_GROUP_KHR,
- GL_DONT_CARE, 0, NULL, GL_FALSE);
- glDebugMessageControlKHR(GL_DONT_CARE, GL_DEBUG_TYPE_PUSH_GROUP_KHR,
- GL_DONT_CARE, 0, NULL, GL_FALSE);
+ gles2_procs.glDebugMessageControlKHR(GL_DONT_CARE,
+ GL_DEBUG_TYPE_POP_GROUP_KHR, GL_DONT_CARE, 0, NULL, GL_FALSE);
+ gles2_procs.glDebugMessageControlKHR(GL_DONT_CARE,
+ GL_DEBUG_TYPE_PUSH_GROUP_KHR, GL_DONT_CARE, 0, NULL, GL_FALSE);
}
PUSH_GLES2_DEBUG;
@@ -641,7 +662,7 @@ error:
if (renderer->exts.debug_khr) {
glDisable(GL_DEBUG_OUTPUT_KHR);
- glDebugMessageCallbackKHR(NULL, NULL);
+ gles2_procs.glDebugMessageCallbackKHR(NULL, NULL);
}
free(renderer);
diff --git a/render/gles2/texture.c b/render/gles2/texture.c
index 9ff88b35..7beb0672 100644
--- a/render/gles2/texture.c
+++ b/render/gles2/texture.c
@@ -11,7 +11,6 @@
#include <wlr/render/wlr_texture.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/util/log.h>
-#include "glapi.h"
#include "render/gles2.h"
#include "util/signal.h"
@@ -91,12 +90,12 @@ static bool gles2_texture_to_dmabuf(struct wlr_texture *wlr_texture,
if (!texture->image) {
assert(texture->target == GL_TEXTURE_2D);
- if (!eglCreateImageKHR) {
+ if (!texture->egl->exts.image_base_khr) {
return false;
}
- texture->image = eglCreateImageKHR(texture->egl->display,
- texture->egl->context, EGL_GL_TEXTURE_2D_KHR,
+ texture->image = texture->egl->procs.eglCreateImageKHR(
+ texture->egl->display, texture->egl->context, EGL_GL_TEXTURE_2D_KHR,
(EGLClientBuffer)(uintptr_t)texture->tex, NULL);
if (texture->image == EGL_NO_IMAGE_KHR) {
return false;
@@ -188,7 +187,7 @@ struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
}
- if (!glEGLImageTargetTexture2DOES) {
+ if (!gles2_procs.glEGLImageTargetTexture2DOES) {
return NULL;
}
@@ -230,7 +229,8 @@ struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
glGenTextures(1, &texture->tex);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->tex);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, texture->image);
+ gles2_procs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
+ texture->image);
POP_GLES2_DEBUG;
return &texture->wlr_texture;
@@ -242,7 +242,7 @@ struct wlr_texture *wlr_gles2_texture_from_dmabuf(struct wlr_egl *egl,
wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
}
- if (!glEGLImageTargetTexture2DOES) {
+ if (!gles2_procs.glEGLImageTargetTexture2DOES) {
return NULL;
}
@@ -290,7 +290,8 @@ struct wlr_texture *wlr_gles2_texture_from_dmabuf(struct wlr_egl *egl,
glGenTextures(1, &texture->tex);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->tex);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, texture->image);
+ gles2_procs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
+ texture->image);
POP_GLES2_DEBUG;
return &texture->wlr_texture;