diff options
author | Simon Ser <contact@emersion.fr> | 2019-11-10 14:31:33 +0100 |
---|---|---|
committer | Scott Anderson <scott@anderso.nz> | 2019-12-20 01:03:34 +0000 |
commit | 515679e4fed1c7c762a8c269fca09cbb195a4323 (patch) | |
tree | 04e4011d75869e07839c2783efaaf52655cb1dbd /render/gles2 | |
parent | 774548696c0a5f3164a3ce5a85d893da6c3b18be (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.c | 79 | ||||
-rw-r--r-- | render/gles2/texture.c | 17 |
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; |