st/egl: Add support for EGL_KHR_reusable_sync.
authorChia-I Wu <olv@lunarg.com>
Sat, 14 Aug 2010 15:56:46 +0000 (23:56 +0800)
committerChia-I Wu <olv@lunarg.com>
Mon, 16 Aug 2010 16:06:19 +0000 (00:06 +0800)
The extension is implemented by pipe_condvar.

src/gallium/state_trackers/egl/common/egl_g3d.c
src/gallium/state_trackers/egl/common/egl_g3d.h
src/gallium/state_trackers/egl/common/egl_g3d_api.c
src/gallium/state_trackers/egl/common/egl_g3d_sync.c [new file with mode: 0644]
src/gallium/state_trackers/egl/common/egl_g3d_sync.h [new file with mode: 0644]

index 56d575ffe08c4f7884612b8d9bea88061e5eb8f5..10e2170729bfbd67b153b4e44e49117c317d438b 100644 (file)
@@ -530,6 +530,8 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
    if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
       dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
 
+   dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
+
    if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
       goto fail;
index f33dc91cf9076c756fce5ac949e0be2a28309f5e..dabcf841e2a364971b27c76d6d41cb033647ec7e 100644 (file)
 #include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "pipe/p_format.h"
+#include "os/os_thread.h"
 #include "egldriver.h"
 #include "egldisplay.h"
 #include "eglcontext.h"
 #include "eglsurface.h"
 #include "eglconfig.h"
 #include "eglimage.h"
+#include "eglsync.h"
 #include "eglscreen.h"
 #include "eglmode.h"
 
@@ -99,6 +101,21 @@ struct egl_g3d_image {
 _EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d)
 _EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj)
 
