[Mesa-dev] [PATCH 04/10] egl: add EGL_ANDROID_native_fence_sync
Rafael Antognolli
rafael.antognolli at intel.com
Fri Nov 18 17:15:31 UTC 2016
The first 4 patches of this series at least (including this one) work
well on i915 when combined with the pending i915 patches for mesa,
libdrm and kernel.
Tested-by: Rafael Antognolli <rafael.antognolli at intel.com>
On Fri, Nov 18, 2016 at 08:39:33AM -0500, Rob Clark wrote:
> From: Rob Clark <robclark at freedesktop.org>
>
> With fixes from Chad squashed in, plus fixes for issues that Rafael
> found while writing piglit tests.
>
> Cc: Chad Versace <chadversary at chromium.org>
> Cc: Rafael Antognolli <rafael.antognolli at intel.com>
> Signed-off-by: Rob Clark <robclark at freedesktop.org>
> ---
> src/egl/drivers/dri2/egl_dri2.c | 58 ++++++++++++++++++++++++++++++++++++++++-
> src/egl/main/eglapi.c | 38 ++++++++++++++++++++++++---
> src/egl/main/eglapi.h | 2 ++
> src/egl/main/egldisplay.h | 1 +
> src/egl/main/eglfallbacks.c | 1 +
> src/egl/main/eglsync.c | 22 ++++++++++++++--
> src/egl/main/eglsync.h | 1 +
> 7 files changed, 117 insertions(+), 6 deletions(-)
>
> diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
> index f18e9fb..52fbdff 100644
> --- a/src/egl/drivers/dri2/egl_dri2.c
> +++ b/src/egl/drivers/dri2/egl_dri2.c
> @@ -658,6 +658,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;
> @@ -2511,8 +2517,17 @@ dri2_egl_unref_sync(struct dri2_egl_display *dri2_dpy,
> struct dri2_egl_sync *dri2_sync)
> {
> if (p_atomic_dec_zero(&dri2_sync->refcount)) {
> - if (dri2_sync->base.Type == EGL_SYNC_REUSABLE_KHR)
> + switch (dri2_sync->base.Type) {
> + case EGL_SYNC_REUSABLE_KHR:
> cnd_destroy(&dri2_sync->cond);
> + break;
> + case EGL_SYNC_NATIVE_FENCE_ANDROID:
> + if (dri2_sync->base.SyncFd != EGL_NO_NATIVE_FENCE_FD_ANDROID)
> + close(dri2_sync->base.SyncFd);
> + break;
> + default:
> + break;
> + }
>
> if (dri2_sync->fence)
> dri2_dpy->fence->destroy_fence(dri2_dpy->dri_screen, dri2_sync->fence);
> @@ -2603,6 +2618,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);
> @@ -2632,12 +2660,38 @@ dri2_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
> ret = EGL_FALSE;
> }
> }
> +
> 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)
> {
> @@ -2667,6 +2721,7 @@ dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
>
> switch (sync->Type) {
> case EGL_SYNC_FENCE_KHR:
> + case EGL_SYNC_NATIVE_FENCE_ANDROID:
> case EGL_SYNC_CL_EVENT_KHR:
> if (dri2_dpy->fence->client_wait_sync(dri2_ctx ? dri2_ctx->dri_context : NULL,
> dri2_sync->fence, wait_flags,
> @@ -2922,6 +2977,7 @@ _eglBuiltInDriverDRI2(const char *args)
> dri2_drv->base.API.DestroySyncKHR = dri2_destroy_sync;
> dri2_drv->base.API.GLInteropQueryDeviceInfo = dri2_interop_query_device_info;
> dri2_drv->base.API.GLInteropExportObject = dri2_interop_export_object;
> + dri2_drv->base.API.DupNativeFenceFDANDROID = dri2_dup_native_fence_fd;
>
> dri2_drv->base.Name = "DRI2";
> dri2_drv->base.Unload = dri2_unload;
> diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
> index 4a44315..a13130f 100644
> --- a/src/egl/main/eglapi.c
> +++ b/src/egl/main/eglapi.c
> @@ -474,6 +474,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);
> @@ -1630,6 +1631,10 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *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);
> }
> @@ -1702,7 +1707,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);
> @@ -1723,7 +1729,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);
> @@ -1822,7 +1829,8 @@ _eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAtt
>
> _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);
> @@ -1865,6 +1873,29 @@ 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;
> +
> + _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
> +
> + /* 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 && (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,
> @@ -2340,6 +2371,7 @@ eglGetProcAddress(const char *procname)
> { "eglLabelObjectKHR", (_EGLProc) eglLabelObjectKHR },
> { "eglDebugMessageControlKHR", (_EGLProc) eglDebugMessageControlKHR },
> { "eglQueryDebugKHR", (_EGLProc) eglQueryDebugKHR },
> + { "eglDupNativeFenceFDANDROID", (_EGLProc) eglDupNativeFenceFDANDROID },
> { NULL, NULL }
> };
> EGLint i;
> diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
> index b9bcc8e..2dc89fc 100644
> --- a/src/egl/main/eglapi.h
> +++ b/src/egl/main/eglapi.h
> @@ -146,6 +146,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 62d9a11..4e0d717 100644
> --- a/src/egl/main/egldisplay.h
> +++ b/src/egl/main/egldisplay.h
> @@ -94,6 +94,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 7b2c882..cb931b8 100644
> --- a/src/egl/main/eglsync.c
> +++ b/src/egl/main/eglsync.c
> @@ -59,6 +59,14 @@ _eglParseSyncAttribList(_EGLSync *sync, const EGLAttrib *attrib_list)
> err = EGL_BAD_ATTRIBUTE;
> }
> break;
> + case EGL_SYNC_NATIVE_FENCE_FD_ANDROID:
> + if (sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID) {
> + /* we take ownership of the native fd, so no dup(): */
> + sync->SyncFd = val;
> + } else {
> + err = EGL_BAD_ATTRIBUTE;
> + }
> + break;
> default:
> err = EGL_BAD_ATTRIBUTE;
> break;
> @@ -83,6 +91,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;
>
> err = _eglParseSyncAttribList(sync, attrib_list);
>
> @@ -90,6 +99,12 @@ _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:
> + 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;
> }
> @@ -117,17 +132,20 @@ _eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
> if (sync->SyncStatus != EGL_SIGNALED_KHR &&
> (sync->Type == EGL_SYNC_FENCE_KHR ||
> sync->Type == EGL_SYNC_CL_EVENT_KHR ||
> - sync->Type == EGL_SYNC_REUSABLE_KHR))
> + sync->Type == EGL_SYNC_REUSABLE_KHR ||
> + sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID))
> drv->API.ClientWaitSyncKHR(drv, dpy, sync, 0, 0);
>
> *value = sync->SyncStatus;
> 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 83b6f72..5ac76f3 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.7.4
>
More information about the mesa-dev
mailing list