From: Kyle Brenneman <kbrenne...@nvidia.com> Implemented eglDebugMessageControlKHR and eglQueryDebugKHR. Added entries in _egl_global to hold the debug callback and the set of enabled message types.
Added a _eglDebugReport function to report a debug message, plus some macros for each of the message types. Still to do is to replace existing calls to _eglError with _eglDebugReport. Reviewed-by: Adam Jackson <a...@redhat.com> --- src/egl/main/eglapi.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ src/egl/main/eglcurrent.c | 37 +++++++++++++++++++++++++-- src/egl/main/eglcurrent.h | 15 +++++++++++ src/egl/main/eglglobals.c | 5 +++- src/egl/main/eglglobals.h | 15 +++++++++++ 5 files changed, 133 insertions(+), 3 deletions(-) diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 31b842f..e5b098e 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -1852,6 +1852,68 @@ eglLabelObjectKHR( } } +static EGLint +eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list) +{ + mtx_lock(_eglGlobal.Mutex); + + if (callback != NULL) { + if (attrib_list != NULL) { + unsigned int newEnabled = _eglGlobal.debugTypesEnabled; + int i; + + for (i = 0; attrib_list[i] != EGL_NONE; i += 2) { + if (attrib_list[i] >= EGL_DEBUG_MSG_CRITICAL_KHR && + attrib_list[i] <= EGL_DEBUG_MSG_INFO_KHR) { + if (attrib_list[i + 1]) { + newEnabled |= DebugBitFromType(attrib_list[i]); + } else { + newEnabled &= ~DebugBitFromType(attrib_list[i]); + } + } else { + // 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, "eglDebugMessageControlKHR", NULL, + "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]); + return EGL_BAD_ATTRIBUTE; + } + } + + _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 +eglQueryDebugKHR(EGLint attribute, EGLAttrib *value) +{ + mtx_lock(_eglGlobal.Mutex); + if (attribute >= EGL_DEBUG_MSG_CRITICAL_KHR && + attribute <= EGL_DEBUG_MSG_INFO_KHR) { + if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute)) { + *value = EGL_TRUE; + } else { + *value = EGL_FALSE; + } + } else if (attribute == EGL_DEBUG_CALLBACK_KHR) { + *value = (EGLAttrib) _eglGlobal.debugCallback; + } else { + mtx_unlock(_eglGlobal.Mutex); + _eglReportError(EGL_BAD_ATTRIBUTE, "eglQueryDebugKHR", NULL, + "Invalid attribute 0x%04lx", (unsigned long) attribute); + return EGL_FALSE; + } + mtx_unlock(_eglGlobal.Mutex); + return EGL_TRUE; +} __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname) @@ -1933,6 +1995,8 @@ eglGetProcAddress(const char *procname) { "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/eglcurrent.c b/src/egl/main/eglcurrent.c index 6dd6f4c..83db229 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -26,8 +26,10 @@ **************************************************************************/ +#include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdarg.h> #include "c99_compat.h" #include "c11/threads.h" @@ -35,7 +37,6 @@ #include "eglcurrent.h" #include "eglglobals.h" - /* This should be kept in sync with _eglInitThreadInfo() */ #define _EGL_THREAD_INFO_INITIALIZER \ { EGL_SUCCESS, { NULL }, 0 } @@ -283,8 +284,40 @@ _eglError(EGLint errCode, const char *msg) /** * Returns the label set for the current thread. */ -EGLLabelKHR _eglGetThreadLabel(void) +EGLLabelKHR +_eglGetThreadLabel(void) { _EGLThreadInfo *t = _eglGetCurrentThread(); return t->Label; } + +void +_eglDebugReport(EGLenum error, const char *command, EGLint type, EGLLabelKHR objectLabel, const char *message, ...) +{ + EGLDEBUGPROCKHR callback = NULL; + + mtx_lock(_eglGlobal.Mutex); + if (_eglGlobal.debugTypesEnabled & DebugBitFromType(type)) { + callback = _eglGlobal.debugCallback; + } + mtx_unlock(_eglGlobal.Mutex); + + if (callback != NULL) { + char *buf = NULL; + + if (message != NULL) { + va_list args; + va_start(args, message); + if (vasprintf(&buf, message, args) < 0) { + buf = NULL; + } + va_end(args); + } + callback(error, command, type, _eglGetThreadLabel(), objectLabel, buf); + free(buf); + } + + if (type == EGL_DEBUG_MSG_CRITICAL_KHR || type == EGL_DEBUG_MSG_ERROR_KHR) { + _eglError(error, command); + } +} diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h index e139271..92185c0 100644 --- a/src/egl/main/eglcurrent.h +++ b/src/egl/main/eglcurrent.h @@ -95,6 +95,21 @@ _eglError(EGLint errCode, const char *msg); extern EGLLabelKHR _eglGetThreadLabel(void); +extern void +_eglDebugReport(EGLenum error, const char *command, EGLint type, + EGLLabelKHR objectLabel, const char *message, ...); + +#define _eglReportCritical(error, command, objLabel, ...) \ + _eglDebugReport(error, command, EGL_DEBUG_MSG_ERROR_KHR, objLabel, __VA_ARGS__) + +#define _eglReportError(error, command, objLabel, ...) \ + _eglDebugReport(error, command, EGL_DEBUG_MSG_CRITICAL_KHR, objLabel, __VA_ARGS__) + +#define _eglReportWarn(command, objLabel, ...) \ + _eglDebugReport(EGL_SUCCESS, command, EGL_DEBUG_MSG_WARN_KHR, objLabel, __VA_ARGS__) + +#define _eglReportInfo(command, objLabel, ...) \ + _eglDebugReport(EGL_SUCCESS, command, EGL_DEBUG_MSG_INFO_KHR, objLabel, __VA_ARGS__) #ifdef __cplusplus } diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 938d953..f67bc25 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -56,7 +56,10 @@ struct _egl_global _eglGlobal = " EGL_EXT_platform_wayland" " EGL_EXT_platform_x11" " EGL_KHR_client_get_all_proc_addresses" - " EGL_MESA_platform_gbm" + " EGL_MESA_platform_gbm", + + NULL, /* debugCallback */ + _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR, /* debugTypesEnabled */ }; diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index ae1b75b..ec4f3d0 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -36,6 +36,13 @@ #include "egltypedefs.h" +enum +{ + _EGL_DEBUG_BIT_CRITICAL = 0x1, + _EGL_DEBUG_BIT_ERROR = 0x2, + _EGL_DEBUG_BIT_WARN = 0x4, + _EGL_DEBUG_BIT_INFO = 0x8, +}; /** * Global library data @@ -51,6 +58,9 @@ struct _egl_global void (*AtExitCalls[10])(void); const char *ClientExtensionString; + + EGLDEBUGPROCKHR debugCallback; + unsigned int debugTypesEnabled; }; @@ -60,5 +70,10 @@ extern struct _egl_global _eglGlobal; extern void _eglAddAtExitCall(void (*func)(void)); +static inline unsigned int DebugBitFromType(EGLenum type) +{ + assert(type >= EGL_DEBUG_MSG_CRITICAL_KHR && type <= EGL_DEBUG_MSG_INFO_KHR); + return (1 << (type - EGL_DEBUG_MSG_CRITICAL_KHR)); +} #endif /* EGLGLOBALS_INCLUDED */ -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev