On 09/13/2016 11:57 AM, Adam Jackson wrote:
From: Kyle Brenneman <kbrenne...@nvidia.com>

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
- Set dummy thread's CurrentAPI to EGL_NONE not zero
- Pass draw surface (if any) to _EGL_FUNC_START in eglSwapInterval
---
  src/egl/main/eglapi.c     | 155 ++++++++++++++++++++++++++++++++++++++++++----
  src/egl/main/eglcurrent.c |  91 ++++++++++++++++++++++++++-
  src/egl/main/eglcurrent.h |  22 +++++++
  src/egl/main/eglglobals.h |   5 ++
  4 files changed, 259 insertions(+), 14 deletions(-)

diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 0477ad9..216b289 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -250,6 +250,37 @@ _eglUnlockDisplay(_EGLDisplay *dpy)
     mtx_unlock(&dpy->Mutex);
  }
+static EGLBoolean
+_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, 
_EGLResource *object)
+{
+   _EGLThreadInfo *thr = _eglGetCurrentThread();
+   if (!_eglIsCurrentThreadDummy()) {
+      thr->CurrentFuncName = funcName;
+      thr->CurrentObjectLabel = NULL;
+
+      if (objectType == EGL_OBJECT_THREAD_KHR)
+         thr->CurrentObjectLabel = thr->Label;
+      else if (objectType == EGL_OBJECT_DISPLAY_KHR)
+         thr->CurrentObjectLabel = disp ? disp->Label : NULL;
+      else
+         thr->CurrentObjectLabel = object ? object->Label : NULL;
+
+      return EGL_TRUE;
+   }
+
+   _eglDebugReportFull(EGL_BAD_ALLOC, funcName, funcName,
+                      EGL_DEBUG_MSG_CRITICAL_KHR, NULL, NULL);
+   return EGL_FALSE;
+}
_eglSetFuncName starts with "thr->CurrentObjectLabel = NULL", so if it didn't set the label to something else later, it would have been cleared.
+
+#define _EGL_FUNC_START(disp, objectType, object, ret) \
+   do { \
+      if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) 
object)) { \
+         if (disp)                                 \
+            _eglUnlockDisplay(disp);               \
+         return ret; \
+      } \
+   } while(0)
static EGLint *
  _eglConvertAttribsToInt(const EGLAttrib *attr_list)
@@ -287,6 +318,8 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
     _EGLDisplay *dpy;
     void *native_display_ptr;
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
+
     STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
     native_display_ptr = (void*) nativeDisplay;
@@ -330,6 +363,7 @@ static EGLDisplay EGLAPIENTRY
  eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
                           const EGLint *attrib_list)
  {
+   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
     return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
  }
@@ -340,6 +374,8 @@ eglGetPlatformDisplay(EGLenum platform, void *native_display,
     EGLDisplay display;
     EGLint *int_attribs;
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
+
     int_attribs = _eglConvertAttribsToInt(attrib_list);
     if (attrib_list && !int_attribs)
        RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
@@ -483,6 +519,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     if (!disp)
        RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
@@ -533,6 +571,8 @@ eglTerminate(EGLDisplay dpy)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     if (!disp)
        RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
@@ -560,6 +600,7 @@ eglQueryString(EGLDisplay dpy, EGLint name)
     }
disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
     _EGL_CHECK_DISPLAY(disp, NULL, drv);
switch (name) {
@@ -585,6 +626,8 @@ eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
@@ -600,6 +643,8 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
                                  config_size, num_config);
@@ -617,6 +662,8 @@ eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
     ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
@@ -635,6 +682,8 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
     _EGLContext *context;
     EGLContext ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
+
     _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
if (!config && !disp->Extensions.KHR_no_config_context)
@@ -658,6 +707,8 @@ eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
+
     _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
     _eglUnlinkContext(context);
     ret = drv->API.DestroyContext(drv, disp, context);
