+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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.
+ *
+ **************************************************************************/
+
+
/**
* Public EGL API entrypoints
*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
#include "eglcontext.h"
#include "egldisplay.h"
#include "egltypedefs.h"
-#include "eglglobals.h"
#include "eglcurrent.h"
#include "egldriver.h"
#include "eglsurface.h"
#include "eglscreen.h"
#include "eglmode.h"
#include "eglimage.h"
+#include "eglsync.h"
/**
#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 *
}
+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;
+}
+
+
#ifdef EGL_MESA_screen_surface
EGLDisplay EGLAPIENTRY
eglGetDisplay(EGLNativeDisplayType nativeDisplay)
{
- _EGLDisplay *dpy = _eglFindDisplay(nativeDisplay);
+ _EGLPlatformType plat = _eglGetNativePlatform(nativeDisplay);
+ _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);
return _eglGetDisplayHandle(dpy);
}
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
- EGLint major_int, minor_int;
if (!disp)
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
if (!disp->Initialized) {
- _EGLDriver *drv = disp->Driver;
-
- if (!drv) {
- _eglPreloadDrivers();
- drv = _eglMatchDriver(disp);
- if (!drv)
- RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
- }
-
- /* Initialize the particular display now */
- if (!drv->API.Initialize(drv, disp, &major_int, &minor_int))
+ if (!_eglMatchDriver(disp, EGL_FALSE))
RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
- disp->APImajor = major_int;
- disp->APIminor = minor_int;
- snprintf(disp->Version, sizeof(disp->Version),
- "%d.%d (%s)", major_int, minor_int, drv->Name);
-
/* limit to APIs supported by core */
- disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
-
- disp->Driver = drv;
- disp->Initialized = EGL_TRUE;
- } else {
- major_int = disp->APImajor;
- minor_int = disp->APIminor;
+ disp->ClientAPIs &= _EGL_API_ALL_BITS;
}
/* Update applications version of major and minor if not NULL */
if ((major != NULL) && (minor != NULL)) {
- *major = major_int;
- *minor = minor_int;
+ *major = disp->VersionMajor;
+ *minor = disp->VersionMinor;
}
RETURN_EGL_SUCCESS(disp, EGL_TRUE);
_EGLContext *context;
EGLContext ret;
- _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
+ _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
+
+ if (!config) {
+ /* config may be NULL if surfaceless */
+ if (!disp->Extensions.KHR_surfaceless_gles1 &&
+ !disp->Extensions.KHR_surfaceless_gles2 &&
+ !disp->Extensions.KHR_surfaceless_opengl)
+ RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+ }
+
if (!share && share_list != EGL_NO_CONTEXT)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
- ret = (context) ? _eglLinkContext(context, disp) : EGL_NO_CONTEXT;
+ ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
RETURN_EGL_EVAL(disp, ret);
}
if (!context && ctx != EGL_NO_CONTEXT)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
- if ((!draw_surf && draw != EGL_NO_SURFACE) ||
- (!read_surf && read != EGL_NO_SURFACE))
- RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
+ if (!draw_surf || !read_surf) {
+ /* surfaces may be NULL if surfaceless */
+ if (!disp->Extensions.KHR_surfaceless_gles1 &&
+ !disp->Extensions.KHR_surfaceless_gles2 &&
+ !disp->Extensions.KHR_surfaceless_opengl)
+ RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
+
+ if ((!draw_surf && draw != EGL_NO_SURFACE) ||
+ (!read_surf && read != EGL_NO_SURFACE))
+ RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
+ if (draw_surf || read_surf)
+ RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
+ }
ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
EGLSurface ret;
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
EGLSurface ret;
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
- if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp)
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ ctx->Resource.Display != disp)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
surf = ctx->DrawSurface;
- if (!_eglIsSurfaceLinked(surf))
+ if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
ret = drv->API.SwapInterval(drv, disp, surf, interval);
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
/* surface must be bound to current context in EGL 1.4 */
- if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ surf != ctx->DrawSurface)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
ret = drv->API.SwapBuffers(drv, disp, surf);
EGLBoolean ret;
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
+ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
ret = drv->API.CopyBuffers(drv, disp, surf, target);
RETURN_EGL_EVAL(disp, ret);
_eglLockMutex(&disp->Mutex);
/* let bad current context imply bad current surface */
- if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
/* a valid current context implies an initialized current display */
EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
-#ifdef EGL_VERSION_1_2
_EGLThreadInfo *t = _eglGetCurrentThread();
EGLint api_index = t->CurrentAPIIndex;
EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
ret = eglWaitClient();
t->CurrentAPIIndex = api_index;
return ret;
-#else
- return eglWaitClient();
-#endif
}
_eglLockMutex(&disp->Mutex);
/* let bad current context imply bad current surface */
- if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
/* a valid current context implies an initialized current display */
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 },
{ "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
{ "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
#endif /* EGL_MESA_screen_surface */
-#ifdef EGL_KHR_image_base
+#ifdef EGL_MESA_drm_display
+ { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
+#endif
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
-#endif /* EGL_KHR_image_base */
+ { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
+ { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
+ { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
+ { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
+ { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
+#ifdef EGL_NOK_swap_region
+ { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
+#endif
+#ifdef EGL_MESA_drm_image
+ { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
+ { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
+#endif
+#ifdef EGL_WL_bind_wayland_display
+ { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
+ { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
+#endif
+ { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
{ NULL, NULL }
};
EGLint i;
}
}
}
- if (ret)
- RETURN_EGL_SUCCESS(NULL, ret);
-
- _eglPreloadDrivers();
-
- /* now loop over drivers to query their procs */
- for (i = 0; i < _eglGlobal.NumDrivers; i++) {
- _EGLDriver *drv = _eglGlobal.Drivers[i];
- ret = drv->API.GetProcAddress(drv, procname);
- if (ret)
- break;
- }
+ if (!ret)
+ ret = _eglGetDriverProc(procname);
RETURN_EGL_SUCCESS(NULL, ret);
}
}
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
EGLint max_screens, EGLint *num_screens)
{
}
-EGLSurface
+EGLSurface EGLAPIENTRY
eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
EGLSurface surface, EGLModeMESA mode)
{
}
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
}
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLint attribute, EGLint *value)
{
}
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
EGLSurface *surface)
{
}
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
}
-const char *
+const char * EGLAPIENTRY
eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
#endif /* EGL_MESA_screen_surface */
+#ifdef EGL_MESA_drm_display
+
+EGLDisplay EGLAPIENTRY
+eglGetDRMDisplayMESA(int fd)
+{
+ _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
+ return _eglGetDisplayHandle(dpy);
+}
+
+#endif /* EGL_MESA_drm_display */
+
/**
** EGL 1.2
**/
-#ifdef EGL_VERSION_1_2
-
-
/**
* Specify the client API to use for subsequent calls including:
* eglCreateContext()
* eglWaitNative()
* See section 3.7 "Rendering Context" in the EGL specification for details.
*/
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglBindAPI(EGLenum api)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
/**
* Return the last value set with eglBindAPI().
*/
-EGLenum
+EGLenum EGLAPIENTRY
eglQueryAPI(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
}
-EGLSurface
+EGLSurface EGLAPIENTRY
eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
EGLClientBuffer buffer, EGLConfig config,
const EGLint *attrib_list)
surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
conf, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglReleaseThread(void)
{
/* unbind current contexts */
}
-#endif /* EGL_VERSION_1_2 */
-
-
-#ifdef EGL_KHR_image_base
-
-
-EGLImageKHR
+EGLImageKHR EGLAPIENTRY
eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
EGLClientBuffer buffer, const EGLint *attr_list)
{
EGLImageKHR ret;
_EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
+ if (!disp->Extensions.KHR_image_base)
+ RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
if (!context && ctx != EGL_NO_CONTEXT)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
img = drv->API.CreateImageKHR(drv,
disp, context, target, buffer, attr_list);
- ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR;
+ ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
RETURN_EGL_EVAL(disp, ret);
}
-EGLBoolean
+EGLBoolean EGLAPIENTRY
eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
EGLBoolean ret;
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+ if (!disp->Extensions.KHR_image_base)
+ RETURN_EGL_EVAL(disp, EGL_FALSE);
if (!img)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
}
-#endif /* EGL_KHR_image_base */
+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);
+ if (!disp->Extensions.KHR_reusable_sync)
+ RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
+
+ sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
+ ret = (sync) ? _eglLinkSync(sync) : 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);
+ assert(disp->Extensions.KHR_reusable_sync);
+
+ _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);
+ assert(disp->Extensions.KHR_reusable_sync);
+ 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);
+ assert(disp->Extensions.KHR_reusable_sync);
+ 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);
+ assert(disp->Extensions.KHR_reusable_sync);
+ ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+
+#ifdef EGL_NOK_swap_region
+
+EGLBoolean EGLAPIENTRY
+eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
+ EGLint numRects, const EGLint *rects)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSurface *surf = _eglLookupSurface(surface, disp);
+ _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+
+ if (!disp->Extensions.NOK_swap_region)
+ RETURN_EGL_EVAL(disp, EGL_FALSE);
+
+ /* surface must be bound to current context in EGL 1.4 */
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ surf != ctx->DrawSurface)
+ RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
+
+ ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+#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);
+ if (!disp->Extensions.MESA_drm_image)
+ RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
+
+ img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
+ ret = (img) ? _eglLinkImage(img) : 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);
+ assert(disp->Extensions.MESA_drm_image);
+
+ 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
+
+#ifdef EGL_WL_bind_wayland_display
+struct wl_display;
+
+EGLBoolean EGLAPIENTRY
+eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+ assert(disp->Extensions.WL_bind_wayland_display);
+
+ if (!display)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+EGLBoolean EGLAPIENTRY
+eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+ assert(disp->Extensions.WL_bind_wayland_display);
+
+ if (!display)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+#endif
+
+
+EGLBoolean EGLAPIENTRY
+eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
+ EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSurface *surf = _eglLookupSurface(surface, disp);
+ _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+
+ if (!disp->Extensions.NV_post_sub_buffer)
+ RETURN_EGL_EVAL(disp, EGL_FALSE);
+
+ ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
+
+ RETURN_EGL_EVAL(disp, ret);
+}