[Mesa-dev] [PATCH 13/14] egl: Track EGL_KHR_debug state when going through EGL API calls (v3)

Adam Jackson ajax at redhat.com
Wed Sep 14 13:59:25 UTC 2016


From: Kyle Brenneman <kbrenneman at 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
- 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
---
 src/egl/main/eglapi.c     | 153 +++++++++++++++++++++++++++++++++++++++++++---
 src/egl/main/eglcurrent.c |  91 ++++++++++++++++++++++++++-
 src/egl/main/eglcurrent.h |  22 +++++++
 src/egl/main/eglglobals.h |   5 ++
 4 files changed, 258 insertions(+), 13 deletions(-)

diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 1c62a80..cbc3841 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 && disp)
+         thr->CurrentObjectLabel = disp->Label;
+      else if (object)
+         thr->CurrentObjectLabel = object->Label;
+
+      return EGL_TRUE;
+   }
+
+   _eglDebugReportFull(EGL_BAD_ALLOC, funcName, funcName,
+		       EGL_DEBUG_MSG_CRITICAL_KHR, NULL, NULL);
+   return EGL_FALSE;
+}
+
+#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,8 +1441,11 @@ 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(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
 
@@ -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..eae7bdc 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);
+}
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 */
-- 
2.9.3



More information about the mesa-dev mailing list