[Mesa-dev] [PATCH 4/6] EGL: Call the EGL_KHR_debug callback on errors.

Kyle Brenneman kbrenneman at nvidia.com
Wed Jul 6 16:33:45 UTC 2016


Added a member to _EGLThreadInfo to hold the name of the current EGL
function. Each EGL entrypoint will now set that at the beginning.

_eglError will now call the debug callback function, using the function name
stored in the current _EGLThreadInfo struct.

This should allow the EGL_KHR_debug callback to work correctly without having
to rewrite all of the _eglError calls. It also avoids having to pass the EGL
function names down to driver and platform functions that may be called from
multiple entrypoints.

This is really the bare minimum functionality for EGL_KHR_debug, since the
callback will be missing object labels and messages in most cases. Later
changes can update the _eglError calls to provide more info.
---
 src/egl/main/eglapi.c     | 142 ++++++++++++++++++++++++++++++++++++++++++++--
 src/egl/main/eglcurrent.c |  35 ++++++++++--
 src/egl/main/eglcurrent.h |  26 +++++----
 src/egl/main/eglglobals.c |   5 +-
 4 files changed, 188 insertions(+), 20 deletions(-)

diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 5220f98..6e39bca 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -250,6 +250,27 @@ _eglUnlockDisplay(_EGLDisplay *dpy)
    mtx_unlock(&dpy->Mutex);
 }
 
+#define _EGL_FUNC_START(disp, ret) \
+   do { \
+      if (!_eglSetFuncName(__func__)) { \
+         if (disp)                                 \
+            _eglUnlockDisplay(disp);               \
+         return ret; \
+      } \
+   } while(0)
+
+static EGLBoolean
+_eglSetFuncName(const char *funcName)
+{
+   _EGLThreadInfo *thr = _eglGetCurrentThread();
+   if (!_eglIsCurrentThreadDummy()) {
+      thr->CurrentFuncName = funcName;
+      return EGL_TRUE;
+   } else {
+      _eglDebugReport(EGL_BAD_ALLOC, funcName, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL, NULL);
+      return EGL_FALSE;
+   }
+}
 
 static EGLint *
 _eglConvertAttribsToInt(const EGLAttrib *attr_list)
@@ -287,6 +308,8 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
    _EGLDisplay *dpy;
    void *native_display_ptr;
 
+   _EGL_FUNC_START(NULL, EGL_NO_DISPLAY);
+
    STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
    native_display_ptr = (void*) nativeDisplay;
 
@@ -301,6 +324,8 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
 {
    _EGLDisplay *dpy;
 
+   _EGL_FUNC_START(NULL, EGL_NO_DISPLAY);
+
    switch (platform) {
 #ifdef HAVE_X11_PLATFORM
    case EGL_PLATFORM_X11_EXT:
@@ -331,8 +356,11 @@ eglGetPlatformDisplay(EGLenum platform, void *native_display,
                       const EGLAttrib *attrib_list)
 {
    EGLDisplay display;
-   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+   EGLint *int_attribs;
+
+   _EGL_FUNC_START(NULL, EGL_NO_DISPLAY);
 
+   int_attribs = _eglConvertAttribsToInt(attrib_list);
    if (attrib_list && !int_attribs)
       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
 
@@ -473,6 +501,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    if (!disp)
       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
 
@@ -523,6 +553,8 @@ eglTerminate(EGLDisplay dpy)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    if (!disp)
       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
 
@@ -545,6 +577,8 @@ eglQueryString(EGLDisplay dpy, EGLint name)
    _EGLDisplay *disp;
    _EGLDriver *drv;
 
+   _EGL_FUNC_START(NULL, NULL);
+
    if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
       RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
    }
@@ -575,6 +609,8 @@ eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
 
@@ -590,6 +626,8 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
                                 config_size, num_config);
@@ -607,6 +645,8 @@ eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
    ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
 
@@ -625,6 +665,8 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
    _EGLContext *context;
    EGLContext ret;
 
+   _EGL_FUNC_START(disp, EGL_NO_CONTEXT);
+
    _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
 
    if (!config && !disp->Extensions.MESA_configless_context)
@@ -648,6 +690,8 @@ eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
    _eglUnlinkContext(context);
    ret = drv->API.DestroyContext(drv, disp, context);
@@ -667,6 +711,8 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    if (!disp)
       RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
    drv = disp->Driver;
@@ -713,6 +759,8 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
    ret = drv->API.QueryContext(drv, disp, context, attribute, value);
 
@@ -747,6 +795,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
                        EGLNativeWindowType window, const EGLint *attrib_list)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_NO_SURFACE);
    STATIC_ASSERT(sizeof(void*) == sizeof(window));
    return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
                                         attrib_list);
