[Mesa-dev] [PATCH 3/6] EGL: Implement remaining functions from EGL_KHR_debug.
Kyle Brenneman
kbrenneman at nvidia.com
Wed Jul 6 16:33:44 UTC 2016
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 relace existing calls to _eglError with _eglDebugReport.
---
src/egl/main/eglapi.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++
src/egl/main/eglcurrent.c | 36 ++++++++++++++++++++++++--
src/egl/main/eglcurrent.h | 15 +++++++++++
src/egl/main/eglglobals.c | 5 +++-
src/egl/main/eglglobals.h | 15 +++++++++++
5 files changed, 132 insertions(+), 3 deletions(-)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index bba8a98..5220f98 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -1870,6 +1870,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)
@@ -1951,6 +2013,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 e75e804..5816967 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 }
@@ -294,9 +295,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 ce926aa..ed0d2f4 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -123,6 +123,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 */
--
1.9.1
More information about the mesa-dev
mailing list