+
+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);
+
+ char *message_buf = NULL;
+ if (message != NULL) {
+ va_start(args, message);
+ if (vasprintf(&message_buf, message, args) < 0)
+ message_buf = NULL;
+ va_end(args);
+ }
+
+ if (callback != NULL) {
+ callback(error, funcName, type, thr->Label, thr->CurrentObjectLabel,
+ message_buf);
+ }
+
+ if (type == EGL_DEBUG_MSG_CRITICAL_KHR || type == EGL_DEBUG_MSG_ERROR_KHR) {
+ char *func_message_buf = NULL;
+ /* Note: _eglError() is often called with msg == thr->currentFuncName */
+ if (message_buf && funcName && strcmp(message_buf, funcName) != 0) {
+ if (asprintf(&func_message_buf, "%s: %s", funcName, message_buf) < 0)
+ func_message_buf = NULL;
+ }
+ _eglInternalError(error, func_message_buf ? func_message_buf : funcName);
+ free(func_message_buf);
+ }
+ free(message_buf);
+}