@@ -759,6 +808,7 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
                                   const EGLint *attrib_list)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_NO_SURFACE);
 
 #ifdef HAVE_X11_PLATFORM
    if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
@@ -784,8 +834,11 @@ eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
                                const EGLAttrib *attrib_list)
 {
    EGLSurface surface;
-   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+   EGLint *int_attribs;
 
+   _EGL_FUNC_START(NULL, EGL_NO_SURFACE);
+
+   int_attribs = _eglConvertAttribsToInt(attrib_list);
    if (attrib_list && !int_attribs)
       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
 
@@ -819,6 +872,7 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
                        EGLNativePixmapType pixmap, const EGLint *attrib_list)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_NO_SURFACE);
    STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
    return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
                                          attrib_list);
@@ -830,6 +884,7 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
                                    const EGLint *attrib_list)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGL_FUNC_START(disp, EGL_NO_SURFACE);
 
 #ifdef HAVE_X11_PLATFORM
       /* The `native_pixmap` parameter for the X11 platform differs between
@@ -855,8 +910,11 @@ eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
                                const EGLAttrib *attrib_list)
 {
    EGLSurface surface;
-   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+   EGLint *int_attribs;
+
+   _EGL_FUNC_START(NULL, EGL_NO_SURFACE);
 
+   int_attribs = _eglConvertAttribsToInt(attrib_list);
    if (attrib_list && !int_attribs)
       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
 
@@ -877,6 +935,7 @@ eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
    _EGLSurface *surf;
    EGLSurface ret;
 
+   _EGL_FUNC_START(disp, EGL_NO_SURFACE);
    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
 
    surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
@@ -894,6 +953,7 @@ eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
    _eglUnlinkSurface(surf);
    ret = drv->API.DestroySurface(drv, disp, surf);
@@ -910,6 +970,7 @@ eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
    ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
 
@@ -925,6 +986,7 @@ eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
    ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
 
@@ -940,6 +1002,7 @@ eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
    ret = drv->API.BindTexImage(drv, disp, surf, buffer);
 
@@ -955,6 +1018,7 @@ eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
    ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
 
@@ -971,6 +1035,7 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
 
    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
@@ -996,6 +1061,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
 
    /* surface must be bound to current context in EGL 1.4 */
@@ -1021,6 +1087,7 @@ eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
 
    /* surface must be bound to current context in EGL 1.4 */
@@ -1045,6 +1112,7 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
    EGLBoolean ret;
    void *native_pixmap_ptr;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
    STATIC_ASSERT(sizeof(void*) == sizeof(target));
    native_pixmap_ptr = (void*) target;
 
@@ -1068,6 +1136,8 @@ eglWaitClient(void)
    if (!ctx)
       RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
 
+   _EGL_FUNC_START(NULL, EGL_FALSE);
+
    disp = ctx->Resource.Display;
    mtx_lock(&disp->Mutex);
 
@@ -1093,6 +1163,8 @@ eglWaitGL(void)
    EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
    EGLBoolean ret;
 
+   _EGL_FUNC_START(NULL, EGL_FALSE);
+
    if (api_index != es_index && _eglIsCurrentThreadDummy())
       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
 
@@ -1114,6 +1186,8 @@ eglWaitNative(EGLint engine)
    if (!ctx)
       RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
 
