Mesa (master): egl: Add support for EGL_KHR_reusable_sync.

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


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

Author: Chia-I Wu <olv at lunarg.com>
Date:   Sat Aug 14 23:09:12 2010 +0800

egl: Add support for EGL_KHR_reusable_sync.

Individual drivers still need to support and enable the extension.

---

 src/egl/main/Makefile      |    6 ++-
 src/egl/main/eglapi.c      |  107 ++++++++++++++++++++++++++++++++++++++
 src/egl/main/eglapi.h      |   18 +++++++
 src/egl/main/egldisplay.h  |    6 ++
 src/egl/main/egldriver.c   |    9 +++
 src/egl/main/eglmisc.c     |    2 +
 src/egl/main/eglsync.c     |  121 ++++++++++++++++++++++++++++++++++++++++++++
 src/egl/main/eglsync.h     |  119 +++++++++++++++++++++++++++++++++++++++++++
 src/egl/main/egltypedefs.h |    2 +
 9 files changed, 388 insertions(+), 2 deletions(-)

diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 41d301f..d92fbf6 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -26,7 +26,8 @@ HEADERS = \
 	eglmutex.h \
 	eglscreen.h \
 	eglstring.h \
-	eglsurface.h
+	eglsurface.h \
+	eglsync.h
 
 SOURCES = \
 	eglapi.c \
@@ -44,7 +45,8 @@ SOURCES = \
 	eglmode.c \
 	eglscreen.c \
 	eglstring.c \
-	eglsurface.c
+	eglsurface.c \
+	eglsync.c
 
 OBJECTS = $(SOURCES:.c=.o)
 
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 4dc8707..53a5f6e 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -68,6 +68,7 @@
 #include "eglscreen.h"
 #include "eglmode.h"
 #include "eglimage.h"
+#include "eglsync.h"
 
 
 /**
@@ -126,6 +127,8 @@
 #define _EGL_CHECK_MODE(disp, m, ret, drv) \
    _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
 
+#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
+   _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
 
 
 static INLINE _EGLDriver *
@@ -185,6 +188,26 @@ _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
 }
 
 
+#ifdef EGL_KHR_reusable_sync
+
+
+static INLINE _EGLDriver *
+_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
+{
+   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+   if (!drv)
+      return NULL;
+   if (!s) {
+      _eglError(EGL_BAD_PARAMETER, msg);
+      return NULL;
+   }
+   return drv;
+}
+
+
+#endif /* EGL_KHR_reusable_sync */
+
+
 #ifdef EGL_MESA_screen_surface
 
 
@@ -1245,6 +1268,90 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
 #endif /* EGL_KHR_image_base */
 
 
+#ifdef EGL_KHR_reusable_sync
+
+
+EGLSyncKHR EGLAPIENTRY
+eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLDriver *drv;
+   _EGLSync *sync;
+   EGLSyncKHR ret;
+
+   _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
+
+   sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
+   ret = (sync) ? _eglLinkSync(sync, disp) : EGL_NO_SYNC_KHR;
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+
+EGLBoolean EGLAPIENTRY
+eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSync *s = _eglLookupSync(sync, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   _eglUnlinkSync(s);
+   ret = drv->API.DestroySyncKHR(drv, disp, s);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+
+EGLint EGLAPIENTRY
+eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSync *s = _eglLookupSync(sync, disp);
+   _EGLDriver *drv;
+   EGLint ret;
+
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+
+EGLBoolean EGLAPIENTRY
+eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSync *s = _eglLookupSync(sync, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+
+EGLBoolean EGLAPIENTRY
+eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSync *s = _eglLookupSync(sync, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+
+#endif /* EGL_KHR_reusable_sync */
+
+
 #ifdef EGL_NOK_swap_region
 
 EGLBoolean EGLAPIENTRY
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index d8c8b49..5045a9a 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -76,6 +76,16 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo
 typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
 #endif /* EGL_KHR_image_base */
 
+
+#ifdef EGL_KHR_reusable_sync
+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 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);
+#endif /* EGL_KHR_reusable_sync */
+
+
 #ifdef EGL_NOK_swap_region
 typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects);
 #endif
@@ -138,6 +148,14 @@ struct _egl_api
    DestroyImageKHR_t DestroyImageKHR;
 #endif /* EGL_KHR_image_base */
 
+#ifdef EGL_KHR_reusable_sync
+   CreateSyncKHR_t CreateSyncKHR;
+   DestroySyncKHR_t DestroySyncKHR;
+   ClientWaitSyncKHR_t ClientWaitSyncKHR;
+   SignalSyncKHR_t SignalSyncKHR;
+   GetSyncAttribKHR_t GetSyncAttribKHR;
+#endif /* EGL_KHR_reusable_sync */
+
 #ifdef EGL_NOK_swap_region
    SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
 #endif
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index a2cee08..a5c1453 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -24,6 +24,7 @@ enum _egl_resource_type {
    _EGL_RESOURCE_CONTEXT,
    _EGL_RESOURCE_SURFACE,
    _EGL_RESOURCE_IMAGE,
+   _EGL_RESOURCE_SYNC,
 
    _EGL_NUM_RESOURCES
 };
@@ -53,6 +54,7 @@ struct _egl_extensions
    EGLBoolean MESA_screen_surface;
    EGLBoolean MESA_copy_context;
    EGLBoolean MESA_drm_display;
+
    EGLBoolean KHR_image_base;
    EGLBoolean KHR_image_pixmap;
    EGLBoolean KHR_vg_parent_image;
@@ -60,9 +62,13 @@ struct _egl_extensions
    EGLBoolean KHR_gl_texture_cubemap_image;
    EGLBoolean KHR_gl_texture_3D_image;
    EGLBoolean KHR_gl_renderbuffer_image;
+
+   EGLBoolean KHR_reusable_sync;
+
    EGLBoolean KHR_surfaceless_gles1;
    EGLBoolean KHR_surfaceless_gles2;
    EGLBoolean KHR_surfaceless_opengl;
+
    EGLBoolean NOK_swap_region;
    EGLBoolean NOK_texture_from_pixmap;
 
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index 8fc9e79..67f1d3d 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -21,6 +21,7 @@
 #include "eglstring.h"
 #include "eglsurface.h"
 #include "eglimage.h"
+#include "eglsync.h"
 #include "eglmutex.h"
 
 #if defined(_EGL_OS_UNIX)
@@ -722,6 +723,14 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
    drv->API.CreateImageKHR = _eglCreateImageKHR;
    drv->API.DestroyImageKHR = _eglDestroyImageKHR;
 #endif /* EGL_KHR_image_base */
+
+#ifdef EGL_KHR_reusable_sync
+   drv->API.CreateSyncKHR = _eglCreateSyncKHR;
+   drv->API.DestroySyncKHR = _eglDestroySyncKHR;
+   drv->API.ClientWaitSyncKHR = _eglClientWaitSyncKHR;
+   drv->API.SignalSyncKHR = _eglSignalSyncKHR;
+   drv->API.GetSyncAttribKHR = _eglGetSyncAttribKHR;
+#endif /* EGL_KHR_reusable_sync */
 }
 
 
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 985d1e0..2ef6ba5 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -97,6 +97,8 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
    _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
 
+   _EGL_CHECK_EXTENSION(KHR_reusable_sync);
+
    _EGL_CHECK_EXTENSION(KHR_surfaceless_gles1);
    _EGL_CHECK_EXTENSION(KHR_surfaceless_gles2);
    _EGL_CHECK_EXTENSION(KHR_surfaceless_opengl);
diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c
new file mode 100644
index 0000000..3f51e89
--- /dev/null
+++ b/src/egl/main/eglsync.c
@@ -0,0 +1,121 @@
+#include <string.h>
+
+#include "eglsync.h"
+#include "eglcurrent.h"
+#include "egllog.h"
+
+
+#ifdef EGL_KHR_reusable_sync
+
+
+/**
+ * Parse the list of sync attributes and return the proper error code.
+ */
+static EGLint
+_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
+{
+   EGLint i, err = EGL_SUCCESS;
+
+   if (!attrib_list)
+      return EGL_SUCCESS;
+
+   for (i = 0; attrib_list[i] != EGL_NONE; i++) {
+      EGLint attr = attrib_list[i++];
+      EGLint val = attrib_list[i];
+
+      switch (attr) {
+      default:
+         (void) val;
+         err = EGL_BAD_ATTRIBUTE;
+         break;
+      }
+
+      if (err != EGL_SUCCESS) {
+         _eglLog(_EGL_DEBUG, "bad sync attribute 0x%04x", attr);
+         break;
+      }
+   }
+
+   return err;
+}
+
+
+EGLBoolean
+_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
+             const EGLint *attrib_list)
+{
+   EGLint err;
+
+   if (!(type == EGL_SYNC_REUSABLE_KHR && dpy->Extensions.KHR_reusable_sync))
+      return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
+
+   memset(sync, 0, sizeof(*sync));
+
+   sync->Resource.Display = dpy;
+
+   sync->Type = type;
+   sync->SyncStatus = EGL_UNSIGNALED_KHR;
+
+   err = _eglParseSyncAttribList(sync, attrib_list);
+   if (err != EGL_SUCCESS)
+      return _eglError(err, "eglCreateSyncKHR");
+
+   return EGL_TRUE;
+}
+
+
+_EGLSync *
+_eglCreateSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy,
+                  EGLenum type, const EGLint *attrib_list)
+{
+   return NULL;
+}
+
+
+EGLBoolean
+_eglDestroySyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
+{
+   return EGL_TRUE;
+}
+
+
+EGLint
+_eglClientWaitSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                      EGLint flags, EGLTimeKHR timeout)
+{
+   return EGL_FALSE;
+}
+
+
+EGLBoolean
+_eglSignalSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                  EGLenum mode)
+{
+   return EGL_FALSE;
+}
+
+
+EGLBoolean
+_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                     EGLint attribute, EGLint *value)
+{
+   if (!value)
+      return _eglError(EGL_BAD_PARAMETER, "eglGetConfigs");
+
+   switch (attribute) {
+   case EGL_SYNC_TYPE_KHR:
+      *value = sync->Type;
+      break;
+   case EGL_SYNC_STATUS_KHR:
+      *value = sync->SyncStatus;
+      break;
+   default:
+      return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
+      break;
+   }
+
+   return EGL_TRUE;
+}
+
+
+#endif /* EGL_KHR_reusable_sync */
diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h
new file mode 100644
index 0000000..a013478
--- /dev/null
+++ b/src/egl/main/eglsync.h
@@ -0,0 +1,119 @@
+#ifndef EGLSYNC_INCLUDED
+#define EGLSYNC_INCLUDED
+
+
+#include "egltypedefs.h"
+#include "egldisplay.h"
+
+
+#ifdef EGL_KHR_reusable_sync
+
+
+/**
+ * "Base" class for device driver syncs.
+ */
+struct _egl_sync
+{
+   /* A sync is a display resource */
+   _EGLResource Resource;
+
+   EGLenum Type;
+   EGLenum SyncStatus;
+};
+
+
+PUBLIC EGLBoolean
+_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
+             const EGLint *attrib_list);
+
+
+extern _EGLSync *
+_eglCreateSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy,
+                  EGLenum type, const EGLint *attrib_list);
+
+
+extern EGLBoolean
+_eglDestroySyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
+
+
+extern EGLint
+_eglClientWaitSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                      EGLint flags, EGLTimeKHR timeout);
+
+
+extern EGLBoolean
+_eglSignalSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                  EGLenum mode);
+
+
+extern EGLBoolean
+_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+                     EGLint attribute, EGLint *value);
+
+
+/**
+ * Link a sync to a display and return the handle of the link.
+ * The handle can be passed to client directly.
+ */
+static INLINE EGLSyncKHR
+_eglLinkSync(_EGLSync *sync, _EGLDisplay *dpy)
+{
+   _eglLinkResource(&sync->Resource, _EGL_RESOURCE_SYNC, dpy);
+   return (EGLSyncKHR) sync;
+}
+
+
+/**
+ * Unlink a linked sync from its display.
+ */
+static INLINE void
+_eglUnlinkSync(_EGLSync *sync)
+{
+   _eglUnlinkResource(&sync->Resource, _EGL_RESOURCE_SYNC);
+}
+
+
+/**
+ * Lookup a handle to find the linked sync.
+ * Return NULL if the handle has no corresponding linked sync.
+ */
+static INLINE _EGLSync *
+_eglLookupSync(EGLSyncKHR handle, _EGLDisplay *dpy)
+{
+   _EGLSync *sync = (_EGLSync *) handle;
+   if (!dpy || !_eglCheckResource((void *) sync, _EGL_RESOURCE_SYNC, dpy))
+      sync = NULL;
+   return sync;
+}
+
+
+/**
+ * Return the handle of a linked sync, or EGL_NO_SYNC_KHR.
+ */
+static INLINE EGLSyncKHR
+_eglGetSyncHandle(_EGLSync *sync)
+{
+   _EGLResource *res = (_EGLResource *) sync;
+   return (res && _eglIsResourceLinked(res)) ?
+      (EGLSyncKHR) sync : EGL_NO_SYNC_KHR;
+}
+
+
+/**
+ * Return true if the sync is linked to a display.
+ *
+ * The link is considered a reference to the sync (the display is owning the
+ * sync).  Drivers should not destroy a sync when it is linked.
+ */
+static INLINE EGLBoolean
+_eglIsSyncLinked(_EGLSync *sync)
+{
+   _EGLResource *res = (_EGLResource *) sync;
+   return (res && _eglIsResourceLinked(res));
+}
+
+
+#endif /* EGL_KHR_reusable_sync */
+
+
+#endif /* EGLSYNC_INCLUDED */
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index 0e29e9a..b65f3b7 100644
--- a/src/egl/main/egltypedefs.h
+++ b/src/egl/main/egltypedefs.h
@@ -32,6 +32,8 @@ typedef struct _egl_screen _EGLScreen;
 
 typedef struct _egl_surface _EGLSurface;
 
+typedef struct _egl_sync _EGLSync;
+
 typedef struct _egl_thread_info _EGLThreadInfo;
 
 #endif /* EGLTYPEDEFS_INCLUDED */




More information about the mesa-commit mailing list