+#ifdef EGL_KHR_reusable_sync
+
+struct egl_g3d_sync {
+   _EGLSync base;
+
+   int refs;
+
+   /* the mutex protects only the condvar, not the struct */
+   pipe_mutex mutex;
+   pipe_condvar condvar;
+};
+_EGL_DRIVER_TYPECAST(egl_g3d_sync, _EGLSync, obj)
+
+#endif /* EGL_KHR_reusable_sync */
+
 #ifdef EGL_MESA_screen_surface
 
 struct egl_g3d_screen {
index edac72a82232da8c7d5a9ef9c4865569486fbda0..1120945edc73fb5afb5a8ba161f6b5d77a243698 100644 (file)
@@ -34,6 +34,7 @@
 #include "egl_g3d.h"
 #include "egl_g3d_api.h"
 #include "egl_g3d_image.h"
+#include "egl_g3d_sync.h"
 #include "egl_g3d_st.h"
 #include "egl_g3d_loader.h"
 #include "native.h"
@@ -806,6 +807,13 @@ egl_g3d_init_driver_api(_EGLDriver *drv)
    drv->API.CreateImageKHR = egl_g3d_create_image;
    drv->API.DestroyImageKHR = egl_g3d_destroy_image;
 
+#ifdef EGL_KHR_reusable_sync
+   drv->API.CreateSyncKHR = egl_g3d_create_sync;
+   drv->API.DestroySyncKHR = egl_g3d_destroy_sync;
+   drv->API.ClientWaitSyncKHR = egl_g3d_client_wait_sync;
+   drv->API.SignalSyncKHR = egl_g3d_signal_sync;
+#endif
+
 #ifdef EGL_MESA_screen_surface
    drv->API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
    drv->API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
new file mode 100644 (file)
index 0000000..3351973
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_atomic.h"
+#include "os/os_thread.h"
+#include "eglsync.h"
+#include "eglcurrent.h"
+
+#include "egl_g3d.h"
+#include "egl_g3d_sync.h"
+
+#ifdef EGL_KHR_reusable_sync
+
+/**
+ * Wait for the conditional variable.
+ */
+static EGLint
+egl_g3d_wait_sync_condvar(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
+{
+   _EGLDisplay *dpy = gsync->base.Resource.Display;
+
+   pipe_mutex_lock(gsync->mutex);
+
+   /* unlock display lock just before waiting */
+   _eglUnlockMutex(&dpy->Mutex);
+
+   /* No timed wait.  Always treat timeout as EGL_FOREVER_KHR */
+   pipe_condvar_wait(gsync->condvar, gsync->mutex);
+
+   _eglLockMutex(&dpy->Mutex);
+
+   pipe_mutex_unlock(gsync->mutex);
+
+   return EGL_CONDITION_SATISFIED_KHR;
+}
+
+/**
+ * Signal the conditional variable.
+ */
+static void
+egl_g3d_signal_sync_condvar(struct egl_g3d_sync *gsync)
+{
+   pipe_mutex_lock(gsync->mutex);
+   pipe_condvar_broadcast(gsync->condvar);
+   pipe_mutex_unlock(gsync->mutex);
+}
+
+static INLINE void
+egl_g3d_ref_sync(struct egl_g3d_sync *gsync)
+{
+   p_atomic_inc(&gsync->refs);
+}
+
+static INLINE void
+egl_g3d_unref_sync(struct egl_g3d_sync *gsync)
+{
+   if (p_atomic_dec_zero(&gsync->refs)) {
+      pipe_condvar_destroy(gsync->condvar);
+      pipe_mutex_destroy(gsync->mutex);
+
+      FREE(gsync);
+   }
+}
+
+_EGLSync *
+egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
+                    EGLenum type, const EGLint *attrib_list)
+{
+   _EGLContext *ctx = _eglGetCurrentContext();
+   struct egl_g3d_sync *gsync;
+   EGLint err;
+
+   if (!ctx || ctx->Resource.Display != dpy) {
+      _eglError(EGL_BAD_MATCH, "eglCreateSyncKHR");
+      return NULL;
+   }
+
+   gsync = CALLOC_STRUCT(egl_g3d_sync);
+   if (!gsync) {
+      _eglError(EGL_BAD_ALLOC, "eglCreateSyncKHR");
+      return NULL;
+   }
+
+   if (!_eglInitSync(&gsync->base, dpy, type, attrib_list)) {
+      FREE(gsync);
+      return NULL;
+   }
+
+   switch (type) {
+   case EGL_SYNC_REUSABLE_KHR:
+      err = EGL_SUCCESS;
+      break;
+   default:
+      err = EGL_BAD_ATTRIBUTE;
+      break;
+   }
+
+   if (err != EGL_SUCCESS) {
+      _eglError(err, "eglCreateSyncKHR");
+      FREE(gsync);
+      return NULL;
+   }
+
+   pipe_mutex_init(gsync->mutex);
+   pipe_condvar_init(gsync->condvar);
+   p_atomic_set(&gsync->refs, 1);
+
+   return &gsync->base;
+}
+
+EGLBoolean
+egl_g3d_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
+{
+   struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+
+   switch (gsync->base.Type) {
+   case EGL_SYNC_REUSABLE_KHR:
+      /* signal the waiters */
+      if (gsync->base.SyncStatus != EGL_SIGNALED_KHR) {
+         gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+         egl_g3d_signal_sync_condvar(gsync);
+      }
+      break;
+   default:
+      break;
+   }
+
+   egl_g3d_unref_sync(gsync);
+
+   return EGL_TRUE;
+}
+
+EGLint
+egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                         EGLint flags, EGLTimeKHR timeout)
+{
+   struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+   EGLint ret = EGL_CONDITION_SATISFIED_KHR;
+
+   if (gsync->base.SyncStatus != EGL_SIGNALED_KHR) {
+      /* flush if there is a current context */
+      if (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR) {
+         _EGLContext *ctx = _eglGetCurrentContext();
+         struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+         if (gctx)
+            gctx->stctxi->flush(gctx->stctxi, PIPE_FLUSH_RENDER_CACHE , NULL);
+      }
+
+      if (timeout) {
+         /* reference the sync object in case it is destroyed while waiting */
+         egl_g3d_ref_sync(gsync);
+
+         switch (gsync->base.Type) {
+         case EGL_SYNC_REUSABLE_KHR:
+            ret = egl_g3d_wait_sync_condvar(gsync, timeout);
+            break;
+         default:
+            break;
+         }
+
+         egl_g3d_unref_sync(gsync);
+      }
+      else {
+         ret = EGL_TIMEOUT_EXPIRED_KHR;
+      }
+   }
+
+   return ret;
+}
+
+EGLBoolean
+egl_g3d_signal_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                    EGLenum mode)
+{
+   struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+
+   /* only for reusable sync */
+   if (sync->Type != EGL_SYNC_REUSABLE_KHR)
+      return _eglError(EGL_BAD_MATCH, "eglSignalSyncKHR");
+
+   if (gsync->base.SyncStatus != mode) {
+      gsync->base.SyncStatus = mode;
+      if (mode == EGL_SIGNALED_KHR)
+         egl_g3d_signal_sync_condvar(gsync);
+   }
+
+   return EGL_TRUE;
+}
+
+#endif /* EGL_KHR_reusable_sync */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.h b/src/gallium/state_trackers/egl/common/egl_g3d_sync.h
new file mode 100644 (file)
index 0000000..3179ca0
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _EGL_G3D_SYNC_H_
+#define _EGL_G3D_SYNC_H_
+
+#include "egl_g3d.h"
+
+#ifdef EGL_KHR_reusable_sync
+
+_EGLSync *
+egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
+                    EGLenum type, const EGLint *attrib_list);
+
+EGLBoolean
+egl_g3d_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
+
+EGLint
+egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                         EGLint flags, EGLTimeKHR timeout);
+
+EGLBoolean
+egl_g3d_signal_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                    EGLenum mode);
+
+#endif /* EGL_KHR_reusable_sync */
+
+#endif /* _EGL_G3D_SYNC_H_ */