+   _EGL_FUNC_START(NULL, EGL_FALSE);
+
    disp = ctx->Resource.Display;
    mtx_lock(&disp->Mutex);
 
@@ -1163,6 +1237,8 @@ eglGetCurrentSurface(EGLint readdraw)
    _EGLSurface *surf;
    EGLSurface ret;
 
+   _EGL_FUNC_START(NULL, EGL_NO_SURFACE);
+
    if (!ctx)
       RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
 
@@ -1216,6 +1292,8 @@ eglBindAPI(EGLenum api)
 {
    _EGLThreadInfo *t = _eglGetCurrentThread();
 
+   _EGL_FUNC_START(NULL, EGL_FALSE);
+
    if (_eglIsCurrentThreadDummy())
       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
 
@@ -1255,6 +1333,8 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
    _EGLSurface *surf;
    EGLSurface ret;
 
+   _EGL_FUNC_START(disp, EGL_NO_SURFACE);
+
    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
 
    surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
@@ -1274,6 +1354,8 @@ eglReleaseThread(void)
       EGLint api_index = t->CurrentAPIIndex;
       EGLint i;
 
+      _eglSetFuncName(__func__);
+
       for (i = 0; i < _EGL_API_NUM_APIS; i++) {
          _EGLContext *ctx = t->CurrentContexts[i];
          if (ctx) {
@@ -1308,6 +1390,8 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
    _EGLImage *img;
    EGLImage ret;
 
+   _EGL_FUNC_START(disp, EGL_NO_IMAGE_KHR);
+
    _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
    if (!disp->Extensions.KHR_image_base)
       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
@@ -1332,8 +1416,11 @@ eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
                EGLClientBuffer buffer, const EGLAttrib *attr_list)
 {
    EGLImage image;
-   EGLint *int_attribs = _eglConvertAttribsToInt(attr_list);
+   EGLint *int_attribs;
 
+   _EGL_FUNC_START(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);
 
@@ -1351,6 +1438,8 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    if (!disp->Extensions.KHR_image_base)
       RETURN_EGL_EVAL(disp, EGL_FALSE);
@@ -1412,6 +1501,7 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
 static EGLSync EGLAPIENTRY
 eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
 {
+   _EGL_FUNC_START(NULL, EGL_NO_SYNC_KHR);
    return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE,
                          EGL_BAD_ATTRIBUTE);
 }
@@ -1420,6 +1510,7 @@ eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
 static EGLSync EGLAPIENTRY
 eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
 {
+   _EGL_FUNC_START(NULL, EGL_NO_SYNC_KHR);
    return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
                          EGL_BAD_ATTRIBUTE);
 }
@@ -1428,6 +1519,7 @@ eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
 EGLSync EGLAPIENTRY
 eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
 {
+   _EGL_FUNC_START(NULL, EGL_NO_SYNC_KHR);
    return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
                          EGL_BAD_PARAMETER);
 }
@@ -1441,6 +1533,8 @@ eglDestroySync(EGLDisplay dpy, EGLSync sync)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
    assert(disp->Extensions.KHR_reusable_sync ||
           disp->Extensions.KHR_fence_sync);
@@ -1460,6 +1554,8 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
    _EGLDriver *drv;
    EGLint ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
    assert(disp->Extensions.KHR_reusable_sync ||
           disp->Extensions.KHR_fence_sync);
@@ -1497,6 +1593,8 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
    _EGLDriver *drv;
    EGLint ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
    assert(disp->Extensions.KHR_wait_sync);
 
@@ -1533,6 +1631,8 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
    assert(disp->Extensions.KHR_reusable_sync);
    ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
@@ -1549,6 +1649,8 @@ eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *valu
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
    assert(disp->Extensions.KHR_reusable_sync ||
           disp->Extensions.KHR_fence_sync);
@@ -1564,6 +1666,8 @@ eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *valu
    EGLAttrib attrib;
    EGLBoolean result;
 
+   _EGL_FUNC_START(NULL, EGL_FALSE);
+
    if (!value)
       RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
 
