summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-08-14 23:09:12 +0800
committerChia-I Wu <[email protected]>2010-08-17 00:06:19 +0800
commit4eebea74a81ec5fbacf2347ea88cac137ddd4d69 (patch)
treed789cb3e6205ea0f4b80d9e954426fffcfee5fef
parentb2a575ff288a909eeddefe5168e29d15e6d17ab8 (diff)
egl: Add support for EGL_KHR_reusable_sync.
Individual drivers still need to support and enable the extension.
-rw-r--r--src/egl/main/Makefile6
-rw-r--r--src/egl/main/eglapi.c107
-rw-r--r--src/egl/main/eglapi.h18
-rw-r--r--src/egl/main/egldisplay.h6
-rw-r--r--src/egl/main/egldriver.c9
-rw-r--r--src/egl/main/eglmisc.c2
-rw-r--r--src/egl/main/eglsync.c121
-rw-r--r--src/egl/main/eglsync.h119
-rw-r--r--src/egl/main/egltypedefs.h2
9 files changed, 388 insertions, 2 deletions
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 41d301fc140..d92fbf6d9a7 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 4dc8707cfbc..53a5f6ed223 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 d8c8b49a49d..5045a9a272f 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 a2cee08bf6f..a5c14530676 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 8fc9e792b06..67f1d3dbaa4 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 985d1e0069d..2ef6ba59e34 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 00000000000..3f51e89acd6
--- /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 00000000000..a0134784aa2
--- /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 0e29e9aa47e..b65f3b72ae5 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 */