egl: move alloc & init out of _eglBuiltInDriver{DRI2,Haiku}
[mesa.git] / src / egl / main / eglcurrent.c
index 5d8cae4ee3198aab432678e04b94790dc431c678..7af3011b75764deeebc65abe1a7136f794291c59 100644 (file)
  **************************************************************************/
 
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdarg.h>
 #include "c99_compat.h"
 #include "c11/threads.h"
 
 #include "eglcurrent.h"
 #include "eglglobals.h"
 
-
-/* This should be kept in sync with _eglInitThreadInfo() */
-#define _EGL_THREAD_INFO_INITIALIZER \
-   { EGL_SUCCESS, { NULL }, 0 }
-
 /* a fallback thread info to guarantee that every thread always has one */
-static _EGLThreadInfo dummy_thread = _EGL_THREAD_INFO_INITIALIZER;
+static _EGLThreadInfo dummy_thread;
 static mtx_t _egl_TSDMutex = _MTX_INITIALIZER_NP;
 static EGLBoolean _egl_TSDInitialized;
 static tss_t _egl_TSD;
@@ -54,7 +51,7 @@ static __thread const _EGLThreadInfo *_egl_TLS
 
 static inline void _eglSetTSD(const _EGLThreadInfo *t)
 {
-   tss_set(_egl_TSD, (const void *) t);
+   tss_set(_egl_TSD, (void *) t);
 #ifdef GLX_USE_TLS
    _egl_TLS = t;
 #endif
@@ -108,10 +105,9 @@ static inline EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
 static void
 _eglInitThreadInfo(_EGLThreadInfo *t)
 {
-   memset(t, 0, sizeof(*t));
    t->LastError = EGL_SUCCESS;
    /* default, per EGL spec */
-   t->CurrentAPIIndex = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
+   t->CurrentAPI = EGL_OPENGL_ES_API;
 }
 
 
@@ -122,10 +118,10 @@ static _EGLThreadInfo *
 _eglCreateThreadInfo(void)
 {
    _EGLThreadInfo *t = calloc(1, sizeof(_EGLThreadInfo));
-   if (t)
-      _eglInitThreadInfo(t);
-   else
+   if (!t)
       t = &dummy_thread;
+
+   _eglInitThreadInfo(t);
    return t;
 }
 
@@ -204,17 +200,6 @@ _eglIsCurrentThreadDummy(void)
 }
 
 
-/**
- * Return the currently bound context of the given API, or NULL.
- */
-_EGLContext *
-_eglGetAPIContext(EGLenum api)
-{
-   _EGLThreadInfo *t = _eglGetCurrentThread();
-   return t->CurrentContexts[_eglConvertApiToIndex(api)];
-}
-
-
 /**
  * Return the currently bound context of the current API, or NULL.
  */
@@ -222,15 +207,15 @@ _EGLContext *
 _eglGetCurrentContext(void)
 {
    _EGLThreadInfo *t = _eglGetCurrentThread();
-   return t->CurrentContexts[t->CurrentAPIIndex];
+   return t->CurrentContext;
 }
 
 
 /**
  * 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();
 
@@ -282,14 +267,6 @@ _eglError(EGLint errCode, const char *msg)
       case EGL_NOT_INITIALIZED:
          s = "EGL_NOT_INITIALIZED";
          break;
-#ifdef EGL_MESA_screen_surface
-      case EGL_BAD_SCREEN_MESA:
-         s = "EGL_BAD_SCREEN_MESA";
-         break;
-      case EGL_BAD_MODE_MESA:
-         s = "EGL_BAD_MODE_MESA";
-         break;
-#endif
       default:
          s = "other EGL error";
       }
@@ -298,3 +275,55 @@ _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, NULL, type, msg);
+   } else
+      _eglInternalError(errCode, msg);
+
+   return EGL_FALSE;
+}
+
+void
+_eglDebugReport(EGLenum error, const char *funcName,
+      EGLint type, const char *message, ...)
+{
+   _EGLThreadInfo *thr = _eglGetCurrentThread();
+   EGLDEBUGPROCKHR callback = NULL;
+   va_list args;
+
+   if (funcName == NULL)
+      funcName = thr->CurrentFuncName;
+
+   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_start(args, message);
+         if (vasprintf(&buf, message, args) < 0)
+            buf = NULL;
+
+         va_end(args);
+      }
+      callback(error, funcName, type, thr->Label, thr->CurrentObjectLabel, buf);
+      free(buf);
+   }
+
+   if (type == EGL_DEBUG_MSG_CRITICAL_KHR || type == EGL_DEBUG_MSG_ERROR_KHR)
+      _eglInternalError(error, funcName);
+}