@@ -1592,6 +1696,8 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
 
    if (!disp->Extensions.NOK_swap_region)
@@ -1616,6 +1722,8 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
    _EGLImage *img;
    EGLImage ret;
 
+   _EGL_FUNC_START(disp, 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);
@@ -1635,6 +1743,8 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    assert(disp->Extensions.MESA_drm_image);
 
@@ -1656,6 +1766,8 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    assert(disp->Extensions.WL_bind_wayland_display);
 
@@ -1674,6 +1786,8 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    assert(disp->Extensions.WL_bind_wayland_display);
 
@@ -1693,6 +1807,8 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    assert(disp->Extensions.WL_bind_wayland_display);
 
@@ -1713,6 +1829,8 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
    _EGLDriver *drv;
    struct wl_buffer *ret;
 
+   _EGL_FUNC_START(disp, NULL);
+
    _EGL_CHECK_DISPLAY(disp, NULL, drv);
    assert(disp->Extensions.WL_create_wayland_buffer_from_image);
 
@@ -1735,6 +1853,8 @@ eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
 
    if (!disp->Extensions.NV_post_sub_buffer)
@@ -1755,6 +1875,8 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
    if (!disp->Extensions.CHROMIUM_sync_control)
       RETURN_EGL_EVAL(disp, EGL_FALSE);
@@ -1777,6 +1899,8 @@ eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    assert(disp->Extensions.MESA_image_dma_buf_export);
 
@@ -1798,6 +1922,8 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
    _EGLDriver *drv;
    EGLBoolean ret;
 
+   _EGL_FUNC_START(disp, EGL_FALSE);
+
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    assert(disp->Extensions.MESA_image_dma_buf_export);
 
