[Mesa-dev] [PATCH 13/14] egl: Track EGL_KHR_debug state when going through EGL API calls (v2)
Kyle Brenneman
kyle.brenneman at gmail.com
Tue Sep 13 20:14:18 UTC 2016
On 09/13/2016 11:57 AM, Adam Jackson wrote:
> 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
> - 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 */
More information about the mesa-dev
mailing list