@@ -677,6 +728,8 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface 
read,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
+
     if (!disp)
        RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
     drv = disp->Driver;
@@ -723,6 +776,8 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
+
     _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
     ret = drv->API.QueryContext(drv, disp, context, attribute, value);
@@ -757,6 +812,8 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
                         EGLNativeWindowType window, const EGLint *attrib_list)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+
+   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
     STATIC_ASSERT(sizeof(void*) == sizeof(window));
     return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
                                          attrib_list);
@@ -789,6 +846,7 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig 
config,
native_window = fixupNativeWindow(disp, native_window); + _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
     return _eglCreateWindowSurfaceCommon(disp, config, native_window,
                                          attrib_list);
  }
@@ -801,10 +859,13 @@ eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig 
config,
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
     EGLSurface surface;
-   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+   EGLint *int_attribs;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+
+   int_attribs = _eglConvertAttribsToInt(attrib_list);
     if (attrib_list && !int_attribs)
-      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
native_window = fixupNativeWindow(disp, native_window);
     surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
@@ -853,6 +914,8 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
                         EGLNativePixmapType pixmap, const EGLint *attrib_list)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+
+   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
     STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
     return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
                                           attrib_list);
@@ -865,6 +928,7 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig 
config,
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
     native_pixmap = fixupNativePixmap(disp, native_pixmap);
     return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
                                          attrib_list);
@@ -878,10 +942,13 @@ eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig 
config,
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
     EGLSurface surface;
-   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+   EGLint *int_attribs;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+
+   int_attribs = _eglConvertAttribsToInt(attrib_list);
     if (attrib_list && !int_attribs)
-      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
native_pixmap = fixupNativePixmap(disp, native_pixmap);
     surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
@@ -901,6 +968,7 @@ eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
     _EGLSurface *surf;
     EGLSurface ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
     _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
@@ -918,6 +986,7 @@ eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
     _eglUnlinkSurface(surf);
     ret = drv->API.DestroySurface(drv, disp, surf);
@@ -934,6 +1003,7 @@ eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
     ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
@@ -949,6 +1019,7 @@ eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
     ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
@@ -964,6 +1035,7 @@ eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
     ret = drv->API.BindTexImage(drv, disp, surf, buffer);
@@ -979,6 +1051,7 @@ eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
     ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
@@ -991,17 +1064,17 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
     _EGLContext *ctx = _eglGetCurrentContext();
-   _EGLSurface *surf;
+   _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
         ctx->Resource.Display != disp)
        RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
- surf = ctx->DrawSurface;
     if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
        RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
@@ -1020,6 +1093,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
/* surface must be bound to current context in EGL 1.4 */
@@ -1045,6 +1119,7 @@ eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface 
surface,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
/* surface must be bound to current context in EGL 1.4 */
@@ -1069,6 +1144,7 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, 
EGLNativePixmapType target)
     EGLBoolean ret;
     void *native_pixmap_ptr;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
     STATIC_ASSERT(sizeof(void*) == sizeof(target));
     native_pixmap_ptr = (void*) target;
@@ -1111,6 +1187,7 @@ _eglWaitClientCommon(void)
  EGLBoolean EGLAPIENTRY
  eglWaitClient(void)
  {
+   _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), 
EGL_FALSE);
     return _eglWaitClientCommon();
  }
@@ -1118,6 +1195,7 @@ EGLBoolean EGLAPIENTRY
  eglWaitGL(void)
  {
     /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to 
eglWaitClient. */
+   _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), 
EGL_FALSE);
     return _eglWaitClientCommon();
  }
@@ -1133,6 +1211,8 @@ eglWaitNative(EGLint engine)
     if (!ctx)
        RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
+
     disp = ctx->Resource.Display;
     mtx_lock(&disp->Mutex);
@@ -1182,6 +1262,8 @@ eglGetCurrentSurface(EGLint readdraw)
     _EGLSurface *surf;
     EGLSurface ret;
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
+
     if (!ctx)
        RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
@@ -1233,8 +1315,11 @@ eglGetError(void)
  EGLBoolean EGLAPIENTRY
  eglBindAPI(EGLenum api)
  {
-   _EGLThreadInfo *t = _eglGetCurrentThread();
+   _EGLThreadInfo *t;
+ _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
+
+   t = _eglGetCurrentThread();
     if (_eglIsCurrentThreadDummy())
        RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
@@ -1274,6 +1359,8 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
     _EGLSurface *surf;
     EGLSurface ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
+
     _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
@@ -1290,8 +1377,10 @@ eglReleaseThread(void)
     /* unbind current contexts */
     if (!_eglIsCurrentThreadDummy()) {
        _EGLThreadInfo *t = _eglGetCurrentThread();
-
        _EGLContext *ctx = t->CurrentContext;
+
+      _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
+
        if (ctx) {
           _EGLDisplay *disp = ctx->Resource.Display;
           _EGLDriver *drv;
@@ -1341,6 +1430,7 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum 
target,
                    EGLClientBuffer buffer, const EGLint *attr_list)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
     return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
  }
@@ -1351,10 +1441,13 @@ eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
     EGLImage image;
-   EGLint *int_attribs = _eglConvertAttribsToInt(attr_list);
+   EGLint *int_attribs;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
+
+   int_attribs = _eglConvertAttribsToInt(attr_list);
     if (attr_list && !int_attribs)
-      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE);
+      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
     free(int_attribs);
@@ -1370,6 +1463,8 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     if (!disp->Extensions.KHR_image_base)
        RETURN_EGL_EVAL(disp, EGL_FALSE);
@@ -1431,6 +1526,7 @@ static EGLSync EGLAPIENTRY
  eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
     return _eglCreateSync(disp, type, attrib_list, NULL, EGL_FALSE,
                           EGL_BAD_ATTRIBUTE);
  }
@@ -1440,6 +1536,7 @@ static EGLSync EGLAPIENTRY
  eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
     return _eglCreateSync(disp, type, NULL, attrib_list, EGL_TRUE,
                           EGL_BAD_ATTRIBUTE);
  }
@@ -1449,6 +1546,7 @@ EGLSync EGLAPIENTRY
  eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
     return _eglCreateSync(disp, type, NULL, attrib_list, EGL_TRUE,
                           EGL_BAD_PARAMETER);
  }
@@ -1462,6 +1560,8 @@ eglDestroySync(EGLDisplay dpy, EGLSync sync)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
     _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
     assert(disp->Extensions.KHR_reusable_sync ||
            disp->Extensions.KHR_fence_sync);
@@ -1481,6 +1581,8 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint 
flags, EGLTime timeout)
     _EGLDriver *drv;
     EGLint ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
     _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
     assert(disp->Extensions.KHR_reusable_sync ||
            disp->Extensions.KHR_fence_sync);
@@ -1537,6 +1639,7 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
     _EGLSync *s = _eglLookupSync(sync, disp);
+   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
     return _eglWaitSyncCommon(disp, s, flags);
  }
@@ -1550,6 +1653,7 @@ eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
      */
     _EGLDisplay *disp = _eglLockDisplay(dpy);
     _EGLSync *s = _eglLookupSync(sync, disp);
+   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
     return _eglWaitSyncCommon(disp, s, flags);
  }
@@ -1562,6 +1666,8 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
     _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
     assert(disp->Extensions.KHR_reusable_sync);
     ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
@@ -1589,6 +1695,7 @@ eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint 
attribute, EGLAttrib *valu
  {
     _EGLDisplay *disp = _eglLockDisplay(dpy);
     _EGLSync *s = _eglLookupSync(sync, disp);
+   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
     return _eglGetSyncAttribCommon(disp, s, attribute, value);
  }