@@ -1816,6 +1942,8 @@ eglLabelObjectKHR(
       EGLObjectKHR object,
       EGLLabelKHR label)
 {
+   _EGL_FUNC_START(NULL, EGL_BAD_ALLOC);
+
    if (objectType == EGL_OBJECT_THREAD_KHR) {
       _EGLThreadInfo *t = _eglGetCurrentThread();
       if (!_eglIsCurrentThreadDummy()) {
@@ -1873,6 +2001,8 @@ eglLabelObjectKHR(
 static EGLint
 eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list)
 {
+   _EGL_FUNC_START(NULL, EGL_BAD_ALLOC);
+
    mtx_lock(_eglGlobal.Mutex);
 
    if (callback != NULL) {
@@ -1913,6 +2043,8 @@ eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list
 static EGLBoolean
 eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
 {
+   _EGL_FUNC_START(NULL, EGL_BAD_ALLOC);
+
    mtx_lock(_eglGlobal.Mutex);
    if (attribute >= EGL_DEBUG_MSG_CRITICAL_KHR &&
          attribute <= EGL_DEBUG_MSG_INFO_KHR) {
@@ -2023,6 +2155,8 @@ eglGetProcAddress(const char *procname)
    if (!procname)
       RETURN_EGL_SUCCESS(NULL, NULL);
 
+   _EGL_FUNC_START(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 5816967..2000f10 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -230,8 +230,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();
 
@@ -292,6 +292,24 @@ _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, msg, type, NULL, NULL);
+   } else {
+      _eglInternalError(errCode, msg);
+   }
+   return EGL_FALSE;
+}
+
 /**
  * Returns the label set for the current thread.
  */
@@ -303,7 +321,8 @@ _eglGetThreadLabel(void)
 }
 
 void
-_eglDebugReport(EGLenum error, const char *command, EGLint type, EGLLabelKHR objectLabel, const char *message, ...)
+_eglDebugReport(EGLenum error, const char *command, const char *funcName,
+      EGLint type, EGLLabelKHR objectLabel, const char *message, ...)
 {
    EGLDEBUGPROCKHR callback = NULL;
 
@@ -313,6 +332,14 @@ _eglDebugReport(EGLenum error, const char *command, EGLint type, EGLLabelKHR obj
    }
    mtx_unlock(_eglGlobal.Mutex);
 
+   if (command == NULL) {
+      _EGLThreadInfo *thr = _eglGetCurrentThread();
+      command = thr->CurrentFuncName;
+   }
+   if (funcName == NULL) {
+      funcName = command;
+   }
+
    if (callback != NULL) {
       char *buf = NULL;
 
@@ -329,6 +356,6 @@ _eglDebugReport(EGLenum error, const char *command, EGLint type, EGLLabelKHR obj
    }
 
    if (type == EGL_DEBUG_MSG_CRITICAL_KHR || type == EGL_DEBUG_MSG_ERROR_KHR) {
-      _eglError(error, command);
+      _eglInternalError(error, funcName);
    }
 }
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index ed0d2f4..a7b6abf 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -62,6 +62,12 @@ struct _egl_thread_info
    EGLint CurrentAPIIndex;
 
    EGLLabelKHR Label;
+
+   /**
+    * The name of the EGL function that's being called at the moment. This is
+    * used to report the function name to the EGL_KHR_debug callback.
+    */
+   const char *CurrentFuncName;
 };
 
 
@@ -124,20 +130,20 @@ extern EGLLabelKHR
 _eglGetThreadLabel(void);
 
 extern void
-_eglDebugReport(EGLenum error, const char *command, EGLint type,
-      EGLLabelKHR objectLabel, const char *message, ...);
+_eglDebugReport(EGLenum error, const char *command, const char *funcName,
+      EGLint type, EGLLabelKHR objectLabel, const char *message, ...);
 
-#define _eglReportCritical(error, command, objLabel, ...) \
-    _eglDebugReport(error, command, EGL_DEBUG_MSG_ERROR_KHR, objLabel, __VA_ARGS__)
+#define _eglReportCritical(error, funcName, objLabel, ...) \
+    _eglDebugReport(error, NULL, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, objLabel, __VA_ARGS__)
 
-#define _eglReportError(error, command, objLabel, ...) \
-    _eglDebugReport(error, command, EGL_DEBUG_MSG_CRITICAL_KHR, objLabel, __VA_ARGS__)
+#define _eglReportError(error, funcName, objLabel, ...) \
+    _eglDebugReport(error, NULL, funcName, EGL_DEBUG_MSG_ERROR_KHR, objLabel, __VA_ARGS__)
 
-#define _eglReportWarn(command, objLabel, ...) \
-    _eglDebugReport(EGL_SUCCESS, command, EGL_DEBUG_MSG_WARN_KHR, objLabel, __VA_ARGS__)
+#define _eglReportWarn(funcName, objLabel, ...) \
+    _eglDebugReport(EGL_SUCCESS, NULL, funcName, EGL_DEBUG_MSG_WARN_KHR, objLabel, __VA_ARGS__)
 
-#define _eglReportInfo(command, objLabel, ...) \
-    _eglDebugReport(EGL_SUCCESS, command, EGL_DEBUG_MSG_INFO_KHR, objLabel, __VA_ARGS__)
+#define _eglReportInfo(funcName, objLabel, ...) \
+    _eglDebugReport(EGL_SUCCESS, NULL, funcName, EGL_DEBUG_MSG_INFO_KHR, objLabel, __VA_ARGS__)
 
 #ifdef __cplusplus
 }
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index f67bc25..27ca27f 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -50,13 +50,14 @@ struct _egl_global _eglGlobal =
       _eglFiniDisplay
    },
 
-   /* ClientExtensionsString */
+   /* ClientExtensionString */
    "EGL_EXT_client_extensions"
    " EGL_EXT_platform_base"
    " EGL_EXT_platform_wayland"
    " EGL_EXT_platform_x11"
    " EGL_KHR_client_get_all_proc_addresses"
-   " EGL_MESA_platform_gbm",
+   " EGL_MESA_platform_gbm"
+   " EGL_KHR_debug",
 
    NULL, /* debugCallback */
    _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR, /* debugTypesEnabled */
-- 
1.9.1



More information about the mesa-dev mailing list