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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to