egl/dri2: implement EGL_KHR_wait_sync
authorMarek Olšák <marek.olsak@amd.com>
Fri, 10 Apr 2015 10:04:18 +0000 (12:04 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 30 Apr 2015 12:38:38 +0000 (14:38 +0200)
src/egl/drivers/dri2/egl_dri2.c
src/egl/main/eglapi.c
src/egl/main/eglapi.h
src/egl/main/egldisplay.h
src/egl/main/eglfallbacks.c

index 97175aef4d58c37b0863cf5aaeb724947601504a..e096a7df282666b4e69bf9256b0e9b10ba0694fc 100644 (file)
@@ -530,6 +530,7 @@ dri2_setup_screen(_EGLDisplay *disp)
 
    if (dri2_dpy->fence) {
       disp->Extensions.KHR_fence_sync = EGL_TRUE;
+      disp->Extensions.KHR_wait_sync = EGL_TRUE;
    }
 
    if (dri2_dpy->image) {
@@ -2272,6 +2273,19 @@ dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
    return ret;
 }
 
+static EGLint
+dri2_server_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
+{
+   _EGLContext *ctx = _eglGetCurrentContext();
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+   struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+   struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync);
+
+   dri2_dpy->fence->server_wait_sync(dri2_ctx->dri_context,
+                                     dri2_sync->fence, 0);
+   return EGL_TRUE;
+}
+
 static void
 dri2_unload(_EGLDriver *drv)
 {
@@ -2386,6 +2400,7 @@ _eglBuiltInDriverDRI2(const char *args)
    dri2_drv->base.API.GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium;
    dri2_drv->base.API.CreateSyncKHR = dri2_create_sync;
    dri2_drv->base.API.ClientWaitSyncKHR = dri2_client_wait_sync;
+   dri2_drv->base.API.WaitSyncKHR = dri2_server_wait_sync;
    dri2_drv->base.API.DestroySyncKHR = dri2_destroy_sync;
 
    dri2_drv->base.Name = "DRI2";
index dd972b2edb8cc0f38a755ca4372674bf2634ecf6..65a730abb5e28a43ba99483a560f817143936865 100644 (file)
@@ -406,6 +406,7 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
 
    _EGL_CHECK_EXTENSION(KHR_reusable_sync);
    _EGL_CHECK_EXTENSION(KHR_fence_sync);
+   _EGL_CHECK_EXTENSION(KHR_wait_sync);
 
    _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
    _EGL_CHECK_EXTENSION(KHR_create_context);
@@ -1216,6 +1217,7 @@ eglGetProcAddress(const char *procname)
       { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
       { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
       { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
+      { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR },
       { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
       { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
 #ifdef EGL_NOK_swap_region
@@ -1729,6 +1731,32 @@ eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR t
 }
 
 
+EGLint EGLAPIENTRY
+eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSync *s = _eglLookupSync(sync, disp);
+   _EGLContext *ctx = _eglGetCurrentContext();
+   _EGLDriver *drv;
+   EGLint ret;
+
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   assert(disp->Extensions.KHR_wait_sync);
+
+   /* return an error if the client API doesn't support GL_OES_EGL_sync */
+   if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
+      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
+
+   /* the API doesn't allow any flags yet */
+   if (flags != 0)
+      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+   ret = drv->API.WaitSyncKHR(drv, disp, s);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+
 EGLBoolean EGLAPIENTRY
 eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
 {
index 3245327ae39c41dfffa9d5f1f0a66497e13389d5..7462b35d3ba16332ae6f877b1cb5696587714c15 100644 (file)
@@ -105,6 +105,7 @@ typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLI
 typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list);
 typedef EGLBoolean (*DestroySyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
 typedef EGLint (*ClientWaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLint (*WaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
 typedef EGLBoolean (*SignalSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLenum mode);
 typedef EGLBoolean (*GetSyncAttribKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLint *value);
 
@@ -201,6 +202,7 @@ struct _egl_api
    CreateSyncKHR_t CreateSyncKHR;
    DestroySyncKHR_t DestroySyncKHR;
    ClientWaitSyncKHR_t ClientWaitSyncKHR;
+   WaitSyncKHR_t WaitSyncKHR;
    SignalSyncKHR_t SignalSyncKHR;
    GetSyncAttribKHR_t GetSyncAttribKHR;
 
index 4a1fb4ab15c16bd133aa7f7d2ee61827df80f9b2..70381bcfe51b7ec30f64a00793c4621d7f9d6e93 100644 (file)
@@ -106,6 +106,7 @@ struct _egl_extensions
 
    EGLBoolean KHR_reusable_sync;
    EGLBoolean KHR_fence_sync;
+   EGLBoolean KHR_wait_sync;
 
    EGLBoolean KHR_surfaceless_context;
    EGLBoolean KHR_create_context;
index c108ca7687ce58a99d457eb226ef4e112dc80e04..83d775610c52f369322222618d059d4fb384966d 100644 (file)
@@ -107,6 +107,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
    drv->API.CreateSyncKHR = NULL;
    drv->API.DestroySyncKHR = NULL;
    drv->API.ClientWaitSyncKHR = NULL;
+   drv->API.WaitSyncKHR = NULL;
    drv->API.SignalSyncKHR = NULL;
    drv->API.GetSyncAttribKHR = _eglGetSyncAttribKHR;