Mesa (master): st/egl: Add support for EGL_KHR_fence_sync.

Chia-I Wu olv at kemper.freedesktop.org
Mon Aug 16 16:10:07 UTC 2010


Module: Mesa
Branch: master
Commit: f945cb651518025159499999527ff5d4536acaf8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f945cb651518025159499999527ff5d4536acaf8

Author: Chia-I Wu <olv at lunarg.com>
Date:   Sun Aug 15 17:24:14 2010 +0800

st/egl: Add support for EGL_KHR_fence_sync.

The extension is implemented by pipe_fence_handle.

---

 src/gallium/state_trackers/egl/common/egl_g3d.c    |    1 +
 src/gallium/state_trackers/egl/common/egl_g3d.h    |    3 +
 .../state_trackers/egl/common/egl_g3d_sync.c       |   67 ++++++++++++++++++++
 3 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 10e2170..02b9f6a 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -531,6 +531,7 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
       dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
 
    dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
+   dpy->Extensions.KHR_fence_sync = EGL_TRUE;
 
    if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index dabcf84..be450bb 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -111,6 +111,9 @@ struct egl_g3d_sync {
    /* the mutex protects only the condvar, not the struct */
    pipe_mutex mutex;
    pipe_condvar condvar;
+
+   /* for fence sync */
+   struct pipe_fence_handle *fence;
 };
 _EGL_DRIVER_TYPECAST(egl_g3d_sync, _EGLSync, obj)
 
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
index 3351973..ec74e9e 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
@@ -71,6 +71,60 @@ egl_g3d_signal_sync_condvar(struct egl_g3d_sync *gsync)
    pipe_mutex_unlock(gsync->mutex);
 }
 
+/**
+ * Insert a fence command to the command stream of the current context.
+ */
+static EGLint
+egl_g3d_insert_fence_sync(struct egl_g3d_sync *gsync)
+{
+   _EGLContext *ctx = _eglGetCurrentContext();
+   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+   /* already checked in egl_g3d_create_sync */
+   assert(gctx);
+
+   /* insert the fence command */
+   gctx->stctxi->flush(gctx->stctxi, 0x0, &gsync->fence);
+   if (!gsync->fence)
+      gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+
+   return EGL_SUCCESS;
+}
+
+/**
+ * Wait for the fence sync to be signaled.
+ */
+static EGLint
+egl_g3d_wait_fence_sync(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
+{
+   EGLint ret;
+
+   if (gsync->fence) {
+      _EGLDisplay *dpy = gsync->base.Resource.Display;
+      struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+      struct pipe_screen *screen = gdpy->native->screen;
+      struct pipe_fence_handle *fence = gsync->fence;
+
+      gsync->fence = NULL;
+
+      _eglUnlockMutex(&dpy->Mutex);
+      /* no timed finish? */
+      screen->fence_finish(screen, fence, 0x0);
+      ret = EGL_CONDITION_SATISFIED_KHR;
+      _eglLockMutex(&dpy->Mutex);
+
+      gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+
+      screen->fence_reference(screen, &fence, NULL);
+      egl_g3d_signal_sync_condvar(gsync);
+   }
+   else {
+      ret = egl_g3d_wait_sync_condvar(gsync, timeout);
+   }
+
+   return ret;
+}
+
 static INLINE void
 egl_g3d_ref_sync(struct egl_g3d_sync *gsync)
 {
@@ -84,6 +138,14 @@ egl_g3d_unref_sync(struct egl_g3d_sync *gsync)
       pipe_condvar_destroy(gsync->condvar);
       pipe_mutex_destroy(gsync->mutex);
 
+      if (gsync->fence) {
+         struct egl_g3d_display *gdpy =
+            egl_g3d_display(gsync->base.Resource.Display);
+         struct pipe_screen *screen = gdpy->native->screen;
+
+         screen->fence_reference(screen, &gsync->fence, NULL);
+      }
+
       FREE(gsync);
    }
 }
@@ -116,6 +178,9 @@ egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
    case EGL_SYNC_REUSABLE_KHR:
       err = EGL_SUCCESS;
       break;
+   case EGL_SYNC_FENCE_KHR:
+      err = egl_g3d_insert_fence_sync(gsync);
+      break;
    default:
       err = EGL_BAD_ATTRIBUTE;
       break;
@@ -181,6 +246,8 @@ egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
          case EGL_SYNC_REUSABLE_KHR:
             ret = egl_g3d_wait_sync_condvar(gsync, timeout);
             break;
+         case EGL_SYNC_FENCE_KHR:
+            ret = egl_g3d_wait_fence_sync(gsync, timeout);
          default:
             break;
          }




More information about the mesa-commit mailing list