[Mesa-dev] [PATCH 3/7] EGL: Implement remaining functions from EGL_KHR_debug
Kyle Brenneman
kbrenneman at nvidia.com
Thu Sep 8 17:57:36 UTC 2016
This one has the a bug in it where it doesn't set the callback if
(attrib_list == NULL), plus the more minor bug where it doesn't check
for invalid attributes if (callback == NULL). The first one is the same
bug you noticed in libglvnd, which got copied over when I adapted it for
Mesa. I can fix that and send out an updated patch if you like, or if
it's easier, I can add a commit to the end of this list.
-Kyle
On 09/08/2016 11:46 AM, Adam Jackson wrote:
> From: Kyle Brenneman <kbrenneman at 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 <ajax at 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 */
More information about the mesa-dev
mailing list