[Mesa-dev] [PATCH 3/7] EGL: Implement remaining functions from EGL_KHR_debug

Adam Jackson ajax at redhat.com
Thu Sep 8 17:46:58 UTC 2016


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 */
-- 
2.9.3



More information about the mesa-dev mailing list