mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-31 22:25:21 -04:00
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
This commit is contained in:
parent
774548696c
commit
515679e4fe
11 changed files with 191 additions and 245 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue