[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