From 01818ad2c8c6b6bf3f77955775ccd5b1cffa0b29 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 20 Dec 2019 16:46:59 +0100 Subject: [PATCH] render: fix EGL extensions not loaded Some extensions are only advertised by the EGL implementation with a non-zero EGLDisplay. That's the case when the extension can only be enabled when the hardware/driver supports it for instance. Instead of checking for all extensions without a display, check only for EGL_EXT_platform_base and EGL_KHR_debug which are used before eglGetDisplay. Check for all other extensions when we have a display. Closes: https://github.com/swaywm/wlroots/issues/1955 --- render/egl.c | 89 +++++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/render/egl.c b/render/egl.c index 14a7bf98..088c4ad7 100644 --- a/render/egl.c +++ b/render/egl.c @@ -133,6 +133,9 @@ out: bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, EGLint *config_attribs, EGLint visual_id) { + // Check for EGL_EXT_platform_base before creating a display, because we + // actually use this extension to create displays. Check for EGL_KHR_debug + // before creating display to get EGL logs as soon as possible. const char *exts_str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); if (exts_str == NULL) { wlr_log(WLR_ERROR, "Failed to query EGL extensions"); @@ -148,6 +151,52 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, load_egl_proc(&egl->procs.eglCreatePlatformWindowSurfaceEXT, "eglCreatePlatformWindowSurfaceEXT"); + if (check_egl_ext(exts_str, "EGL_KHR_debug")) { + load_egl_proc(&egl->procs.eglDebugMessageControlKHR, + "eglDebugMessageControlKHR"); + + static const EGLAttrib debug_attribs[] = { + EGL_DEBUG_MSG_CRITICAL_KHR, EGL_TRUE, + EGL_DEBUG_MSG_ERROR_KHR, EGL_TRUE, + EGL_DEBUG_MSG_WARN_KHR, EGL_TRUE, + EGL_DEBUG_MSG_INFO_KHR, EGL_TRUE, + EGL_NONE, + }; + egl->procs.eglDebugMessageControlKHR(egl_log, debug_attribs); + } + + if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) { + wlr_log(WLR_ERROR, "Failed to bind to the OpenGL ES API"); + goto error; + } + + if (platform == EGL_PLATFORM_SURFACELESS_MESA) { + assert(remote_display == NULL); + egl->display = egl->procs.eglGetPlatformDisplayEXT(platform, + EGL_DEFAULT_DISPLAY, NULL); + } else { + egl->display = egl->procs.eglGetPlatformDisplayEXT(platform, + remote_display, NULL); + } + if (egl->display == EGL_NO_DISPLAY) { + wlr_log(WLR_ERROR, "Failed to create EGL display"); + goto error; + } + + egl->platform = platform; + + EGLint major, minor; + if (eglInitialize(egl->display, &major, &minor) == EGL_FALSE) { + wlr_log(WLR_ERROR, "Failed to initialize EGL"); + goto error; + } + + exts_str = eglQueryString(egl->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_KHR_image_base")) { egl->exts.image_base_khr = true; load_egl_proc(&egl->procs.eglCreateImageKHR, "eglCreateImageKHR"); @@ -195,46 +244,6 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, "eglQueryWaylandBufferWL"); } - if (check_egl_ext(exts_str, "EGL_KHR_debug")) { - load_egl_proc(&egl->procs.eglDebugMessageControlKHR, - "eglDebugMessageControlKHR"); - - static const EGLAttrib debug_attribs[] = { - EGL_DEBUG_MSG_CRITICAL_KHR, EGL_TRUE, - EGL_DEBUG_MSG_ERROR_KHR, EGL_TRUE, - EGL_DEBUG_MSG_WARN_KHR, EGL_TRUE, - EGL_DEBUG_MSG_INFO_KHR, EGL_TRUE, - EGL_NONE, - }; - egl->procs.eglDebugMessageControlKHR(egl_log, debug_attribs); - } - - if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) { - wlr_log(WLR_ERROR, "Failed to bind to the OpenGL ES API"); - goto error; - } - - if (platform == EGL_PLATFORM_SURFACELESS_MESA) { - assert(remote_display == NULL); - egl->display = egl->procs.eglGetPlatformDisplayEXT(platform, - EGL_DEFAULT_DISPLAY, NULL); - } else { - egl->display = egl->procs.eglGetPlatformDisplayEXT(platform, - remote_display, NULL); - } - if (egl->display == EGL_NO_DISPLAY) { - wlr_log(WLR_ERROR, "Failed to create EGL display"); - goto error; - } - - egl->platform = platform; - - EGLint major, minor; - if (eglInitialize(egl->display, &major, &minor) == EGL_FALSE) { - wlr_log(WLR_ERROR, "Failed to initialize EGL"); - goto error; - } - if (!egl_get_config(egl->display, config_attribs, &egl->config, visual_id)) { wlr_log(WLR_ERROR, "Failed to get EGL config"); goto error;