From ca9f26ac6fcb0afb68101fb3f74fcb3100507c0c Mon Sep 17 00:00:00 2001 From: Kyle Brenneman Date: Mon, 12 Sep 2016 17:51:22 -0400 Subject: [PATCH] egl: Implement EGL_KHR_debug (v2) Wire up the debug entrypoints to EGL dispatch, and add the extension string to the client extension list. v2: - Lots of style fixes - Fix missing EGLAPIENTRYs - Factor out valid attribute check - Lock display in eglLabelObjectKHR as needed, and use RETURN_EGL_* - Move "EGL_KHR_debug" into asciibetical order in client extension string Reviewed-by: Adam Jackson Reviewed-by: Emil Velikov --- src/egl/main/eglapi.c | 145 ++++++++++++++++++++++++++++++++++++++ src/egl/main/eglglobals.c | 1 + 2 files changed, 146 insertions(+) diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 88cdf06121f..d2a89af6880 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -2028,6 +2028,148 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image, RETURN_EGL_EVAL(disp, ret); } +static EGLint EGLAPIENTRY +eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object, + EGLLabelKHR label) +{ + _EGLDisplay *disp = NULL; + _EGLResourceType type; + + _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC); + + if (objectType == EGL_OBJECT_THREAD_KHR) { + _EGLThreadInfo *t = _eglGetCurrentThread(); + + if (!_eglIsCurrentThreadDummy()) { + t->Label = label; + return EGL_SUCCESS; + } + + RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC); + } + + disp = _eglLockDisplay(dpy); + if (disp == NULL) + RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY); + + if (objectType == EGL_OBJECT_DISPLAY_KHR) { + if (dpy != (EGLDisplay) object) + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER); + + disp->Label = label; + RETURN_EGL_EVAL(disp, EGL_SUCCESS); + } + + switch (objectType) { + case EGL_OBJECT_CONTEXT_KHR: + type = _EGL_RESOURCE_CONTEXT; + break; + case EGL_OBJECT_SURFACE_KHR: + type = _EGL_RESOURCE_SURFACE; + break; + case EGL_OBJECT_IMAGE_KHR: + type = _EGL_RESOURCE_IMAGE; + break; + case EGL_OBJECT_SYNC_KHR: + type = _EGL_RESOURCE_SYNC; + break; + case EGL_OBJECT_STREAM_KHR: + default: + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER); + } + + if (_eglCheckResource(object, type, disp)) { + _EGLResource *res = (_EGLResource *) object; + + res->Label = label; + RETURN_EGL_EVAL(disp, EGL_SUCCESS); + } + + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER); +} + +static EGLBoolean +validDebugMessageLevel(EGLAttrib level) +{ + return (level >= EGL_DEBUG_MSG_CRITICAL_KHR && + level <= EGL_DEBUG_MSG_INFO_KHR); +} + +static EGLint EGLAPIENTRY +eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, + const EGLAttrib *attrib_list) +{ + unsigned int newEnabled; + + _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC); + + mtx_lock(_eglGlobal.Mutex); + + newEnabled = _eglGlobal.debugTypesEnabled; + if (attrib_list != NULL) { + int i; + + for (i = 0; attrib_list[i] != EGL_NONE; i += 2) { + if (validDebugMessageLevel(attrib_list[i])) { + if (attrib_list[i + 1]) + newEnabled |= DebugBitFromType(attrib_list[i]); + else + newEnabled &= ~DebugBitFromType(attrib_list[i]); + continue; + } + + // On error, set the last error code, call the current + // debug callback, and return the error code. + mtx_unlock(_eglGlobal.Mutex); + _eglReportError(EGL_BAD_ATTRIBUTE, NULL, + "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]); + return EGL_BAD_ATTRIBUTE; + } + } + + if (callback != NULL) { + _eglGlobal.debugCallback = callback; + _eglGlobal.debugTypesEnabled = newEnabled; + } else { + _eglGlobal.debugCallback = NULL; + _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR; + } + + mtx_unlock(_eglGlobal.Mutex); + return EGL_SUCCESS; +} + +static EGLBoolean EGLAPIENTRY +eglQueryDebugKHR(EGLint attribute, EGLAttrib *value) +{ + _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC); + + mtx_lock(_eglGlobal.Mutex); + + do { + if (validDebugMessageLevel(attribute)) { + if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute)) + *value = EGL_TRUE; + else + *value = EGL_FALSE; + break; + } + + if (attribute == EGL_DEBUG_CALLBACK_KHR) { + *value = (EGLAttrib) _eglGlobal.debugCallback; + break; + } + + mtx_unlock(_eglGlobal.Mutex); + _eglReportError(EGL_BAD_ATTRIBUTE, NULL, + "Invalid attribute 0x%04lx", (unsigned long) attribute); + return EGL_FALSE; + } while (0); + + mtx_unlock(_eglGlobal.Mutex); + return EGL_TRUE; +} + __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname) { @@ -2107,6 +2249,9 @@ eglGetProcAddress(const char *procname) { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM }, { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA }, { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA }, + { "eglLabelObjectKHR", (_EGLProc) eglLabelObjectKHR }, + { "eglDebugMessageControlKHR", (_EGLProc) eglDebugMessageControlKHR }, + { "eglQueryDebugKHR", (_EGLProc) eglQueryDebugKHR }, { NULL, NULL } }; EGLint i; diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index dca5c21f0dc..ac1a263ab52 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -56,6 +56,7 @@ struct _egl_global _eglGlobal = " EGL_EXT_platform_wayland" " EGL_EXT_platform_x11" " EGL_KHR_client_get_all_proc_addresses" + " EGL_KHR_debug" " EGL_MESA_platform_gbm", NULL, /* debugCallback */ -- 2.30.2