summaryrefslogtreecommitdiffstats
path: root/src/egl/main/eglcurrent.c
diff options
context:
space:
mode:
authorKyle Brenneman <[email protected]>2016-09-12 17:50:40 -0400
committerAdam Jackson <[email protected]>2016-10-05 11:40:51 -0400
commit6a5545d3ba60a19a3bce8f62141e0991a595eeaf (patch)
tree2c2f43ea6fc78b565162a4801e89be79341d3927 /src/egl/main/eglcurrent.c
parentf8b861a8673ca49eb6e4fbcdc1cf7f6be884afe1 (diff)
egl: Track EGL_KHR_debug state when going through EGL API calls (v3)
This decorates every EGL entrypoint with _EGL_FUNC_START, which records the function name and primary dispatch object label in the current thread state. It also adds debug report functions and calls them when appropriate. This would be useful enough for debugging on its own, if the user set a breakpoint when the report function was called. We will also need this state tracked in order to expose EGL_KHR_debug. v2: - Clear the object label in more cases in _eglSetFuncName - Pass draw surface (if any) to _EGL_FUNC_START in eglSwapInterval v3: - Set dummy thread's CurrentAPI to EGL_OPENGL_ES_API not zero - Less ?: in _eglSetFuncName Reviewed-by: Adam Jackson <[email protected]> Reviewed-by: Emil Velikov <[email protected]>
Diffstat (limited to 'src/egl/main/eglcurrent.c')
-rw-r--r--src/egl/main/eglcurrent.c91
1 files changed, 88 insertions, 3 deletions
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index f093becc7b4..eae7bdcea15 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"
@@ -37,7 +39,7 @@
/* This should be kept in sync with _eglInitThreadInfo() */
#define _EGL_THREAD_INFO_INITIALIZER \
- { EGL_SUCCESS, NULL, 0, NULL, NULL, NULL }
+ { EGL_SUCCESS, NULL, EGL_OPENGL_ES_API, NULL, NULL, NULL }
/* a fallback thread info to guarantee that every thread always has one */
static _EGLThreadInfo dummy_thread = _EGL_THREAD_INFO_INITIALIZER;
@@ -217,8 +219,8 @@ _eglGetCurrentContext(void)
/**
* Record EGL error code and return EGL_FALSE.
*/
-EGLBoolean
-_eglError(EGLint errCode, const char *msg)
+static EGLBoolean
+_eglInternalError(EGLint errCode, const char *msg)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
@@ -278,3 +280,86 @@ _eglError(EGLint errCode, const char *msg)
return EGL_FALSE;
}
+
+EGLBoolean
+_eglError(EGLint errCode, const char *msg)
+{
+ if (errCode != EGL_SUCCESS) {
+ EGLint type;
+ if (errCode == EGL_BAD_ALLOC) {
+ type = EGL_DEBUG_MSG_CRITICAL_KHR;
+ } else {
+ type = EGL_DEBUG_MSG_ERROR_KHR;
+ }
+
+ _eglDebugReport(errCode, msg, type, NULL);
+ } else
+ _eglInternalError(errCode, msg);
+
+ return EGL_FALSE;
+}
+
+/**
+ * Returns the label set for the current thread.
+ */
+EGLLabelKHR
+_eglGetThreadLabel(void)
+{
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+ return t->Label;
+}
+
+static void
+_eglDebugReportFullv(EGLenum error, const char *command, const char *funcName,
+ EGLint type, EGLLabelKHR objectLabel, const char *message, va_list args)
+{
+ 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) {
+ if (vasprintf(&buf, message, args) < 0) {
+ buf = NULL;
+ }
+ }
+ callback(error, command, type, _eglGetThreadLabel(), objectLabel, buf);
+ free(buf);
+ }
+
+ if (type == EGL_DEBUG_MSG_CRITICAL_KHR || type == EGL_DEBUG_MSG_ERROR_KHR) {
+ _eglInternalError(error, funcName);
+ }
+}
+
+void
+_eglDebugReportFull(EGLenum error, const char *command, const char *funcName,
+ EGLint type, EGLLabelKHR objectLabel, const char *message, ...)
+{
+ va_list args;
+ va_start(args, message);
+ _eglDebugReportFullv(error, command, funcName, type, objectLabel, message, args);
+ va_end(args);
+}
+
+void
+_eglDebugReport(EGLenum error, const char *funcName,
+ EGLint type, const char *message, ...)
+{
+ _EGLThreadInfo *thr = _eglGetCurrentThread();
+ va_list args;
+
+ if (funcName == NULL) {
+ funcName = thr->CurrentFuncName;
+ }
+
+ va_start(args, message);
+ _eglDebugReportFullv(error, thr->CurrentFuncName, funcName, type, thr->CurrentObjectLabel, message, args);
+ va_end(args);
+}