From b1f93bc5cc6eee4fd15b16bdc0337d665e83a040 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 21 Mar 2018 10:42:43 +0100 Subject: [PATCH] render/egl: use EGL_KHR_debug --- backend/drm/backend.c | 2 +- backend/drm/renderer.c | 2 +- backend/headless/output.c | 4 +- backend/wayland/output.c | 4 +- include/wlr/render/egl.h | 5 --- render/egl.c | 87 ++++++++++++++++++--------------------- render/glapi.txt | 1 + render/gles2/texture.c | 2 +- 8 files changed, 49 insertions(+), 58 deletions(-) diff --git a/backend/drm/backend.c b/backend/drm/backend.c index 75b44210..43a8d017 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -173,7 +173,7 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, } if (!wlr_egl_bind_display(&drm->renderer.egl, display)) { - wlr_log(L_INFO, "Failed to bind egl/wl display: %s", egl_error()); + wlr_log(L_INFO, "Failed to bind egl/wl display"); } drm->display_destroy.notify = handle_display_destroy; diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 7e330990..528cd26c 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -211,7 +211,7 @@ static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, tex->img = eglCreateImageKHR(renderer->egl.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); if (!tex->img) { - wlr_log(L_ERROR, "Failed to create EGL image: %s", egl_error()); + wlr_log(L_ERROR, "Failed to create EGL image"); abort(); } diff --git a/backend/headless/output.c b/backend/headless/output.c index 6ce8fc35..fc275eaf 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -13,7 +13,7 @@ static EGLSurface egl_create_surface(struct wlr_egl *egl, unsigned int width, EGLSurface surf = eglCreatePbufferSurface(egl->display, egl->config, attribs); if (surf == EGL_NO_SURFACE) { - wlr_log(L_ERROR, "Failed to create EGL surface: %s", egl_error()); + wlr_log(L_ERROR, "Failed to create EGL surface"); return EGL_NO_SURFACE; } return surf; @@ -123,7 +123,7 @@ struct wlr_output *wlr_headless_add_output(struct wlr_backend *wlr_backend, if (!eglMakeCurrent(output->backend->egl.display, output->egl_surface, output->egl_surface, output->backend->egl.context)) { - wlr_log(L_ERROR, "eglMakeCurrent failed: %s", egl_error()); + wlr_log(L_ERROR, "eglMakeCurrent failed"); goto error; } diff --git a/backend/wayland/output.c b/backend/wayland/output.c index fc40dea0..6becceb7 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -321,7 +321,7 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *_backend) { if (!eglMakeCurrent(output->backend->egl.display, output->egl_surface, output->egl_surface, output->backend->egl.context)) { - wlr_log(L_ERROR, "eglMakeCurrent failed: %s", egl_error()); + wlr_log(L_ERROR, "eglMakeCurrent failed"); goto error; } @@ -333,7 +333,7 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *_backend) { wl_callback_add_listener(output->frame_callback, &frame_listener, output); if (!eglSwapBuffers(output->backend->egl.display, output->egl_surface)) { - wlr_log(L_ERROR, "eglSwapBuffers failed: %s", egl_error()); + wlr_log(L_ERROR, "eglSwapBuffers failed"); goto error; } diff --git a/include/wlr/render/egl.h b/include/wlr/render/egl.h index f05a9837..aa429e8e 100644 --- a/include/wlr/render/egl.h +++ b/include/wlr/render/egl.h @@ -94,11 +94,6 @@ int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, int format, */ bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImageKHR image); -/** - * Returns a string for the last error ocurred with egl. - */ -const char *egl_error(void); - bool wlr_egl_make_current(struct wlr_egl *egl, EGLSurface surface, int *buffer_age); diff --git a/render/egl.c b/render/egl.c index d60da2ab..b1bd4884 100644 --- a/render/egl.c +++ b/render/egl.c @@ -12,43 +12,6 @@ // https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image_base.txt. // https://cgit.freedesktop.org/mesa/mesa/tree/docs/specs/WL_bind_wayland_display.spec -const char *egl_error(void) { - switch (eglGetError()) { - case EGL_SUCCESS: - return "Success"; - case EGL_NOT_INITIALIZED: - return "Not initialized"; - case EGL_BAD_ACCESS: - return "Bad access"; - case EGL_BAD_ALLOC: - return "Bad alloc"; - case EGL_BAD_ATTRIBUTE: - return "Bad attribute"; - case EGL_BAD_CONTEXT: - return "Bad Context"; - case EGL_BAD_CONFIG: - return "Bad Config"; - case EGL_BAD_CURRENT_SURFACE: - return "Bad current surface"; - case EGL_BAD_DISPLAY: - return "Bad display"; - case EGL_BAD_SURFACE: - return "Bad surface"; - case EGL_BAD_MATCH: - return "Bad match"; - case EGL_BAD_PARAMETER: - return "Bad parameter"; - case EGL_BAD_NATIVE_PIXMAP: - return "Bad native pixmap"; - case EGL_BAD_NATIVE_WINDOW: - return "Bad native window"; - case EGL_CONTEXT_LOST: - return "Context lost"; - default: - return "Unknown"; - } -} - static bool egl_get_config(EGLDisplay disp, EGLint *attribs, EGLConfig *out, EGLint visual_id) { EGLint count = 0, matched = 0, ret; @@ -84,6 +47,21 @@ static bool egl_get_config(EGLDisplay disp, EGLint *attribs, EGLConfig *out, return false; } +static log_importance_t egl_log_importance_to_wlr(EGLint type) { + switch (type) { + case EGL_DEBUG_MSG_CRITICAL_KHR: return L_ERROR; + case EGL_DEBUG_MSG_ERROR_KHR: return L_ERROR; + case EGL_DEBUG_MSG_WARN_KHR: return L_ERROR; + case EGL_DEBUG_MSG_INFO_KHR: return L_INFO; + default: return L_INFO; + } +} + +static void egl_log(EGLenum error, const char *command, EGLint msg_type, + EGLLabelKHR thread, EGLLabelKHR obj, const char *msg) { + _wlr_log(egl_log_importance_to_wlr(msg_type), "[EGL] %s: %s", command, msg); +} + static bool check_egl_ext(const char *egl_exts, const char *ext) { size_t extlen = strlen(ext); const char *end = egl_exts + strlen(egl_exts); @@ -128,8 +106,19 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, return false; } + if (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, + }; + eglDebugMessageControlKHR(egl_log, debug_attribs); + } + if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) { - wlr_log(L_ERROR, "Failed to bind to the OpenGL ES API: %s", egl_error()); + wlr_log(L_ERROR, "Failed to bind to the OpenGL ES API"); goto error; } @@ -140,13 +129,13 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, egl->display = eglGetPlatformDisplayEXT(platform, remote_display, NULL); } if (egl->display == EGL_NO_DISPLAY) { - wlr_log(L_ERROR, "Failed to create EGL display: %s", egl_error()); + wlr_log(L_ERROR, "Failed to create EGL display"); goto error; } EGLint major, minor; if (eglInitialize(egl->display, &major, &minor) == EGL_FALSE) { - wlr_log(L_ERROR, "Failed to initialize EGL: %s", egl_error()); + wlr_log(L_ERROR, "Failed to initialize EGL"); goto error; } @@ -161,7 +150,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, EGL_NO_CONTEXT, attribs); if (egl->context == EGL_NO_CONTEXT) { - wlr_log(L_ERROR, "Failed to create EGL context: %s", egl_error()); + wlr_log(L_ERROR, "Failed to create EGL context"); goto error; } @@ -199,12 +188,18 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, error: eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglTerminate(egl->display); + if (egl->display) { + eglTerminate(egl->display); + } eglReleaseThread(); return false; } void wlr_egl_finish(struct wlr_egl *egl) { + if (egl == NULL) { + return; + } + eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); if (egl->wl_display && eglUnbindWaylandDisplayWL) { eglUnbindWaylandDisplayWL(egl->display, egl->wl_display); @@ -259,7 +254,7 @@ EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) { EGLSurface surf = eglCreatePlatformWindowSurfaceEXT(egl->display, egl->config, window, NULL); if (surf == EGL_NO_SURFACE) { - wlr_log(L_ERROR, "Failed to create EGL surface: %s", egl_error()); + wlr_log(L_ERROR, "Failed to create EGL surface"); return EGL_NO_SURFACE; } return surf; @@ -274,7 +269,7 @@ int wlr_egl_get_buffer_age(struct wlr_egl *egl, EGLSurface surface) { EGLBoolean ok = eglQuerySurface(egl->display, surface, EGL_BUFFER_AGE_EXT, &buffer_age); if (!ok) { - wlr_log(L_ERROR, "Failed to get EGL surface buffer age: %s", egl_error()); + wlr_log(L_ERROR, "Failed to get EGL surface buffer age"); return -1; } @@ -284,7 +279,7 @@ int wlr_egl_get_buffer_age(struct wlr_egl *egl, EGLSurface surface) { bool wlr_egl_make_current(struct wlr_egl *egl, EGLSurface surface, int *buffer_age) { if (!eglMakeCurrent(egl->display, surface, surface, egl->context)) { - wlr_log(L_ERROR, "eglMakeCurrent failed: %s", egl_error()); + wlr_log(L_ERROR, "eglMakeCurrent failed"); return false; } @@ -322,7 +317,7 @@ bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface, } if (!ret) { - wlr_log(L_ERROR, "eglSwapBuffers failed: %s", egl_error()); + wlr_log(L_ERROR, "eglSwapBuffers failed"); return false; } return true; diff --git a/render/glapi.txt b/render/glapi.txt index 02ac7dd8..2077d1c3 100644 --- a/render/glapi.txt +++ b/render/glapi.txt @@ -10,3 +10,4 @@ eglCreatePlatformWindowSurfaceEXT -eglSwapBuffersWithDamageKHR -eglQueryDmaBufFormatsEXT -eglQueryDmaBufModifiersEXT +-eglDebugMessageControlKHR diff --git a/render/gles2/texture.c b/render/gles2/texture.c index 99f153b8..8da40032 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -198,7 +198,7 @@ static bool gles2_texture_upload_drm(struct wlr_texture *_tex, tex->image = wlr_egl_create_image(tex->egl, EGL_WAYLAND_BUFFER_WL, (EGLClientBuffer*) buf, attribs); if (!tex->image) { - wlr_log(L_ERROR, "failed to create egl image: %s", egl_error()); + wlr_log(L_ERROR, "failed to create EGL image"); return false; }