From: Rob Clark <robcl...@freedesktop.org> [chadv]: Fix bugs in attribute parsing.
Signed-off-by: Rob Clark <robcl...@freedesktop.org> --- src/egl/drivers/dri2/egl_dri2.c | 49 +++++++++++++++++++++++++++++++++++++++++ src/egl/main/eglapi.c | 36 +++++++++++++++++++++++++++--- src/egl/main/eglapi.h | 2 ++ src/egl/main/egldisplay.h | 1 + src/egl/main/eglfallbacks.c | 1 + src/egl/main/eglsync.c | 20 ++++++++++++++++- src/egl/main/eglsync.h | 1 + 7 files changed, 106 insertions(+), 4 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index bfde640..a9d351e 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -624,6 +624,12 @@ dri2_setup_screen(_EGLDisplay *disp) disp->Extensions.KHR_wait_sync = EGL_TRUE; if (dri2_dpy->fence->get_fence_from_cl_event) disp->Extensions.KHR_cl_event2 = EGL_TRUE; + if (dri2_dpy->fence->base.version >= 2) { + unsigned capabilities = + dri2_dpy->fence->get_capabilities(dri2_dpy->dri_screen); + disp->Extensions.ANDROID_native_fence_sync = + (capabilities & __DRI_FENCE_CAP_NATIVE_FD) != 0; + } } disp->Extensions.KHR_reusable_sync = EGL_TRUE; @@ -2495,6 +2501,19 @@ dri2_create_sync(_EGLDriver *drv, _EGLDisplay *dpy, /* initial status of reusable sync must be "unsignaled" */ dri2_sync->base.SyncStatus = EGL_UNSIGNALED_KHR; break; + + case EGL_SYNC_NATIVE_FENCE_ANDROID: + if (dri2_dpy->fence->create_fence_fd) { + dri2_sync->fence = dri2_dpy->fence->create_fence_fd( + dri2_ctx->dri_context, + dri2_sync->base.SyncFd); + } + if (!dri2_sync->fence) { + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); + free(dri2_sync); + return NULL; + } + break; } p_atomic_set(&dri2_sync->refcount, 1); @@ -2524,11 +2543,40 @@ dri2_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync) ret = EGL_FALSE; } } + + if (sync->SyncFd != EGL_NO_NATIVE_FENCE_FD_ANDROID) + close(sync->SyncFd); + dri2_egl_unref_sync(dri2_dpy, dri2_sync); return ret; } +static EGLint +dri2_dup_native_fence_fd(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); + struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); + + assert(sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID); + + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { + /* try to retrieve the actual native fence fd.. if rendering is + * not flushed this will just return -1, aka NO_NATIVE_FENCE_FD: + */ + sync->SyncFd = dri2_dpy->fence->get_fence_fd(dri2_dpy->dri_screen, + dri2_sync->fence); + } + + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { + /* if native fence fd still not created, return an error: */ + _eglError(EGL_BAD_PARAMETER, "eglDupNativeFenceFDANDROID"); + return EGL_NO_NATIVE_FENCE_FD_ANDROID; + } + + return dup(sync->SyncFd); +} + static EGLint dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTime timeout) @@ -2826,6 +2874,7 @@ _eglBuiltInDriverDRI2(const char *args) dri2_drv->base.API.SignalSyncKHR = dri2_signal_sync; dri2_drv->base.API.WaitSyncKHR = dri2_server_wait_sync; dri2_drv->base.API.DestroySyncKHR = dri2_destroy_sync; + dri2_drv->base.API.DupNativeFenceFDANDROID = dri2_dup_native_fence_fd; dri2_drv->base.API.GLInteropQueryDeviceInfo = dri2_interop_query_device_info; dri2_drv->base.API.GLInteropExportObject = dri2_interop_export_object; diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 4f5b0b2..cd8c5f8 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -425,6 +425,7 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) /* Please keep these sorted alphabetically. */ _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target); _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer); + _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync); _EGL_CHECK_EXTENSION(ANDROID_recordable); _EGL_CHECK_EXTENSION(CHROMIUM_sync_control); @@ -1439,6 +1440,10 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, if (!disp->Extensions.KHR_cl_event2) RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); break; + case EGL_SYNC_NATIVE_FENCE_ANDROID: + if (!disp->Extensions.ANDROID_native_fence_sync) + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); + break; default: RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); } @@ -1484,7 +1489,8 @@ eglDestroySync(EGLDisplay dpy, EGLSync sync) _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); assert(disp->Extensions.KHR_reusable_sync || - disp->Extensions.KHR_fence_sync); + disp->Extensions.KHR_fence_sync || + disp->Extensions.ANDROID_native_fence_sync); _eglUnlinkSync(s); ret = drv->API.DestroySyncKHR(drv, disp, s); @@ -1503,7 +1509,8 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); assert(disp->Extensions.KHR_reusable_sync || - disp->Extensions.KHR_fence_sync); + disp->Extensions.KHR_fence_sync || + disp->Extensions.ANDROID_native_fence_sync); if (s->SyncStatus == EGL_SIGNALED_KHR) RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR); @@ -1592,7 +1599,8 @@ eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *valu _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); assert(disp->Extensions.KHR_reusable_sync || - disp->Extensions.KHR_fence_sync); + disp->Extensions.KHR_fence_sync || + disp->Extensions.ANDROID_native_fence_sync); ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value); RETURN_EGL_EVAL(disp, ret); @@ -1622,6 +1630,27 @@ eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *valu return result; } +static EGLint EGLAPIENTRY +eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLBoolean ret; + + /* the spec doesn't seem to specify what happens if the fence + * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems + * sensible: + */ + if (s->Type != EGL_SYNC_NATIVE_FENCE_ANDROID) + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID); + + _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID, drv); + assert(disp->Extensions.ANDROID_native_fence_sync); + ret = drv->API.DupNativeFenceFDANDROID(drv, disp, s); + + RETURN_EGL_EVAL(disp, ret); +} static EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, @@ -1929,6 +1958,7 @@ eglGetProcAddress(const char *procname) { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM }, { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA }, { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA }, + { "eglDupNativeFenceFDANDROID", (_EGLProc) eglDupNativeFenceFDANDROID }, { NULL, NULL } }; EGLint i; diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index 5d9c1b8..0c8e7b0 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -147,6 +147,8 @@ struct _egl_api EGLBoolean (*GetSyncAttrib)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLAttrib *value); + EGLint (*DupNativeFenceFDANDROID)(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSync *sync); EGLBoolean (*SwapBuffersRegionNOK)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 6bfc858..66251df 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -92,6 +92,7 @@ struct _egl_extensions /* Please keep these sorted alphabetically. */ EGLBoolean ANDROID_framebuffer_target; EGLBoolean ANDROID_image_native_buffer; + EGLBoolean ANDROID_native_fence_sync; EGLBoolean ANDROID_recordable; EGLBoolean CHROMIUM_sync_control; diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c index d0fce8c..017d337 100644 --- a/src/egl/main/eglfallbacks.c +++ b/src/egl/main/eglfallbacks.c @@ -92,6 +92,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv) drv->API.WaitSyncKHR = NULL; drv->API.SignalSyncKHR = NULL; drv->API.GetSyncAttrib = _eglGetSyncAttrib; + drv->API.DupNativeFenceFDANDROID = NULL; drv->API.CreateDRMImageMESA = NULL; drv->API.ExportDRMImageMESA = NULL; diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c index becb57d..375f223 100644 --- a/src/egl/main/eglsync.c +++ b/src/egl/main/eglsync.c @@ -60,6 +60,12 @@ _eglParseSyncAttribList64(_EGLSync *sync, const EGLAttrib *attrib_list) return badSyncAttrib(attr); sync->CLEvent = val; break; + case EGL_SYNC_NATIVE_FENCE_FD_ANDROID: + if (sync->Type != EGL_SYNC_NATIVE_FENCE_ANDROID) + return badSyncAttrib(attr); + /* we take ownership of the native fd, so no dup(): */ + sync->SyncFd = val; + break; default: return badSyncAttrib(attr); } @@ -92,6 +98,8 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, if (!(type == EGL_SYNC_REUSABLE_KHR && dpy->Extensions.KHR_reusable_sync) && !(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync) && + !(type == EGL_SYNC_NATIVE_FENCE_ANDROID && + dpy->Extensions.ANDROID_native_fence_sync) && !(type == EGL_SYNC_CL_EVENT_KHR && dpy->Extensions.KHR_cl_event2 && attrib_list64)) return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); @@ -99,6 +107,7 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, _eglInitResource(&sync->Resource, sizeof(*sync), dpy); sync->Type = type; sync->SyncStatus = EGL_UNSIGNALED_KHR; + sync->SyncFd = EGL_NO_NATIVE_FENCE_FD_ANDROID; if (attrib_list64) err = _eglParseSyncAttribList64(sync, attrib_list64); @@ -109,6 +118,13 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, case EGL_SYNC_CL_EVENT_KHR: sync->SyncCondition = EGL_SYNC_CL_EVENT_COMPLETE_KHR; break; + case EGL_SYNC_NATIVE_FENCE_ANDROID: + sync->SyncCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID; + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) + sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; + else + sync->SyncCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID; + break; default: sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; } @@ -143,10 +159,12 @@ _eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, break; case EGL_SYNC_CONDITION_KHR: if (sync->Type != EGL_SYNC_FENCE_KHR && - sync->Type != EGL_SYNC_CL_EVENT_KHR) + sync->Type != EGL_SYNC_CL_EVENT_KHR && + sync->Type != EGL_SYNC_NATIVE_FENCE_ANDROID) return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR"); *value = sync->SyncCondition; break; + default: return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR"); break; diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h index 9b2aac8..681503f 100644 --- a/src/egl/main/eglsync.h +++ b/src/egl/main/eglsync.h @@ -48,6 +48,7 @@ struct _egl_sync EGLenum SyncStatus; EGLenum SyncCondition; EGLAttrib CLEvent; + EGLint SyncFd; }; -- 2.9.0.rc2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev