summaryrefslogtreecommitdiff
path: root/src/egl/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/main')
-rw-r--r--src/egl/main/Makefile6
-rw-r--r--src/egl/main/SConscript4
-rw-r--r--src/egl/main/egl.def35
-rw-r--r--src/egl/main/eglapi.c189
-rw-r--r--src/egl/main/eglapi.h28
-rw-r--r--src/egl/main/eglconfig.c7
-rw-r--r--src/egl/main/eglcontext.c20
-rw-r--r--src/egl/main/egldisplay.h8
-rw-r--r--src/egl/main/egldriver.c9
-rw-r--r--src/egl/main/eglmisc.c4
-rw-r--r--src/egl/main/eglsync.c128
-rw-r--r--src/egl/main/eglsync.h120
-rw-r--r--src/egl/main/egltypedefs.h2
13 files changed, 545 insertions, 15 deletions
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 41d301fc14..d92fbf6d9a 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/SConscript b/src/egl/main/SConscript
index 3d7ae3a8e4..06846475ba 100644
--- a/src/egl/main/SConscript
+++ b/src/egl/main/SConscript
@@ -12,6 +12,7 @@ if env['platform'] != 'winddk':
'_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_WINDOWS',
'_EGL_DRIVER_SEARCH_DIR=\\"\\"',
'_EGL_OS_WINDOWS',
+ '_EGL_GET_CORE_ADDRESSES',
'KHRONOS_DLL_EXPORTS',
])
@@ -36,11 +37,12 @@ if env['platform'] != 'winddk':
'eglscreen.c',
'eglstring.c',
'eglsurface.c',
+ 'eglsync.c',
]
egl = env.SharedLibrary(
target = 'libEGL',
- source = egl_sources,
+ source = egl_sources + ['egl.def'],
)
env.InstallSharedLibrary(egl, version=(1, 4, 0))
diff --git a/src/egl/main/egl.def b/src/egl/main/egl.def
new file mode 100644
index 0000000000..0cfe920e0e
--- /dev/null
+++ b/src/egl/main/egl.def
@@ -0,0 +1,35 @@
+EXPORTS
+ eglBindAPI
+ eglBindTexImage
+ eglChooseConfig
+ eglCopyBuffers
+ eglCreateContext
+ eglCreatePbufferFromClientBuffer
+ eglCreatePbufferSurface
+ eglCreatePixmapSurface
+ eglCreateWindowSurface
+ eglDestroyContext
+ eglDestroySurface
+ eglGetConfigAttrib
+ eglGetConfigs
+ eglGetCurrentContext
+ eglGetCurrentDisplay
+ eglGetCurrentSurface
+ eglGetDisplay
+ eglGetError
+ eglGetProcAddress
+ eglInitialize
+ eglMakeCurrent
+ eglQueryAPI
+ eglQueryContext
+ eglQueryString
+ eglQuerySurface
+ eglReleaseTexImage
+ eglReleaseThread
+ eglSurfaceAttrib
+ eglSwapBuffers
+ eglSwapInterval
+ eglTerminate
+ eglWaitClient
+ eglWaitGL
+ eglWaitNative
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 4dc8707cfb..31c5419bbc 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
@@ -809,7 +832,44 @@ eglGetProcAddress(const char *procname)
const char *name;
_EGLProc function;
} egl_functions[] = {
- /* extensions only */
+ /* core functions should not be queryable, but, well... */
+#ifdef _EGL_GET_CORE_ADDRESSES
+ /* alphabetical order */
+ { "eglBindAPI", (_EGLProc) eglBindAPI },
+ { "eglBindTexImage", (_EGLProc) eglBindTexImage },
+ { "eglChooseConfig", (_EGLProc) eglChooseConfig },
+ { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
+ { "eglCreateContext", (_EGLProc) eglCreateContext },
+ { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
+ { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
+ { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
+ { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
+ { "eglDestroyContext", (_EGLProc) eglDestroyContext },
+ { "eglDestroySurface", (_EGLProc) eglDestroySurface },
+ { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
+ { "eglGetConfigs", (_EGLProc) eglGetConfigs },
+ { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
+ { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
+ { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
+ { "eglGetDisplay", (_EGLProc) eglGetDisplay },
+ { "eglGetError", (_EGLProc) eglGetError },
+ { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
+ { "eglInitialize", (_EGLProc) eglInitialize },
+ { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
+ { "eglQueryAPI", (_EGLProc) eglQueryAPI },
+ { "eglQueryContext", (_EGLProc) eglQueryContext },
+ { "eglQueryString", (_EGLProc) eglQueryString },
+ { "eglQuerySurface", (_EGLProc) eglQuerySurface },
+ { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
+ { "eglReleaseThread", (_EGLProc) eglReleaseThread },
+ { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
+ { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
+ { "eglSwapInterval", (_EGLProc) eglSwapInterval },
+ { "eglTerminate", (_EGLProc) eglTerminate },
+ { "eglWaitClient", (_EGLProc) eglWaitClient },
+ { "eglWaitGL", (_EGLProc) eglWaitGL },
+ { "eglWaitNative", (_EGLProc) eglWaitNative },
+#endif /* _EGL_GET_CORE_ADDRESSES */
#ifdef EGL_MESA_screen_surface
{ "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
{ "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
@@ -834,6 +894,10 @@ eglGetProcAddress(const char *procname)
#ifdef EGL_NOK_swap_region
{ "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
#endif
+#ifdef EGL_MESA_drm_image
+ { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
+ { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
+#endif
{ NULL, NULL }
};
EGLint i;
@@ -1245,6 +1309,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
@@ -1272,3 +1420,42 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
}
#endif /* EGL_NOK_swap_region */
+
+
+#ifdef EGL_MESA_drm_image
+
+EGLImageKHR EGLAPIENTRY
+eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLDriver *drv;
+ _EGLImage *img;
+ EGLImageKHR ret;
+
+ _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
+
+ img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
+ ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR;
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+EGLBoolean EGLAPIENTRY
+eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
+ EGLint *name, EGLint *handle, EGLint *stride)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLImage *img = _eglLookupImage(image, disp);
+ _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+ if (!img)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+#endif
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index d8c8b49a49..127becc9ac 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -76,10 +76,25 @@ 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
+#ifdef EGL_MESA_drm_image
+typedef _EGLImage *(*CreateDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attr_list);
+typedef EGLBoolean (*ExportDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *name, EGLint *handle, EGLint *stride);
+#endif
+
/**
* The API dispatcher jumps through these functions
*/
@@ -138,9 +153,22 @@ 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
+
+#ifdef EGL_MESA_drm_image
+ CreateDRMImageMESA_t CreateDRMImageMESA;
+ ExportDRMImageMESA_t ExportDRMImageMESA;
+#endif
};
#endif /* EGLAPI_INCLUDED */
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index ea8e47d02b..01e7144d40 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -460,11 +460,14 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria)
}
if (!matched) {
-#ifdef DEBUG
+#ifndef DEBUG
+ /* only print the common errors when DEBUG is not defined */
+ if (attr != EGL_RENDERABLE_TYPE)
+ break;
+#endif
_eglLog(_EGL_DEBUG,
"the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)",
val, attr, cmp);
-#endif
break;
}
}
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 9fc529613e..e72664c23c 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -83,15 +83,6 @@ _eglParseContextAttribList(_EGLContext *ctx, const EGLint *attrib_list)
}
}
- if (err == EGL_SUCCESS && ctx->Config) {
- EGLint renderable_type, api_bit;
-
- renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE);
- api_bit = _eglGetContextAPIBit(ctx);
- if (!(renderable_type & api_bit))
- err = EGL_BAD_CONFIG;
- }
-
return err;
}
@@ -121,6 +112,17 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
ctx->ClientVersion = 1; /* the default, per EGL spec */
err = _eglParseContextAttribList(ctx, attrib_list);
+ if (err == EGL_SUCCESS && ctx->Config) {
+ EGLint renderable_type, api_bit;
+
+ renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE);
+ api_bit = _eglGetContextAPIBit(ctx);
+ if (!(renderable_type & api_bit)) {
+ _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x",
+ api_bit, renderable_type);
+ err = EGL_BAD_CONFIG;
+ }
+ }
if (err != EGL_SUCCESS)
return _eglError(err, "eglCreateContext");
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index a2cee08bf6..3863cce010 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,8 @@ struct _egl_extensions
EGLBoolean MESA_screen_surface;
EGLBoolean MESA_copy_context;
EGLBoolean MESA_drm_display;
+ EGLBoolean MESA_drm_image;
+
EGLBoolean KHR_image_base;
EGLBoolean KHR_image_pixmap;
EGLBoolean KHR_vg_parent_image;
@@ -60,9 +63,14 @@ 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_fence_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 8fc9e792b0..67f1d3dbaa 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 985d1e0069..eb3dde1fb4 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -85,6 +85,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(MESA_screen_surface);
_EGL_CHECK_EXTENSION(MESA_copy_context);
_EGL_CHECK_EXTENSION(MESA_drm_display);
+ _EGL_CHECK_EXTENSION(MESA_drm_image);
_EGL_CHECK_EXTENSION(KHR_image_base);
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
@@ -97,6 +98,9 @@ _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_fence_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 0000000000..b6c62d0087
--- /dev/null
+++ b/src/egl/main/eglsync.c
@@ -0,0 +1,128 @@
+#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) &&
+ !(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync))
+ return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
+
+ memset(sync, 0, sizeof(*sync));
+
+ sync->Resource.Display = dpy;
+
+ sync->Type = type;
+ sync->SyncStatus = EGL_UNSIGNALED_KHR;
+ sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_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;
+ case EGL_SYNC_CONDITION_KHR:
+ if (sync->Type != EGL_SYNC_FENCE_KHR)
+ return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
+ *value = sync->SyncCondition;
+ 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 0000000000..25c467175e
--- /dev/null
+++ b/src/egl/main/eglsync.h
@@ -0,0 +1,120 @@
+#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;
+ EGLenum SyncCondition;
+};
+
+
+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 0e29e9aa47..b65f3b72ae 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 */