aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--backend/drm/renderer.c1
-rw-r--r--backend/headless/backend.c1
-rw-r--r--backend/rdp/backend.c1
-rwxr-xr-xglgen.sh103
-rw-r--r--include/render/gles2.h11
-rw-r--r--include/wlr/render/egl.h23
-rw-r--r--render/egl.c170
-rw-r--r--render/glapi.txt19
-rw-r--r--render/gles2/renderer.c79
-rw-r--r--render/gles2/texture.c17
-rw-r--r--render/meson.build11
11 files changed, 191 insertions, 245 deletions
diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c
index 9edf7632..25101a4b 100644
--- a/backend/drm/renderer.c
+++ b/backend/drm/renderer.c
@@ -11,7 +11,6 @@
#include <wlr/types/wlr_matrix.h>
#include <wlr/util/log.h>
#include "backend/drm/drm.h"
-#include "glapi.h"
bool init_drm_renderer(struct wlr_drm_backend *drm,
struct wlr_drm_renderer *renderer, wlr_renderer_create_func_t create_renderer_func) {
diff --git a/backend/headless/backend.c b/backend/headless/backend.c
index c0fc6022..d6bb141a 100644
--- a/backend/headless/backend.c
+++ b/backend/headless/backend.c
@@ -6,7 +6,6 @@
#include <wlr/render/gles2.h>
#include <wlr/util/log.h>
#include "backend/headless.h"
-#include "glapi.h"
#include "util/signal.h"
struct wlr_headless_backend *headless_backend_from_backend(
diff --git a/backend/rdp/backend.c b/backend/rdp/backend.c
index ef0fca85..c0b63921 100644
--- a/backend/rdp/backend.c
+++ b/backend/rdp/backend.c
@@ -6,7 +6,6 @@
#include <wlr/render/gles2.h>
#include <wlr/util/log.h>
#include "backend/rdp.h"
-#include "glapi.h"
#include "util/signal.h"
struct wlr_rdp_backend *rdp_backend_from_backend(
diff --git a/glgen.sh b/glgen.sh
deleted file mode 100755
index 31af2812..00000000
--- a/glgen.sh
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/bin/sh
-
-# Generates a simple GL/EGL extension function loader.
-#
-# The input is a .txt file, with each function to load on its own line.
-# If a line starts with a -, it is optional, and will not cause the loader
-# to fail if it can't load the function. You'll need to check if that function
-# is NULL before using it.
-
-if [ $# -ne 2 ]; then
- exit 1
-fi
-
-SPEC=$1
-OUTDIR=$2
-
-BASE=$(basename "$SPEC" .txt)
-INCLUDE_GUARD=$(printf %s_%s_H "$OUTDIR" "$BASE" | tr -c [:alnum:] _ | tr [:lower:] [:upper:])
-
-DECL=""
-DEFN=""
-LOADER=""
-
-DECL_FMT='extern %s %s;'
-DEFN_FMT='%s %s;'
-LOADER_FMT='%s = (%s)eglGetProcAddress("%s");'
-CHECK_FMT='if (!%s) {
- wlr_log(WLR_ERROR, "Unable to load %s");
- return false;
-}'
-
-while read -r COMMAND; do
- OPTIONAL=0
- FUNC_PTR_FMT='PFN%sPROC'
-
- case $COMMAND in
- -*)
- OPTIONAL=1
- ;;
- esac
-
- case $COMMAND in
- *WL)
- FUNC_PTR_FMT='PFN%s'
- ;;
- esac
-
- COMMAND=${COMMAND#-}
- FUNC_PTR=$(printf "$FUNC_PTR_FMT" "$COMMAND" | tr [:lower:] [:upper:])
-
- DECL="$DECL$(printf "\n$DECL_FMT" "$FUNC_PTR" "$COMMAND")"
- DEFN="$DEFN$(printf "\n$DEFN_FMT" "$FUNC_PTR" "$COMMAND")"
- LOADER="$LOADER$(printf "\n$LOADER_FMT" "$COMMAND" "$FUNC_PTR" "$COMMAND")"
-
- if [ $OPTIONAL -eq 0 ]; then
- LOADER="$LOADER$(printf "\n$CHECK_FMT" "$COMMAND" "$COMMAND")"
- fi
-done < "$SPEC"
-
-cat > "$OUTDIR/$BASE.h" << EOF
-#ifndef $INCLUDE_GUARD
-#define $INCLUDE_GUARD
-
-#include <stdbool.h>
-#include <wlr/config.h>
-
-#if !WLR_HAS_X11_BACKEND && !WLR_HAS_XWAYLAND
-#ifndef MESA_EGL_NO_X11_HEADERS
-#define MESA_EGL_NO_X11_HEADERS
-#endif
-#ifndef EGL_NO_X11
-#define EGL_NO_X11
-#endif
-#endif
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <EGL/eglmesaext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-bool load_$BASE(void);
-$DECL
-
-#endif
-EOF
-
-cat > "$OUTDIR/$BASE.c" << EOF
-#include <wlr/util/log.h>
-#include "$BASE.h"
-$DEFN
-
-bool load_$BASE(void) {
- static bool done = false;
- if (done) {
- return true;
- }
-$LOADER
-
- done = true;
- return true;
-}
-EOF
diff --git a/include/render/gles2.h b/include/render/gles2.h
index 7a629d69..817ec62d 100644
--- a/include/render/gles2.h
+++ b/include/render/gles2.h
@@ -14,6 +14,16 @@
#include <wlr/render/wlr_texture.h>
#include <wlr/util/log.h>
+struct wlr_gles2_procs {
+ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
+ PFNGLDEBUGMESSAGECALLBACKKHRPROC glDebugMessageCallbackKHR;
+ PFNGLDEBUGMESSAGECONTROLKHRPROC glDebugMessageControlKHR;
+ PFNGLPOPDEBUGGROUPKHRPROC glPopDebugGroupKHR;
+ PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR;
+};
+
+extern struct wlr_gles2_procs gles2_procs;
+
struct wlr_gles2_pixel_format {
enum wl_shm_format wl_format;
GLint gl_format, gl_type;
@@ -33,7 +43,6 @@ struct wlr_gles2_renderer {
struct wlr_renderer wlr_renderer;
struct wlr_egl *egl;
- const char *exts_str;
struct {
bool read_format_bgra_ext;
diff --git a/include/wlr/render/egl.h b/include/wlr/render/egl.h
index efded0b6..2853f8ed 100644
--- a/include/wlr/render/egl.h
+++ b/include/wlr/render/egl.h
@@ -22,6 +22,8 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+// TODO: remove eglmesaext.h
+#include <EGL/eglmesaext.h>
#include <pixman.h>
#include <stdbool.h>
#include <wayland-server-core.h>
@@ -34,8 +36,6 @@ struct wlr_egl {
EGLConfig config;
EGLContext context;
- const char *exts_str;
-
struct {
bool bind_wayland_display_wl;
bool buffer_age_ext;
@@ -43,10 +43,25 @@ struct wlr_egl {
bool image_dma_buf_export_mesa;
bool image_dmabuf_import_ext;
bool image_dmabuf_import_modifiers_ext;
- bool swap_buffers_with_damage_ext;
- bool swap_buffers_with_damage_khr;
+ bool swap_buffers_with_damage;
} exts;
+ struct {
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
+ PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT;
+ PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
+ PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
+ PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL;
+ PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplayWL;
+ PFNEGLUNBINDWAYLANDDISPLAYWL eglUnbindWaylandDisplayWL;
+ PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC eglSwapBuffersWithDamage; // KHR or EXT
+ PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT;
+ PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT;
+ PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQueryMESA;
+ PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA;
+ PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR;
+ } procs;
+
struct wl_display *wl_display;
struct wlr_drm_format_set dmabuf_formats;
diff --git a/render/egl.c b/render/egl.c
index cbd92cb9..14a7bf98 100644
--- a/render/egl.c
+++ b/render/egl.c
@@ -5,7 +5,6 @@
#include <wlr/render/egl.h>
#include <wlr/util/log.h>
#include <wlr/util/region.h>
-#include "glapi.h"
static bool egl_get_config(EGLDisplay disp, EGLint *attribs, EGLConfig *out,
EGLint visual_id) {
@@ -77,6 +76,15 @@ static bool check_egl_ext(const char *exts, const char *ext) {
return false;
}
+static void load_egl_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;
+}
+
static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats);
static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
uint64_t **modifiers);
@@ -125,11 +133,72 @@ out:
bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
EGLint *config_attribs, EGLint visual_id) {
- if (!load_glapi()) {
+ const char *exts_str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (exts_str == NULL) {
+ wlr_log(WLR_ERROR, "Failed to query EGL extensions");
+ return false;
+ }
+
+ if (!check_egl_ext(exts_str, "EGL_EXT_platform_base")) {
+ wlr_log(WLR_ERROR, "EGL_EXT_platform_base not supported");
return false;
}
+ load_egl_proc(&egl->procs.eglGetPlatformDisplayEXT,
+ "eglGetPlatformDisplayEXT");
+ load_egl_proc(&egl->procs.eglCreatePlatformWindowSurfaceEXT,
+ "eglCreatePlatformWindowSurfaceEXT");
+
+ if (check_egl_ext(exts_str, "EGL_KHR_image_base")) {
+ egl->exts.image_base_khr = true;
+ load_egl_proc(&egl->procs.eglCreateImageKHR, "eglCreateImageKHR");
+ load_egl_proc(&egl->procs.eglDestroyImageKHR, "eglDestroyImageKHR");
+ }
+
+ egl->exts.buffer_age_ext =
+ check_egl_ext(exts_str, "EGL_EXT_buffer_age");
+
+ if (check_egl_ext(exts_str, "EGL_KHR_swap_buffers_with_damage")) {
+ egl->exts.swap_buffers_with_damage = true;
+ load_egl_proc(&egl->procs.eglSwapBuffersWithDamage,
+ "eglSwapBuffersWithDamageKHR");
+ } else if (check_egl_ext(exts_str, "EGL_EXT_swap_buffers_with_damage")) {
+ egl->exts.swap_buffers_with_damage = true;
+ load_egl_proc(&egl->procs.eglSwapBuffersWithDamage,
+ "eglSwapBuffersWithDamageEXT");
+ }
+
+ egl->exts.image_dmabuf_import_ext =
+ check_egl_ext(exts_str, "EGL_EXT_image_dma_buf_import");
+ if (check_egl_ext(exts_str, "EGL_EXT_image_dma_buf_import_modifiers")) {
+ egl->exts.image_dmabuf_import_modifiers_ext = true;
+ load_egl_proc(&egl->procs.eglQueryDmaBufFormatsEXT,
+ "eglQueryDmaBufFormatsEXT");
+ load_egl_proc(&egl->procs.eglQueryDmaBufModifiersEXT,
+ "eglQueryDmaBufModifiersEXT");
+ }
+
+ if (check_egl_ext(exts_str, "EGL_MESA_image_dma_buf_export")) {
+ egl->exts.image_dma_buf_export_mesa = true;
+ load_egl_proc(&egl->procs.eglExportDMABUFImageQueryMESA,
+ "eglExportDMABUFImageQueryMESA");
+ load_egl_proc(&egl->procs.eglExportDMABUFImageMESA,
+ "eglExportDMABUFImageMESA");
+ }
+
+ if (check_egl_ext(exts_str, "EGL_WL_bind_wayland_display")) {
+ egl->exts.bind_wayland_display_wl = true;
+ load_egl_proc(&egl->procs.eglBindWaylandDisplayWL,
+ "eglBindWaylandDisplayWL");
+ load_egl_proc(&egl->procs.eglUnbindWaylandDisplayWL,
+ "eglUnbindWaylandDisplayWL");
+ load_egl_proc(&egl->procs.eglQueryWaylandBufferWL,
+ "eglQueryWaylandBufferWL");
+ }
+
+ if (check_egl_ext(exts_str, "EGL_KHR_debug")) {
+ load_egl_proc(&egl->procs.eglDebugMessageControlKHR,
+ "eglDebugMessageControlKHR");
- if (eglDebugMessageControlKHR) {
static const EGLAttrib debug_attribs[] = {
EGL_DEBUG_MSG_CRITICAL_KHR, EGL_TRUE,
EGL_DEBUG_MSG_ERROR_KHR, EGL_TRUE,
@@ -137,7 +206,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
EGL_DEBUG_MSG_INFO_KHR, EGL_TRUE,
EGL_NONE,
};
- eglDebugMessageControlKHR(egl_log, debug_attribs);
+ egl->procs.eglDebugMessageControlKHR(egl_log, debug_attribs);
}
if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
@@ -147,9 +216,11 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
if (platform == EGL_PLATFORM_SURFACELESS_MESA) {
assert(remote_display == NULL);
- egl->display = eglGetPlatformDisplayEXT(platform, EGL_DEFAULT_DISPLAY, NULL);
+ egl->display = egl->procs.eglGetPlatformDisplayEXT(platform,
+ EGL_DEFAULT_DISPLAY, NULL);
} else {
- egl->display = eglGetPlatformDisplayEXT(platform, remote_display, NULL);
+ egl->display = egl->procs.eglGetPlatformDisplayEXT(platform,
+ remote_display, NULL);
}
if (egl->display == EGL_NO_DISPLAY) {
wlr_log(WLR_ERROR, "Failed to create EGL display");
@@ -169,44 +240,14 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
goto error;
}
- egl->exts_str = eglQueryString(egl->display, EGL_EXTENSIONS);
-
wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor);
- wlr_log(WLR_INFO, "Supported EGL extensions: %s", egl->exts_str);
+ wlr_log(WLR_INFO, "Supported EGL extensions: %s", exts_str);
wlr_log(WLR_INFO, "EGL vendor: %s", eglQueryString(egl->display, EGL_VENDOR));
- egl->exts.image_base_khr =
- check_egl_ext(egl->exts_str, "EGL_KHR_image_base")
- && eglCreateImageKHR && eglDestroyImageKHR;
-
- egl->exts.buffer_age_ext =
- check_egl_ext(egl->exts_str, "EGL_EXT_buffer_age");
- egl->exts.swap_buffers_with_damage_ext =
- (check_egl_ext(egl->exts_str, "EGL_EXT_swap_buffers_with_damage") &&
- eglSwapBuffersWithDamageEXT);
- egl->exts.swap_buffers_with_damage_khr =
- (check_egl_ext(egl->exts_str, "EGL_KHR_swap_buffers_with_damage") &&
- eglSwapBuffersWithDamageKHR);
-
- egl->exts.image_dmabuf_import_ext =
- check_egl_ext(egl->exts_str, "EGL_EXT_image_dma_buf_import");
- egl->exts.image_dmabuf_import_modifiers_ext =
- check_egl_ext(egl->exts_str, "EGL_EXT_image_dma_buf_import_modifiers")
- && eglQueryDmaBufFormatsEXT && eglQueryDmaBufModifiersEXT;
-
- egl->exts.image_dma_buf_export_mesa =
- check_egl_ext(egl->exts_str, "EGL_MESA_image_dma_buf_export") &&
- eglExportDMABUFImageQueryMESA && eglExportDMABUFImageMESA;
-
init_dmabuf_formats(egl);
- egl->exts.bind_wayland_display_wl =
- check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display")
- && eglBindWaylandDisplayWL && eglUnbindWaylandDisplayWL
- && eglQueryWaylandBufferWL;
-
bool ext_context_priority =
- check_egl_ext(egl->exts_str, "EGL_IMG_context_priority");
+ check_egl_ext(exts_str, "EGL_IMG_context_priority");
size_t atti = 0;
EGLint attribs[5];
@@ -272,7 +313,7 @@ void wlr_egl_finish(struct wlr_egl *egl) {
eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (egl->wl_display) {
assert(egl->exts.bind_wayland_display_wl);
- eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);
+ egl->procs.eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);
}
eglDestroyContext(egl->display, egl->context);
@@ -285,7 +326,7 @@ bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display)
return false;
}
- if (eglBindWaylandDisplayWL(egl->display, local_display)) {
+ if (egl->procs.eglBindWaylandDisplayWL(egl->display, local_display)) {
egl->wl_display = local_display;
return true;
}
@@ -300,13 +341,13 @@ bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImage image) {
if (!image) {
return true;
}
- return eglDestroyImageKHR(egl->display, image);
+ return egl->procs.eglDestroyImageKHR(egl->display, image);
}
EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) {
- assert(eglCreatePlatformWindowSurfaceEXT);
- EGLSurface surf = eglCreatePlatformWindowSurfaceEXT(egl->display,
- egl->config, window, NULL);
+ assert(egl->procs.eglCreatePlatformWindowSurfaceEXT);
+ EGLSurface surf = egl->procs.eglCreatePlatformWindowSurfaceEXT(
+ egl->display, egl->config, window, NULL);
if (surf == EGL_NO_SURFACE) {
wlr_log(WLR_ERROR, "Failed to create EGL surface");
return EGL_NO_SURFACE;
@@ -355,8 +396,7 @@ bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface,
}
EGLBoolean ret;
- if (damage != NULL && (egl->exts.swap_buffers_with_damage_ext ||
- egl->exts.swap_buffers_with_damage_khr)) {
+ if (damage != NULL && egl->exts.swap_buffers_with_damage) {
EGLint width = 0, height = 0;
eglQuerySurface(egl->display, surface, EGL_WIDTH, &width);
eglQuerySurface(egl->display, surface, EGL_HEIGHT, &height);
@@ -387,13 +427,8 @@ bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface,
memset(egl_damage, 0, sizeof(egl_damage));
}
- if (egl->exts.swap_buffers_with_damage_ext) {
- ret = eglSwapBuffersWithDamageEXT(egl->display, surface, egl_damage,
- nrects);
- } else {
- ret = eglSwapBuffersWithDamageKHR(egl->display, surface, egl_damage,
- nrects);
- }
+ ret = egl->procs.eglSwapBuffersWithDamage(egl->display, surface,
+ egl_damage, nrects);
} else {
ret = eglSwapBuffers(egl->display, surface);
}
@@ -412,16 +447,17 @@ EGLImageKHR wlr_egl_create_image_from_wl_drm(struct wlr_egl *egl,
return NULL;
}
- if (!eglQueryWaylandBufferWL(egl->display, data, EGL_TEXTURE_FORMAT, fmt)) {
+ if (!egl->procs.eglQueryWaylandBufferWL(egl->display, data,
+ EGL_TEXTURE_FORMAT, fmt)) {
return NULL;
}
- eglQueryWaylandBufferWL(egl->display, data, EGL_WIDTH, width);
- eglQueryWaylandBufferWL(egl->display, data, EGL_HEIGHT, height);
+ egl->procs.eglQueryWaylandBufferWL(egl->display, data, EGL_WIDTH, width);
+ egl->procs.eglQueryWaylandBufferWL(egl->display, data, EGL_HEIGHT, height);
EGLint _inverted_y;
- if (eglQueryWaylandBufferWL(egl->display, data, EGL_WAYLAND_Y_INVERTED_WL,
- &_inverted_y)) {
+ if (egl->procs.eglQueryWaylandBufferWL(egl->display, data,
+ EGL_WAYLAND_Y_INVERTED_WL, &_inverted_y)) {
*inverted_y = !!_inverted_y;
} else {
*inverted_y = false;
@@ -431,8 +467,8 @@ EGLImageKHR wlr_egl_create_image_from_wl_drm(struct wlr_egl *egl,
EGL_WAYLAND_PLANE_WL, 0,
EGL_NONE,
};
- return eglCreateImageKHR(egl->display, egl->context, EGL_WAYLAND_BUFFER_WL,
- data, attribs);
+ return egl->procs.eglCreateImageKHR(egl->display, egl->context,
+ EGL_WAYLAND_BUFFER_WL, data, attribs);
}
EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
@@ -517,7 +553,7 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
attribs[atti++] = EGL_NONE;
assert(atti < sizeof(attribs)/sizeof(attribs[0]));
- return eglCreateImageKHR(egl->display, EGL_NO_CONTEXT,
+ return egl->procs.eglCreateImageKHR(egl->display, EGL_NO_CONTEXT,
EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
}
@@ -551,7 +587,7 @@ static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) {
}
EGLint num;
- if (!eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) {
+ if (!egl->procs.eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) {
wlr_log(WLR_ERROR, "Failed to query number of dmabuf formats");
return -1;
}
@@ -562,7 +598,7 @@ static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) {
return -1;
}
- if (!eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) {
+ if (!egl->procs.eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) {
wlr_log(WLR_ERROR, "Failed to query dmabuf format");
free(*formats);
return -1;
@@ -582,7 +618,7 @@ static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
}
EGLint num;
- if (!eglQueryDmaBufModifiersEXT(egl->display, format, 0,
+ if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->display, format, 0,
NULL, NULL, &num)) {
wlr_log(WLR_ERROR, "Failed to query dmabuf number of modifiers");
return -1;
@@ -598,7 +634,7 @@ static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
return -1;
}
- if (!eglQueryDmaBufModifiersEXT(egl->display, format, num,
+ if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->display, format, num,
*modifiers, NULL, &num)) {
wlr_log(WLR_ERROR, "Failed to query dmabuf modifiers");
free(*modifiers);
@@ -621,7 +657,7 @@ bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
}
// Only one set of modifiers is returned for all planes
- if (!eglExportDMABUFImageQueryMESA(egl->display, image,
+ if (!egl->procs.eglExportDMABUFImageQueryMESA(egl->display, image,
(int *)&attribs->format, &attribs->n_planes, &attribs->modifier)) {
return false;
}
@@ -631,7 +667,7 @@ bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
return false;
}
- if (!eglExportDMABUFImageMESA(egl->display, image, attribs->fd,
+ if (!egl->procs.eglExportDMABUFImageMESA(egl->display, image, attribs->fd,
(EGLint *)attribs->stride, (EGLint *)attribs->offset)) {
return false;
}
diff --git a/render/glapi.txt b/render/glapi.txt
deleted file mode 100644
index b1166f27..00000000
--- a/render/glapi.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-eglGetPlatformDisplayEXT
-eglCreatePlatformWindowSurfaceEXT
--eglCreateImageKHR
--eglDestroyImageKHR
--eglQueryWaylandBufferWL
--eglBindWaylandDisplayWL
--eglUnbindWaylandDisplayWL
--glEGLImageTargetTexture2DOES
--eglSwapBuffersWithDamageEXT
--eglSwapBuffersWithDamageKHR
--eglQueryDmaBufFormatsEXT
--eglQueryDmaBufModifiersEXT
--eglExportDMABUFImageQueryMESA
--eglExportDMABUFImageMESA
--eglDebugMessageControlKHR
--glDebugMessageCallbackKHR
--glDebugMessageControlKHR
--glPopDebugGroupKHR
--glPushDebugGroupKHR
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;
diff --git a/render/meson.build b/render/meson.build
index 87577aba..79daba93 100644
--- a/render/meson.build
+++ b/render/meson.build
@@ -1,12 +1,3 @@
-glgen = find_program('../glgen.sh')
-
-glapi = custom_target(
- 'glapi',
- input: 'glapi.txt',
- output: ['@BASENAME@.c', '@BASENAME@.h'],
- command: [glgen, '@INPUT@', '@OUTDIR@'],
-)
-
lib_wlr_render = static_library(
'wlr_render',
files(
@@ -20,7 +11,6 @@ lib_wlr_render = static_library(
'wlr_renderer.c',
'wlr_texture.c',
),
- glapi,
include_directories: wlr_inc,
dependencies: [
egl,
@@ -33,5 +23,4 @@ lib_wlr_render = static_library(
wlr_render = declare_dependency(
link_with: lib_wlr_render,
- sources: glapi[1],
)