@@ -1601,8 +1708,10 @@ eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *valu
     EGLAttrib attrib;
     EGLBoolean result;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
+
     if (!value)
-      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
+      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
attrib = *value;
     result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
@@ -1629,6 +1738,8 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface 
surface,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
if (!disp->Extensions.NOK_swap_region)
@@ -1653,6 +1764,8 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint 
*attr_list)
     _EGLImage *img;
     EGLImage ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
     if (!disp->Extensions.MESA_drm_image)
        RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
@@ -1672,6 +1785,8 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     assert(disp->Extensions.MESA_drm_image);
@@ -1693,6 +1808,8 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     assert(disp->Extensions.WL_bind_wayland_display);
@@ -1711,6 +1828,8 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     assert(disp->Extensions.WL_bind_wayland_display);
@@ -1730,6 +1849,8 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     assert(disp->Extensions.WL_bind_wayland_display);
@@ -1750,6 +1871,8 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
     _EGLDriver *drv;
     struct wl_buffer *ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, NULL, drv);
     assert(disp->Extensions.WL_create_wayland_buffer_from_image);
@@ -1772,6 +1895,8 @@ eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
if (!disp->Extensions.NV_post_sub_buffer)
@@ -1792,6 +1917,8 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface 
surface,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+
     _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
     if (!disp->Extensions.CHROMIUM_sync_control)
        RETURN_EGL_EVAL(disp, EGL_FALSE);
@@ -1814,6 +1941,8 @@ eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage 
image,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     assert(disp->Extensions.MESA_image_dma_buf_export);
@@ -1835,6 +1964,8 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
     _EGLDriver *drv;
     EGLBoolean ret;
+ _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
+
     _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
     assert(disp->Extensions.MESA_image_dma_buf_export);
@@ -1933,6 +2064,8 @@ eglGetProcAddress(const char *procname)
     if (!procname)
        RETURN_EGL_SUCCESS(NULL, NULL);
+ _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
+
     ret = NULL;
     if (strncmp(procname, "egl", 3) == 0) {
        for (i = 0; egl_functions[i].name; i++) {
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index f093bec..bb3738a 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_NONE, NULL, NULL, NULL }
The API here should be EGL_OPENGL_ES_API, not EGL_NONE. Otherwise, the current API would effectively change when the _EGLThreadInfo struct is allocated. Or I guess more generally, _EGL_THREAD_INFO_INITIALIZER should produce the same data as _eglInitThreadInfo.
/* 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);
+}
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index b2638fd..9ec07ba 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -99,6 +99,28 @@ _eglGetCurrentContext(void);
  extern EGLBoolean
  _eglError(EGLint errCode, const char *msg);
+extern EGLLabelKHR
+_eglGetThreadLabel(void);
+
+extern void
+_eglDebugReportFull(EGLenum error, const char *command, const char *funcName,
+      EGLint type, EGLLabelKHR objectLabel, const char *message, ...);
+
+extern void
+_eglDebugReport(EGLenum error, const char *funcName,
+      EGLint type, const char *message, ...);
+
+#define _eglReportCritical(error, funcName, ...) \
+    _eglDebugReport(error, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, __VA_ARGS__)
+
+#define _eglReportError(error, funcName, ...) \
+    _eglDebugReport(error, funcName, EGL_DEBUG_MSG_ERROR_KHR, __VA_ARGS__)
+
+#define _eglReportWarn(funcName, ...) \
+    _eglDebugReport(EGL_SUCCESS, funcName, EGL_DEBUG_MSG_WARN_KHR, __VA_ARGS__)
+
+#define _eglReportInfo(funcName, ...) \
+    _eglDebugReport(EGL_SUCCESS, funcName, EGL_DEBUG_MSG_INFO_KHR, __VA_ARGS__)
#ifdef __cplusplus
  }
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index dfa3577..ec4f3d0 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -70,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