/**************************************************************************
 *
 * Copyright 2008 VMware, Inc.
 * 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
 *
 * Generally, we use the EGLDisplay parameter as a key to lookup the
 * appropriate device driver handle, then jump though the driver's
 * dispatch table to handle the function.
 *
 * That allows us the option of supporting multiple, simultaneous,
 * heterogeneous hardware devices in the future.
 *
 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
 * opaque handles. Internal objects are linked to a display to
 * create the handles.
 *
 * For each public API entry point, the opaque handles are looked up
 * before being dispatched to the drivers.  When it fails to look up
 * a handle, one of
 *
 * EGL_BAD_DISPLAY
 * EGL_BAD_CONFIG
 * EGL_BAD_CONTEXT
 * EGL_BAD_SURFACE
 * EGL_BAD_SCREEN_MESA
 * EGL_BAD_MODE_MESA
 *
 * is generated and the driver function is not called. An
 * uninitialized EGLDisplay has no driver associated with it. When
 * such display is detected,
 *
 * EGL_NOT_INITIALIZED
 *
 * is generated.
 *
 * Some of the entry points use current display, context, or surface
 * implicitly.  For such entry points, the implicit objects are also
 * checked before calling the driver function.  Other than the
 * errors listed above,
 *
 * EGL_BAD_CURRENT_SURFACE
 *
 * may also be generated.
 *
 * Notes on naming conventions:
 *
 * eglFooBar    - public EGL function
 * EGL_FOO_BAR  - public EGL token
 * EGLDatatype  - public EGL datatype
 *
 * _eglFooBar   - private EGL function
 * _EGLDatatype - private EGL datatype, typedef'd struct
 * _egl_struct  - private EGL struct, non-typedef'd
 *
 */


#ifdef USE_LIBGLVND
#define EGLAPI
#undef PUBLIC
#define PUBLIC
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "c99_compat.h"
#include "c11/threads.h"
#include "util/macros.h"

#include "egldefines.h"
#include "eglglobals.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egltypedefs.h"
#include "eglcurrent.h"
#include "egldevice.h"
#include "egldriver.h"
#include "eglsurface.h"
#include "eglconfig.h"
#include "eglimage.h"
#include "eglsync.h"

#include "GL/mesa_glinterop.h"

/**
 * Macros to help return an API entrypoint.
 *
 * These macros will unlock the display and record the error code.
 */
#define RETURN_EGL_ERROR(disp, err, ret)        \
   do {                                         \
      if (disp)                                 \
         _eglUnlockDisplay(disp);               \
      /* EGL error codes are non-zero */        \
      if (err)                                  \
         _eglError(err, __func__);              \
      return ret;                               \
   } while (0)

#define RETURN_EGL_SUCCESS(disp, ret) \
   RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)

/* record EGL_SUCCESS only when ret evaluates to true */
#define RETURN_EGL_EVAL(disp, ret) \
   RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)


/*
 * A bunch of macros and checks to simplify error checking.
 */

#define _EGL_CHECK_DISPLAY(disp, ret, drv)         \
   do {                                            \
      drv = _eglCheckDisplay(disp, __func__);      \
      if (!drv)                                    \
         RETURN_EGL_ERROR(disp, 0, ret);           \
   } while (0)

#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv)      \
   do {                                                   \
      drv = _eglCheck ## type(disp, obj, __func__);       \
      if (!drv)                                           \
         RETURN_EGL_ERROR(disp, 0, ret);                  \
   } while (0)

#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
   _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)

#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
   _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)

#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
   _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)

#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
   _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)


struct _egl_entrypoint {
   const char *name;
   _EGLProc function;
};


static inline const _EGLDriver *
_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
{
   if (!disp) {
      _eglError(EGL_BAD_DISPLAY, msg);
      return NULL;
   }
   if (!disp->Initialized) {
      _eglError(EGL_NOT_INITIALIZED, msg);
      return NULL;
   }
   return disp->Driver;
}


static inline const _EGLDriver *
_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
{
   const _EGLDriver *drv = _eglCheckDisplay(disp, msg);
   if (!drv)
      return NULL;
   if (!surf) {
      _eglError(EGL_BAD_SURFACE, msg);
      return NULL;
   }
   return drv;
}


static inline const _EGLDriver *
_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
{
   const _EGLDriver *drv = _eglCheckDisplay(disp, msg);
   if (!drv)
      return NULL;
   if (!context) {
      _eglError(EGL_BAD_CONTEXT, msg);
      return NULL;
   }
   return drv;
}


static inline const _EGLDriver *
_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
{
   const _EGLDriver *drv = _eglCheckDisplay(disp, msg);
   if (!drv)
      return NULL;
   if (!conf) {
      _eglError(EGL_BAD_CONFIG, msg);
      return NULL;
   }
   return drv;
}


static inline const _EGLDriver *
_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
{
   const _EGLDriver *drv = _eglCheckDisplay(disp, msg);
   if (!drv)
      return NULL;
   if (!s) {
      _eglError(EGL_BAD_PARAMETER, msg);
      return NULL;
   }
   return drv;
}


/**
 * Lookup and lock a display.
 */
static inline _EGLDisplay *
_eglLockDisplay(EGLDisplay dpy)
{
   _EGLDisplay *disp = _eglLookupDisplay(dpy);
   if (disp)
      mtx_lock(&disp->Mutex);
   return disp;
}


/**
 * Unlock a display.
 */
static inline void
_eglUnlockDisplay(_EGLDisplay *disp)
{
   mtx_unlock(&disp->Mutex);
}

static EGLBoolean
_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
{
   _EGLThreadInfo *thr = _eglGetCurrentThread();
   if (!_eglIsCurrentThreadDummy()) {
      thr->CurrentFuncName = funcName;
      thr->CurrentObjectLabel = NULL;

      if (objectType == EGL_OBJECT_THREAD_KHR)
         thr->CurrentObjectLabel = thr->Label;
      else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
         thr->CurrentObjectLabel = disp->Label;
      else if (object)
         thr->CurrentObjectLabel = object->Label;

      return EGL_TRUE;
   }

   _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL);
   return EGL_FALSE;
}

#define _EGL_FUNC_START(disp, objectType, object, ret) \
   do { \
      if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
         if (disp)                                 \
            _eglUnlockDisplay(disp);               \
         return ret; \
      } \
   } while(0)

/**
 * Convert an attribute list from EGLint[] to EGLAttrib[].
 *
 * Return an EGL error code. The output parameter out_attrib_list is modified
 * only on success.
 */
static EGLint
_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
{
   size_t len = 0;
   EGLAttrib *attrib_list;

   if (int_list) {
      while (int_list[2*len] != EGL_NONE)
         ++len;
   }

   if (len == 0) {
      *out_attrib_list = NULL;
      return EGL_SUCCESS;
   }

   if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
      return EGL_BAD_ALLOC;

   attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
   if (!attrib_list)
      return EGL_BAD_ALLOC;

   for (size_t i = 0; i < len; ++i) {
      attrib_list[2*i + 0] = int_list[2*i + 0];
      attrib_list[2*i + 1] = int_list[2*i + 1];
   }

   attrib_list[2*len] = EGL_NONE;

   *out_attrib_list = attrib_list;
   return EGL_SUCCESS;
}


static EGLint *
_eglConvertAttribsToInt(const EGLAttrib *attr_list)
{
   size_t size = _eglNumAttribs(attr_list);
   EGLint *int_attribs = NULL;

   /* Convert attributes from EGLAttrib[] to EGLint[] */
   if (size) {
      int_attribs = calloc(size, sizeof(int_attribs[0]));
      if (!int_attribs)
         return NULL;

      for (size_t i = 0; i < size; i++)
         int_attribs[i] = attr_list[i];
   }
   return int_attribs;
}


/**
 * This is typically the first EGL function that an application calls.
 * It associates a private _EGLDisplay object to the native display.
 */
EGLDisplay EGLAPIENTRY
eglGetDisplay(EGLNativeDisplayType nativeDisplay)
{
   _EGLPlatformType plat;
   _EGLDisplay *disp;
   void *native_display_ptr;

   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);

   STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
   native_display_ptr = (void*) nativeDisplay;

   plat = _eglGetNativePlatform(native_display_ptr);
   disp = _eglFindDisplay(plat, native_display_ptr, NULL);
   return _eglGetDisplayHandle(disp);
}

static EGLDisplay
_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
                             const EGLAttrib *attrib_list)
{
   _EGLDisplay *disp;

   switch (platform) {
#ifdef HAVE_X11_PLATFORM
   case EGL_PLATFORM_X11_EXT:
      disp = _eglGetX11Display((Display*) native_display, attrib_list);
      break;
#endif
#ifdef HAVE_DRM_PLATFORM
   case EGL_PLATFORM_GBM_MESA:
      disp = _eglGetGbmDisplay((struct gbm_device*) native_display,
                              attrib_list);
      break;
#endif
#ifdef HAVE_WAYLAND_PLATFORM
   case EGL_PLATFORM_WAYLAND_EXT:
      disp = _eglGetWaylandDisplay((struct wl_display*) native_display,
                                  attrib_list);
      break;
#endif
   case EGL_PLATFORM_SURFACELESS_MESA:
      disp = _eglGetSurfacelessDisplay(native_display, attrib_list);
      break;
#ifdef HAVE_ANDROID_PLATFORM
   case EGL_PLATFORM_ANDROID_KHR:
      disp = _eglGetAndroidDisplay(native_display, attrib_list);
      break;
#endif
   case EGL_PLATFORM_DEVICE_EXT:
      disp = _eglGetDeviceDisplay(native_display, attrib_list);
      break;
   default:
      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
   }

   return _eglGetDisplayHandle(disp);
}

static EGLDisplay EGLAPIENTRY
eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
                         const EGLint *int_attribs)
{
   EGLAttrib *attrib_list;
   EGLDisplay disp;

   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);

   if (_eglConvertIntsToAttribs(int_attribs, &attrib_list) != EGL_SUCCESS)
      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);

   disp = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
   free(attrib_list);
   return disp;
}

EGLDisplay EGLAPIENTRY
eglGetPlatformDisplay(EGLenum platform, void *native_display,
                      const EGLAttrib *attrib_list)
{
   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
   return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
}

/**
 * Copy the extension into the string and update the string pointer.
 */
static EGLint
_eglAppendExtension(char **str, const char *ext)
{
   char *s = *str;
   size_t len = strlen(ext);

   if (s) {
      memcpy(s, ext, len);
      s[len++] = ' ';
      s[len] = '\0';

      *str += len;
   }
   else {
      len++;
   }

   return (EGLint) len;
}

/**
 * Examine the individual extension enable/disable flags and recompute
 * the driver's Extensions string.
 */
static void
_eglCreateExtensionsString(_EGLDisplay *disp)
{
#define _EGL_CHECK_EXTENSION(ext)                                          \
   do {                                                                    \
      if (disp->Extensions.ext) {                                           \
         _eglAppendExtension(&exts, "EGL_" #ext);                          \
         assert(exts <= disp->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN);  \
      }                                                                    \
   } while (0)

   char *exts = disp->ExtensionsString;

   /* Please keep these sorted alphabetically. */
   _EGL_CHECK_EXTENSION(ANDROID_blob_cache);
   _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
   _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
   _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync);
   _EGL_CHECK_EXTENSION(ANDROID_recordable);

   _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);

   _EGL_CHECK_EXTENSION(EXT_buffer_age);
   _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
   _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
   _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
   _EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
   _EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
   _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);

   _EGL_CHECK_EXTENSION(IMG_context_priority);

   _EGL_CHECK_EXTENSION(KHR_cl_event2);
   _EGL_CHECK_EXTENSION(KHR_config_attribs);
   _EGL_CHECK_EXTENSION(KHR_context_flush_control);
   _EGL_CHECK_EXTENSION(KHR_create_context);
   _EGL_CHECK_EXTENSION(KHR_create_context_no_error);
   _EGL_CHECK_EXTENSION(KHR_fence_sync);
   _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
   _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
   _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
   _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
   _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
   _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
   if (disp->Extensions.KHR_image_base && disp->Extensions.KHR_image_pixmap)
      disp->Extensions.KHR_image = EGL_TRUE;
   _EGL_CHECK_EXTENSION(KHR_image);
   _EGL_CHECK_EXTENSION(KHR_image_base);
   _EGL_CHECK_EXTENSION(KHR_image_pixmap);
   _EGL_CHECK_EXTENSION(KHR_mutable_render_buffer);
   _EGL_CHECK_EXTENSION(KHR_no_config_context);
   _EGL_CHECK_EXTENSION(KHR_partial_update);
   _EGL_CHECK_EXTENSION(KHR_reusable_sync);
   _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
   if (disp->Extensions.EXT_swap_buffers_with_damage)
      _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
   _EGL_CHECK_EXTENSION(EXT_pixel_format_float);
   _EGL_CHECK_EXTENSION(KHR_wait_sync);

   if (disp->Extensions.KHR_no_config_context)
      _eglAppendExtension(&exts, "EGL_MESA_configless_context");
   _EGL_CHECK_EXTENSION(MESA_drm_image);
   _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
   _EGL_CHECK_EXTENSION(MESA_query_driver);

   _EGL_CHECK_EXTENSION(NOK_swap_region);
   _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);

   _EGL_CHECK_EXTENSION(NV_post_sub_buffer);

   _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
   _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);

#undef _EGL_CHECK_EXTENSION
}

static void
_eglCreateAPIsString(_EGLDisplay *disp)
{
#define addstr(str) \
   { \
      const size_t old_len = strlen(disp->ClientAPIsString); \
      const size_t add_len = sizeof(str); \
      const size_t max_len = sizeof(disp->ClientAPIsString) - 1; \
      if (old_len + add_len <= max_len) \
         strcat(disp->ClientAPIsString, str " "); \
      else \
         assert(!"disp->ClientAPIsString is not large enough"); \
   }

   if (disp->ClientAPIs & EGL_OPENGL_BIT)
      addstr("OpenGL");

   if (disp->ClientAPIs & EGL_OPENGL_ES_BIT ||
       disp->ClientAPIs & EGL_OPENGL_ES2_BIT ||
       disp->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
      addstr("OpenGL_ES");
   }

   if (disp->ClientAPIs & EGL_OPENVG_BIT)
      addstr("OpenVG");

#undef addstr
}

static void
_eglComputeVersion(_EGLDisplay *disp)
{
   disp->Version = 14;

   if (disp->Extensions.KHR_fence_sync &&
       disp->Extensions.KHR_cl_event2 &&
       disp->Extensions.KHR_wait_sync &&
       disp->Extensions.KHR_image_base &&
       disp->Extensions.KHR_gl_texture_2D_image &&
       disp->Extensions.KHR_gl_texture_3D_image &&
       disp->Extensions.KHR_gl_texture_cubemap_image &&
       disp->Extensions.KHR_gl_renderbuffer_image &&
       disp->Extensions.KHR_create_context &&
       disp->Extensions.EXT_create_context_robustness &&
       disp->Extensions.KHR_get_all_proc_addresses &&
       disp->Extensions.KHR_gl_colorspace &&
       disp->Extensions.KHR_surfaceless_context)
      disp->Version = 15;

   /* For Android P and below limit the EGL version to 1.4 */
#if defined(ANDROID) && ANDROID_API_LEVEL <= 28
   disp->Version = 14;
#endif
}

/**
 * This is typically the second EGL function that an application calls.
 * Here we load/initialize the actual hardware driver.
 */
EGLBoolean EGLAPIENTRY
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   if (!disp)
      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);

   if (!disp->Initialized) {
      if (!_eglInitializeDisplay(disp))
         RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);

      /* limit to APIs supported by core */
      disp->ClientAPIs &= _EGL_API_ALL_BITS;

      /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
       * classifies it as an EGL display extension, though conceptually it's an
       * EGL client extension.
       *
       * From the EGL_KHR_get_all_proc_addresses spec:
       *
       *    The EGL implementation must expose the name
       *    EGL_KHR_client_get_all_proc_addresses if and only if it exposes
       *    EGL_KHR_get_all_proc_addresses and supports
       *    EGL_EXT_client_extensions.
       *
       * Mesa unconditionally exposes both client extensions mentioned above,
       * so the spec requires that each EGLDisplay unconditionally expose
       * EGL_KHR_get_all_proc_addresses also.
       */
      disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;

      /* Extensions is used to provide EGL 1.3 functionality for 1.2 aware
       * programs. It is driver agnostic and handled in the main EGL code.
       */
      disp->Extensions.KHR_config_attribs = EGL_TRUE;

      _eglComputeVersion(disp);
      _eglCreateExtensionsString(disp);
      _eglCreateAPIsString(disp);
      snprintf(disp->VersionString, sizeof(disp->VersionString),
               "%d.%d", disp->Version / 10, disp->Version % 10);
   }

   /* Update applications version of major and minor if not NULL */
   if ((major != NULL) && (minor != NULL)) {
      *major = disp->Version / 10;
      *minor = disp->Version % 10;
   }

   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
}


EGLBoolean EGLAPIENTRY
eglTerminate(EGLDisplay dpy)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   if (!disp)
      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);

   if (disp->Initialized) {
      const _EGLDriver *drv = disp->Driver;

      drv->Terminate(drv, disp);
      /* do not reset disp->Driver */
      disp->ClientAPIsString[0] = 0;
      disp->Initialized = EGL_FALSE;

      /* Reset blob cache funcs on terminate. */
      disp->BlobCacheSet = NULL;
      disp->BlobCacheGet = NULL;
   }

   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
}


const char * EGLAPIENTRY
eglQueryString(EGLDisplay dpy, EGLint name)
{
   _EGLDisplay *disp;
   const _EGLDriver *drv;

#if !USE_LIBGLVND
   if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
      RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
   }
#endif

   disp = _eglLockDisplay(dpy);
   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
   _EGL_CHECK_DISPLAY(disp, NULL, drv);

   switch (name) {
   case EGL_VENDOR:
      RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
   case EGL_VERSION:
      RETURN_EGL_SUCCESS(disp, disp->VersionString);
   case EGL_EXTENSIONS:
      RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
   case EGL_CLIENT_APIS:
      RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
   default:
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
   }
}


EGLBoolean EGLAPIENTRY
eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
              EGLint config_size, EGLint *num_config)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);

   if (!num_config)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   ret = _eglGetConfigs(drv, disp, configs, config_size, num_config);

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
                EGLint config_size, EGLint *num_config)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);

   if (!num_config)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   ret = _eglChooseConfig(drv, disp, attrib_list, configs,
                          config_size, num_config);

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
                   EGLint attribute, EGLint *value)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLConfig *conf = _eglLookupConfig(config, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);

   ret = _eglGetConfigAttrib(drv, disp, conf, attribute, value);

   RETURN_EGL_EVAL(disp, ret);
}


EGLContext EGLAPIENTRY
eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
                 const EGLint *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLConfig *conf = _eglLookupConfig(config, disp);
   _EGLContext *share = _eglLookupContext(share_list, disp);
   const _EGLDriver *drv;
   _EGLContext *context;
   EGLContext ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);

   _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);

   if (config != EGL_NO_CONFIG_KHR)
      _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
   else if (!disp->Extensions.KHR_no_config_context)
      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->CreateContext(drv, disp, conf, share, attrib_list);
   ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLContext *context = _eglLookupContext(ctx, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);

   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
   _eglUnlinkContext(context);
   ret = drv->DestroyContext(drv, disp, context);

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
               EGLContext ctx)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLContext *context = _eglLookupContext(ctx, disp);
   _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
   _EGLSurface *read_surf = _eglLookupSurface(read, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);

   if (!disp)
      RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
   drv = disp->Driver;

   /* display is allowed to be uninitialized under certain condition */
   if (!disp->Initialized) {
      if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
          ctx != EGL_NO_CONTEXT)
         RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
   }
   if (!drv)
      RETURN_EGL_SUCCESS(disp, EGL_TRUE);

   if (!context && ctx != EGL_NO_CONTEXT)
      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
   if (!draw_surf || !read_surf) {
      /* From the EGL 1.4 (20130211) spec:
       *
       *    To release the current context without assigning a new one, set ctx
       *    to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
       */
      if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
         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);
   }

   /*    If a native window underlying either draw or read is no longer valid,
    *    an EGL_BAD_NATIVE_WINDOW error is generated.
    */
   if (draw_surf && draw_surf->Lost)
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
   if (read_surf && read_surf->Lost)
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);

   ret = drv->MakeCurrent(drv, disp, draw_surf, read_surf, context);

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglQueryContext(EGLDisplay dpy, EGLContext ctx,
                EGLint attribute, EGLint *value)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLContext *context = _eglLookupContext(ctx, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);

   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);

   ret = _eglQueryContext(drv, disp, context, attribute, value);

   RETURN_EGL_EVAL(disp, ret);
}


/* In EGL specs 1.4 and 1.5, at the end of sections 3.5.1 and 3.5.4, it says
 * that if native_surface was already used to create a window or pixmap, we
 * can't create a new one. This is what this function checks for.
 */
static bool
_eglNativeSurfaceAlreadyUsed(_EGLDisplay *disp, void *native_surface)
{
   _EGLResource *list;

   list = disp->ResourceLists[_EGL_RESOURCE_SURFACE];
   while (list) {
      _EGLSurface *surf = (_EGLSurface *) list;

      list = list->Next;

      if (surf->Type == EGL_PBUFFER_BIT)
         continue;

      if (surf->NativeSurface == native_surface)
         return true;
   }

   return false;
}


static EGLSurface
_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
                              void *native_window, const EGLint *attrib_list)
{
   _EGLConfig *conf = _eglLookupConfig(config, disp);
   const _EGLDriver *drv;
   _EGLSurface *surf;
   EGLSurface ret;


   if (native_window == NULL)
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);

   if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
                disp->Platform == _EGL_PLATFORM_DEVICE)) {
      /* From the EGL_MESA_platform_surfaceless spec (v1):
       *
       *    eglCreatePlatformWindowSurface fails when called with a <display>
       *    that belongs to the surfaceless platform. It returns
       *    EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
       *    justification for this unconditional failure is that the
       *    surfaceless platform has no native windows, and therefore the
       *    <native_window> parameter is always invalid.
       *
       * This check must occur before checking the EGLConfig, which emits
       * EGL_BAD_CONFIG.
       */
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
   }

   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);

   if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);

   if (_eglNativeSurfaceAlreadyUsed(disp, native_window))
      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);

   surf = drv->CreateWindowSurface(drv, disp, conf, native_window,
                                       attrib_list);
   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;

   RETURN_EGL_EVAL(disp, ret);
}


EGLSurface EGLAPIENTRY
eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
                       EGLNativeWindowType window, const EGLint *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
   STATIC_ASSERT(sizeof(void*) == sizeof(window));
   return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
                                        attrib_list);
}

static void *
_fixupNativeWindow(_EGLDisplay *disp, void *native_window)
{
#ifdef HAVE_X11_PLATFORM
   if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
      /* The `native_window` parameter for the X11 platform differs between
       * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
       * eglCreateWindowSurface(), the type of `native_window` is an Xlib
       * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
       * `Window*`.  Convert `Window*` to `Window` because that's what
       * dri2_x11_create_window_surface() expects.
       */
      return (void *)(* (Window*) native_window);
   }
#endif
   return native_window;
}

static EGLSurface EGLAPIENTRY
eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
                                  void *native_window,
                                  const EGLint *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);

   native_window = _fixupNativeWindow(disp, native_window);

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
   return _eglCreateWindowSurfaceCommon(disp, config, native_window,
                                        attrib_list);
}


EGLSurface EGLAPIENTRY
eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
                               void *native_window,
                               const EGLAttrib *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   EGLSurface surface;
   EGLint *int_attribs;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);

   int_attribs = _eglConvertAttribsToInt(attrib_list);
   if (attrib_list && !int_attribs)
      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);

   native_window = _fixupNativeWindow(disp, native_window);
   surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
                                           int_attribs);
   free(int_attribs);
   return surface;
}

static void *
_fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
{
#ifdef HAVE_X11_PLATFORM
   /* The `native_pixmap` parameter for the X11 platform differs between
    * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
    * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
    * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
    * `Pixmap*`.  Convert `Pixmap*` to `Pixmap` because that's what
    * dri2_x11_create_pixmap_surface() expects.
    */
   if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
      return (void *)(* (Pixmap*) native_pixmap);
#endif
   return native_pixmap;
}

static EGLSurface
_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
                              void *native_pixmap, const EGLint *attrib_list)
{
   _EGLConfig *conf = _eglLookupConfig(config, disp);
   const _EGLDriver *drv;
   _EGLSurface *surf;
   EGLSurface ret;

   if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
                disp->Platform == _EGL_PLATFORM_DEVICE)) {
      /* From the EGL_MESA_platform_surfaceless spec (v1):
       *
       *   [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
       *   also fails when called with a <display> that belongs to the
       *   surfaceless platform.  It returns EGL_NO_SURFACE and generates
       *   EGL_BAD_NATIVE_PIXMAP.
       *
       * This check must occur before checking the EGLConfig, which emits
       * EGL_BAD_CONFIG.
       */
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
   }

   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);

   if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);

   if (native_pixmap == NULL)
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);

   if (_eglNativeSurfaceAlreadyUsed(disp, native_pixmap))
      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);

   surf = drv->CreatePixmapSurface(drv, disp, conf, native_pixmap,
                                       attrib_list);
   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;

   RETURN_EGL_EVAL(disp, ret);
}


EGLSurface EGLAPIENTRY
eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
                       EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
   STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
   return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
                                        attrib_list);
}

static EGLSurface EGLAPIENTRY
eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
                                  void *native_pixmap,
                                  const EGLint *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
   native_pixmap = _fixupNativePixmap(disp, native_pixmap);
   return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
                                        attrib_list);
}


EGLSurface EGLAPIENTRY
eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
                               void *native_pixmap,
                               const EGLAttrib *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   EGLSurface surface;
   EGLint *int_attribs;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);

   int_attribs = _eglConvertAttribsToInt(attrib_list);
   if (attrib_list && !int_attribs)
      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);

   native_pixmap = _fixupNativePixmap(disp, native_pixmap);
   surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
                                           int_attribs);
   free(int_attribs);
   return surface;
}


EGLSurface EGLAPIENTRY
eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
                        const EGLint *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLConfig *conf = _eglLookupConfig(config, disp);
   const _EGLDriver *drv;
   _EGLSurface *surf;
   EGLSurface ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);

   if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);

   surf = drv->CreatePbufferSurface(drv, disp, conf, attrib_list);
   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
   _eglUnlinkSurface(surf);
   ret = drv->DestroySurface(drv, disp, surf);

   RETURN_EGL_EVAL(disp, ret);
}

EGLBoolean EGLAPIENTRY
eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
                EGLint attribute, EGLint *value)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);

   if (drv->QuerySurface)
      ret = drv->QuerySurface(drv, disp, surf, attribute, value);
   else
      ret = _eglQuerySurface(drv, disp, surf, attribute, value);

   RETURN_EGL_EVAL(disp, ret);
}

EGLBoolean EGLAPIENTRY
eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
                 EGLint attribute, EGLint value)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);

   ret = _eglSurfaceAttrib(drv, disp, surf, attribute, value);

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
   ret = drv->BindTexImage(drv, disp, surf, buffer);

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
   ret = drv->ReleaseTexImage(drv, disp, surf, buffer);

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLContext *ctx = _eglGetCurrentContext();
   _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);

   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
       ctx->Resource.Display != disp)
      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);

   if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);

   if (surf->Type != EGL_WINDOW_BIT)
      RETURN_EGL_EVAL(disp, EGL_TRUE);

   interval = CLAMP(interval,
                    surf->Config->MinSwapInterval,
                    surf->Config->MaxSwapInterval);

   if (surf->SwapInterval != interval) {
      if (drv->SwapInterval)
         ret = drv->SwapInterval(drv, disp, surf, interval);
      else
         ret = _eglSwapInterval(drv, disp, surf, interval);
   }
   else {
      ret = EGL_TRUE;
   }

   if (ret)
      surf->SwapInterval = interval;

   RETURN_EGL_EVAL(disp, ret);
}


EGLBoolean EGLAPIENTRY
eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);

   /* surface must be bound to current context in EGL 1.4 */
   #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
       surf != ctx->DrawSurface)
      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
   #endif

   if (surf->Type != EGL_WINDOW_BIT)
      RETURN_EGL_EVAL(disp, EGL_TRUE);

   /* From the EGL 1.5 spec:
    *
    *    If eglSwapBuffers is called and the native window associated with
    *    surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
    *    generated.
    */
   if (surf->Lost)
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);

   ret = drv->SwapBuffers(drv, disp, surf);

   /* EGL_KHR_partial_update
    * Frame boundary successfully reached,
    * reset damage region and reset BufferAgeRead
    */
   if (ret) {
      surf->SetDamageRegionCalled = EGL_FALSE;
      surf->BufferAgeRead = EGL_FALSE;
   }

   RETURN_EGL_EVAL(disp, ret);
}


static EGLBoolean
_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
                                const EGLint *rects, EGLint n_rects)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);

   /* 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);

   if (surf->Type != EGL_WINDOW_BIT)
      RETURN_EGL_EVAL(disp, EGL_TRUE);

   if ((n_rects > 0 && rects == NULL) || n_rects < 0)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   ret = drv->SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);

   /* EGL_KHR_partial_update
    * Frame boundary successfully reached,
    * reset damage region and reset BufferAgeRead
    */
   if (ret) {
      surf->SetDamageRegionCalled = EGL_FALSE;
      surf->BufferAgeRead = EGL_FALSE;
   }

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
                            const EGLint *rects, EGLint n_rects)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
}

static EGLBoolean EGLAPIENTRY
eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
                            const EGLint *rects, EGLint n_rects)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
}

/**
 * Clamp the rectangles so that they lie within the surface.
 */

static void
_eglSetDamageRegionKHRClampRects(_EGLDisplay* disp, _EGLSurface* surf,
                                 EGLint *rects, EGLint n_rects)
{
   EGLint i;
   EGLint surf_height = surf->Height;
   EGLint surf_width = surf->Width;

   for (i = 0; i < (4 * n_rects); i += 4) {
      EGLint x1, y1, x2, y2;
      x1 = rects[i];
      y1 = rects[i + 1];
      x2 = rects[i + 2] + x1;
      y2 = rects[i + 3] + y1;

      rects[i] = CLAMP(x1, 0, surf_width);
      rects[i + 1] = CLAMP(y1, 0, surf_height);
      rects[i + 2] = CLAMP(x2, 0, surf_width) - rects[i];
      rects[i + 3] = CLAMP(y2, 0, surf_height) - rects[i + 1];
   }
}

static EGLBoolean EGLAPIENTRY
eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
                      EGLint *rects, EGLint n_rects)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   _EGLContext *ctx = _eglGetCurrentContext();
   const _EGLDriver *drv;
   EGLBoolean ret;
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);

   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
       surf->Type != EGL_WINDOW_BIT ||
       ctx->DrawSurface != surf ||
       surf->SwapBehavior != EGL_BUFFER_DESTROYED)
      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);

   /* If the damage region is already set or
    * buffer age is not queried between
    * frame boundaries, throw bad access error
    */

   if (surf->SetDamageRegionCalled || !surf->BufferAgeRead)
      RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);

   _eglSetDamageRegionKHRClampRects(disp, surf, rects, n_rects);
   ret = drv->SetDamageRegion(drv, disp, surf, rects, n_rects);

   if (ret)
      surf->SetDamageRegionCalled = EGL_TRUE;

   RETURN_EGL_EVAL(disp, ret);
}

EGLBoolean EGLAPIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;
   void *native_pixmap_ptr;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
   STATIC_ASSERT(sizeof(void*) == sizeof(target));
   native_pixmap_ptr = (void*) target;

   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
   ret = drv->CopyBuffers(drv, disp, surf, native_pixmap_ptr);

   RETURN_EGL_EVAL(disp, ret);
}


static EGLBoolean
_eglWaitClientCommon(void)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   _EGLDisplay *disp;
   const _EGLDriver *drv;
   EGLBoolean ret;

   if (!ctx)
      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);

   disp = ctx->Resource.Display;
   mtx_lock(&disp->Mutex);

   /* let bad current context imply bad current surface */
   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 */
   assert(disp->Initialized);
   drv = disp->Driver;
   ret = drv->WaitClient(drv, disp, ctx);

   RETURN_EGL_EVAL(disp, ret);
}

EGLBoolean EGLAPIENTRY
eglWaitClient(void)
{
   _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
   return _eglWaitClientCommon();
}

EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
   /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
   _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
   return _eglWaitClientCommon();
}


EGLBoolean EGLAPIENTRY
eglWaitNative(EGLint engine)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   _EGLDisplay *disp;
   const _EGLDriver *drv;
   EGLBoolean ret;

   if (!ctx)
      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);

   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);

   disp = ctx->Resource.Display;
   mtx_lock(&disp->Mutex);

   /* let bad current context imply bad current surface */
   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 */
   assert(disp->Initialized);
   drv = disp->Driver;
   ret = drv->WaitNative(drv, disp, engine);

   RETURN_EGL_EVAL(disp, ret);
}


EGLDisplay EGLAPIENTRY
eglGetCurrentDisplay(void)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   EGLDisplay ret;

   ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;

   RETURN_EGL_SUCCESS(NULL, ret);
}


EGLContext EGLAPIENTRY
eglGetCurrentContext(void)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   EGLContext ret;

   ret = _eglGetContextHandle(ctx);

   RETURN_EGL_SUCCESS(NULL, ret);
}


EGLSurface EGLAPIENTRY
eglGetCurrentSurface(EGLint readdraw)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   EGLint err = EGL_SUCCESS;
   _EGLSurface *surf;
   EGLSurface ret;

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);

   if (!ctx)
      RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);

   switch (readdraw) {
   case EGL_DRAW:
      surf = ctx->DrawSurface;
      break;
   case EGL_READ:
      surf = ctx->ReadSurface;
      break;
   default:
      surf = NULL;
      err = EGL_BAD_PARAMETER;
      break;
   }

   ret = _eglGetSurfaceHandle(surf);

   RETURN_EGL_ERROR(NULL, err, ret);
}


EGLint EGLAPIENTRY
eglGetError(void)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   EGLint e = t->LastError;
   if (!_eglIsCurrentThreadDummy())
      t->LastError = EGL_SUCCESS;
   return e;
}


/**
 ** EGL 1.2
 **/

/**
 * Specify the client API to use for subsequent calls including:
 *  eglCreateContext()
 *  eglGetCurrentContext()
 *  eglGetCurrentDisplay()
 *  eglGetCurrentSurface()
 *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
 *  eglWaitClient()
 *  eglWaitNative()
 * See section 3.7 "Rendering Context" in the EGL specification for details.
 */
EGLBoolean EGLAPIENTRY
eglBindAPI(EGLenum api)
{
   _EGLThreadInfo *t;

   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);

   t = _eglGetCurrentThread();
   if (_eglIsCurrentThreadDummy())
      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);

   if (!_eglIsApiValid(api))
      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);

   t->CurrentAPI = api;

   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
}


/**
 * Return the last value set with eglBindAPI().
 */
EGLenum EGLAPIENTRY
eglQueryAPI(void)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   EGLenum ret;

   /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
   ret = t->CurrentAPI;

   RETURN_EGL_SUCCESS(NULL, ret);
}


EGLSurface EGLAPIENTRY
eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
                                 EGLClientBuffer buffer, EGLConfig config,
                                 const EGLint *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLConfig *conf = _eglLookupConfig(config, disp);
   const _EGLDriver *drv;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);

   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);

   /* OpenVG is not supported */
   RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
}


EGLBoolean EGLAPIENTRY
eglReleaseThread(void)
{
   /* unbind current contexts */
   if (!_eglIsCurrentThreadDummy()) {
      _EGLThreadInfo *t = _eglGetCurrentThread();
      _EGLContext *ctx = t->CurrentContext;

      _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);

      if (ctx) {
         _EGLDisplay *disp = ctx->Resource.Display;
         const _EGLDriver *drv;

         mtx_lock(&disp->Mutex);
         drv = disp->Driver;
         (void) drv->MakeCurrent(drv, disp, NULL, NULL, NULL);
         mtx_unlock(&disp->Mutex);
      }
   }

   _eglDestroyCurrentThread();

   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
}


static EGLImage
_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
                      EGLClientBuffer buffer, const EGLint *attr_list)
{
   _EGLContext *context = _eglLookupContext(ctx, disp);
   const _EGLDriver *drv;
   _EGLImage *img;
   EGLImage 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);
   /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
    *  <ctx> must be EGL_NO_CONTEXT..."
    */
   if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);

   img = drv->CreateImageKHR(drv, disp, context, target,
                                 buffer, attr_list);
   ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;

   RETURN_EGL_EVAL(disp, ret);
}

static EGLImage EGLAPIENTRY
eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
                  EGLClientBuffer buffer, const EGLint *attr_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
   return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
}


EGLImage EGLAPIENTRY
eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
               EGLClientBuffer buffer, const EGLAttrib *attr_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   EGLImage image;
   EGLint *int_attribs;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);

   int_attribs = _eglConvertAttribsToInt(attr_list);
   if (attr_list && !int_attribs)
      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);

   image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
   free(int_attribs);
   return image;
}


static EGLBoolean
_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
{
   const _EGLDriver *drv;
   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);

   _eglUnlinkImage(img);
   ret = drv->DestroyImageKHR(drv, disp, img);

   RETURN_EGL_EVAL(disp, ret);
}

EGLBoolean EGLAPIENTRY
eglDestroyImage(EGLDisplay dpy, EGLImage image)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLImage *img = _eglLookupImage(image, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
   return _eglDestroyImageCommon(disp, img);
}

static EGLBoolean EGLAPIENTRY
eglDestroyImageKHR(EGLDisplay dpy, EGLImage image)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLImage *img = _eglLookupImage(image, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
   return _eglDestroyImageCommon(disp, img);
}


static EGLSync
_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
               EGLBoolean orig_is_EGLAttrib,
               EGLenum invalid_type_error)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   const _EGLDriver *drv;
   _EGLSync *sync;
   EGLSync ret;

   _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);

   if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
      /* There exist two EGLAttrib variants of eglCreateSync*:
       * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
       * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
       * support as a proxy for EGL 1.5 support, even though that's not
       * entirely correct (though _eglComputeVersion does the same).
       *
       * The EGL spec provides no guidance on how to handle unsupported
       * functions. EGL_BAD_MATCH seems reasonable.
       */
      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
   }

   /* If type is EGL_SYNC_FENCE and no context is current for the bound API
    * (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH
    * error is generated.
    */
   if (!ctx &&
       (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID))
      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);

   /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */
   if (ctx && (ctx->Resource.Display != disp ||
               (ctx->ClientAPI != EGL_OPENGL_ES_API &&
                ctx->ClientAPI != EGL_OPENGL_API)))
      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);

   switch (type) {
   case EGL_SYNC_FENCE_KHR:
      if (!disp->Extensions.KHR_fence_sync)
         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
      break;
   case EGL_SYNC_REUSABLE_KHR:
      if (!disp->Extensions.KHR_reusable_sync)
         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
      break;
   case EGL_SYNC_CL_EVENT_KHR:
      if (!disp->Extensions.KHR_cl_event2)
         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
      break;
   case EGL_SYNC_NATIVE_FENCE_ANDROID:
      if (!disp->Extensions.ANDROID_native_fence_sync)
         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
      break;
   default:
      RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
   }

   sync = drv->CreateSyncKHR(drv, disp, type, attrib_list);
   ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;

   RETURN_EGL_EVAL(disp, ret);
}


static EGLSync EGLAPIENTRY
eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   EGLSync sync;
   EGLAttrib *attrib_list;
   EGLint err;

   if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
      attrib_list = (EGLAttrib *) int_list;
   } else {
      err = _eglConvertIntsToAttribs(int_list, &attrib_list);
      if (err != EGL_SUCCESS)
         RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
   }

   sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
                         EGL_BAD_ATTRIBUTE);

   if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
      free(attrib_list);

   /* Don't double-unlock the display. _eglCreateSync already unlocked it. */
   return sync;
}


static EGLSync EGLAPIENTRY
eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
   return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
                         EGL_BAD_ATTRIBUTE);
}


EGLSync EGLAPIENTRY
eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
   return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
                         EGL_BAD_PARAMETER);
}


static EGLBoolean
_eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
{
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
   assert(disp->Extensions.KHR_reusable_sync ||
          disp->Extensions.KHR_fence_sync ||
          disp->Extensions.ANDROID_native_fence_sync);

   _eglUnlinkSync(s);
   ret = drv->DestroySyncKHR(drv, disp, s);

   RETURN_EGL_EVAL(disp, ret);
}

EGLBoolean EGLAPIENTRY
eglDestroySync(EGLDisplay dpy, EGLSync sync)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
   return _eglDestroySync(disp, s);
}

static EGLBoolean EGLAPIENTRY
eglDestroySyncKHR(EGLDisplay dpy, EGLSync sync)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
   return _eglDestroySync(disp, s);
}


static EGLint
_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
                         _EGLSync *s, EGLint flags, EGLTime timeout)
{
   const _EGLDriver *drv;
   EGLint ret;

   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
   assert(disp->Extensions.KHR_reusable_sync ||
          disp->Extensions.KHR_fence_sync ||
          disp->Extensions.ANDROID_native_fence_sync);

   if (s->SyncStatus == EGL_SIGNALED_KHR)
      RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);

   /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
    * unlocked here to allow other threads also to be able to
    * go into waiting state.
    */

   if (s->Type == EGL_SYNC_REUSABLE_KHR)
      _eglUnlockDisplay(dpy);

   ret = drv->ClientWaitSyncKHR(drv, disp, s, flags, timeout);

   /*
    * 'disp' is already unlocked for reusable sync type,
    * so passing 'NULL' to bypass unlocking display.
    */
   if (s->Type == EGL_SYNC_REUSABLE_KHR)
      RETURN_EGL_EVAL(NULL, ret);
   else
      RETURN_EGL_EVAL(disp, ret);
}

EGLint EGLAPIENTRY
eglClientWaitSync(EGLDisplay dpy, EGLSync sync,
                  EGLint flags, EGLTime timeout)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
   return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
}

static EGLint EGLAPIENTRY
eglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync,
                     EGLint flags, EGLTime timeout)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
   return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
}


static EGLint
_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   const _EGLDriver *drv;
   EGLint ret;

   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
   assert(disp->Extensions.KHR_wait_sync);

   /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */
   if (ctx == EGL_NO_CONTEXT ||
         (ctx->ClientAPI != EGL_OPENGL_ES_API &&
          ctx->ClientAPI != EGL_OPENGL_API))
      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);

   /* the API doesn't allow any flags yet */
   if (flags != 0)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   ret = drv->WaitSyncKHR(drv, disp, s);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLint EGLAPIENTRY
eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
   return _eglWaitSyncCommon(disp, s, flags);
}


EGLBoolean EGLAPIENTRY
eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
{
   /* The KHR version returns EGLint, while the core version returns
    * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
    * EGL_TRUE.
    */
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
   return _eglWaitSyncCommon(disp, s, flags);
}


static EGLBoolean EGLAPIENTRY
eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);

   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
   assert(disp->Extensions.KHR_reusable_sync);
   ret = drv->SignalSyncKHR(drv, disp, s, mode);

   RETURN_EGL_EVAL(disp, ret);
}


static EGLBoolean
_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
{
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
   assert(disp->Extensions.KHR_reusable_sync ||
          disp->Extensions.KHR_fence_sync ||
          disp->Extensions.ANDROID_native_fence_sync);

   ret = _eglGetSyncAttrib(drv, disp, s, attribute, value);

   RETURN_EGL_EVAL(disp, ret);
}

EGLBoolean EGLAPIENTRY
eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);

   if (!value)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   return _eglGetSyncAttribCommon(disp, s, attribute, value);
}


static EGLBoolean EGLAPIENTRY
eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   EGLAttrib attrib;
   EGLBoolean result;

   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);

   if (!value)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   attrib = *value;
   result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);

   /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
    *
    *    If any error occurs, <*value> is not modified.
    */
   if (result == EGL_FALSE)
      return result;

   *value = attrib;
   return result;
}

static EGLint EGLAPIENTRY
eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSync *s = _eglLookupSync(sync, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);

   /* the spec doesn't seem to specify what happens if the fence
    * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems
    * sensible:
    */
   if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)))
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID);

   _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID, drv);
   assert(disp->Extensions.ANDROID_native_fence_sync);
   ret = drv->DupNativeFenceFDANDROID(drv, disp, s);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
                        EGLint numRects, const EGLint *rects)
{
   _EGLContext *ctx = _eglGetCurrentContext();
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);

   _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->SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);

   RETURN_EGL_EVAL(disp, ret);
}


static EGLImage EGLAPIENTRY
eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;
   _EGLImage *img;
   EGLImage ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   _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->CreateDRMImageMESA(drv, disp, attr_list);
   ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
                      EGLint *name, EGLint *handle, EGLint *stride)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLImage *img = _eglLookupImage(image, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);

   _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->ExportDRMImageMESA(drv, disp, img, name, handle, stride);

   RETURN_EGL_EVAL(disp, ret);
}


struct wl_display;

static EGLBoolean EGLAPIENTRY
eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   _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->BindWaylandDisplayWL(drv, disp, display);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   _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->UnbindWaylandDisplayWL(drv, disp, display);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
                        EGLint attribute, EGLint *value)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
   assert(disp->Extensions.WL_bind_wayland_display);

   if (!buffer)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   ret = drv->QueryWaylandBufferWL(drv, disp, buffer, attribute, value);

   RETURN_EGL_EVAL(disp, ret);
}


static struct wl_buffer * EGLAPIENTRY
eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLImage *img;
   const _EGLDriver *drv;
   struct wl_buffer *ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);

   _EGL_CHECK_DISPLAY(disp, NULL, drv);
   if (!disp->Extensions.WL_create_wayland_buffer_from_image)
      RETURN_EGL_EVAL(disp, NULL);

   img = _eglLookupImage(image, disp);

   if (!img)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);

   ret = drv->CreateWaylandBufferFromImageWL(drv, disp, img);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
                   EGLint x, EGLint y, EGLint width, EGLint height)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);

   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);

   if (!disp->Extensions.NV_post_sub_buffer)
      RETURN_EGL_EVAL(disp, EGL_FALSE);

   ret = drv->PostSubBufferNV(drv, disp, surf, x, y, width, height);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglGetSyncValuesCHROMIUM(EGLDisplay dpy, EGLSurface surface,
                         EGLuint64KHR *ust, EGLuint64KHR *msc,
                         EGLuint64KHR *sbc)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);

   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
   if (!disp->Extensions.CHROMIUM_sync_control)
      RETURN_EGL_EVAL(disp, EGL_FALSE);

   if (!ust || !msc || !sbc)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   ret = drv->GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
                              EGLint *fourcc, EGLint *nplanes,
                              EGLuint64KHR *modifiers)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLImage *img = _eglLookupImage(image, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);

   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
   assert(disp->Extensions.MESA_image_dma_buf_export);

   if (!img)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   ret = drv->ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
                                             modifiers);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
                         int *fds, EGLint *strides, EGLint *offsets)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   _EGLImage *img = _eglLookupImage(image, disp);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);

   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
   assert(disp->Extensions.MESA_image_dma_buf_export);

   if (!img)
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);

   ret = drv->ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLint EGLAPIENTRY
eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
                  EGLLabelKHR label)
{
   _EGLDisplay *disp = NULL;
   _EGLResourceType type;

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);

   if (objectType == EGL_OBJECT_THREAD_KHR) {
      _EGLThreadInfo *t = _eglGetCurrentThread();

      if (!_eglIsCurrentThreadDummy()) {
         t->Label = label;
         return EGL_SUCCESS;
      }

      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC);
   }

   disp = _eglLockDisplay(dpy);
   if (disp == NULL)
      RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);

   if (objectType == EGL_OBJECT_DISPLAY_KHR) {
      if (dpy != (EGLDisplay) object)
         RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);

      disp->Label = label;
      RETURN_EGL_EVAL(disp, EGL_SUCCESS);
   }

   switch (objectType) {
      case EGL_OBJECT_CONTEXT_KHR:
         type = _EGL_RESOURCE_CONTEXT;
         break;
      case EGL_OBJECT_SURFACE_KHR:
         type = _EGL_RESOURCE_SURFACE;
         break;
      case EGL_OBJECT_IMAGE_KHR:
         type = _EGL_RESOURCE_IMAGE;
         break;
      case EGL_OBJECT_SYNC_KHR:
         type = _EGL_RESOURCE_SYNC;
         break;
      case EGL_OBJECT_STREAM_KHR:
      default:
         RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
   }

   if (_eglCheckResource(object, type, disp)) {
      _EGLResource *res = (_EGLResource *) object;

      res->Label = label;
      RETURN_EGL_EVAL(disp, EGL_SUCCESS);
   }

   RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
}

static EGLint EGLAPIENTRY
eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
                          const EGLAttrib *attrib_list)
{
   unsigned int newEnabled;

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);

   mtx_lock(_eglGlobal.Mutex);

   newEnabled = _eglGlobal.debugTypesEnabled;
   if (attrib_list != NULL) {
      int i;

      for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
         switch (attrib_list[i]) {
         case EGL_DEBUG_MSG_CRITICAL_KHR:
         case EGL_DEBUG_MSG_ERROR_KHR:
         case EGL_DEBUG_MSG_WARN_KHR:
         case EGL_DEBUG_MSG_INFO_KHR:
            if (attrib_list[i + 1])
               newEnabled |= DebugBitFromType(attrib_list[i]);
            else
               newEnabled &= ~DebugBitFromType(attrib_list[i]);
            break;
         default:
            // On error, set the last error code, call the current
            // debug callback, and return the error code.
            mtx_unlock(_eglGlobal.Mutex);
            _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
                  "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
            return EGL_BAD_ATTRIBUTE;
         }
      }
   }

   if (callback != NULL) {
      _eglGlobal.debugCallback = callback;
      _eglGlobal.debugTypesEnabled = newEnabled;
   } else {
      _eglGlobal.debugCallback = NULL;
      _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
   }

   mtx_unlock(_eglGlobal.Mutex);
   return EGL_SUCCESS;
}

static EGLBoolean EGLAPIENTRY
eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
{
   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);

   mtx_lock(_eglGlobal.Mutex);

   switch (attribute) {
   case EGL_DEBUG_MSG_CRITICAL_KHR:
   case EGL_DEBUG_MSG_ERROR_KHR:
   case EGL_DEBUG_MSG_WARN_KHR:
   case EGL_DEBUG_MSG_INFO_KHR:
      if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
         *value = EGL_TRUE;
      else
         *value = EGL_FALSE;
      break;
   case EGL_DEBUG_CALLBACK_KHR:
      *value = (EGLAttrib) _eglGlobal.debugCallback;
      break;
   default:
      mtx_unlock(_eglGlobal.Mutex);
      _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
                      "Invalid attribute 0x%04lx", (unsigned long) attribute);
      return EGL_FALSE;
   }

   mtx_unlock(_eglGlobal.Mutex);
   return EGL_TRUE;
}

static int
_eglFunctionCompare(const void *key, const void *elem)
{
   const char *procname = key;
   const struct _egl_entrypoint *entrypoint = elem;
   return strcmp(procname, entrypoint->name);
}

static EGLBoolean EGLAPIENTRY
eglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats,
                         EGLint *formats, EGLint *num_formats)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);

   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);

   ret = drv->QueryDmaBufFormatsEXT(drv, disp, max_formats, formats,
                                        num_formats);

   RETURN_EGL_EVAL(disp, ret);
}

static EGLBoolean EGLAPIENTRY
eglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers,
                           EGLuint64KHR *modifiers, EGLBoolean *external_only,
                           EGLint *num_modifiers)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;
   EGLBoolean ret;

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);

   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);

   ret = drv->QueryDmaBufModifiersEXT(drv, disp, format, max_modifiers,
                                          modifiers, external_only,
                                          num_modifiers);

   RETURN_EGL_EVAL(disp, ret);
}

static void EGLAPIENTRY
eglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set,
                            EGLGetBlobFuncANDROID get)
{
   /* This function does not return anything so we cannot
    * utilize the helper macros _EGL_FUNC_START or _EGL_CHECK_DISPLAY.
    */
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   if (!_eglSetFuncName(__func__, disp, EGL_OBJECT_DISPLAY_KHR, NULL)) {
      if (disp)
         _eglUnlockDisplay(disp);
      return;
   }

   const _EGLDriver *drv = _eglCheckDisplay(disp, __func__);
   if (!drv) {
      if (disp)
         _eglUnlockDisplay(disp);
      return;
   }

   if (!set || !get) {
      _eglError(EGL_BAD_PARAMETER,
                "eglSetBlobCacheFuncsANDROID: NULL handler given");
      _eglUnlockDisplay(disp);
      return;
   }

   if (disp->BlobCacheSet) {
      _eglError(EGL_BAD_PARAMETER,
                "eglSetBlobCacheFuncsANDROID: functions already set");
      _eglUnlockDisplay(disp);
      return;
   }

   disp->BlobCacheSet = set;
   disp->BlobCacheGet = get;

   drv->SetBlobCacheFuncsANDROID(drv, disp, set, get);

   _eglUnlockDisplay(disp);
}

static EGLBoolean EGLAPIENTRY
eglQueryDeviceAttribEXT(EGLDeviceEXT device,
                        EGLint attribute,
                        EGLAttrib *value)
{
   _EGLDevice *dev = _eglLookupDevice(device);
   EGLBoolean ret;

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
   if (!dev)
      RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, EGL_FALSE);

   ret = _eglQueryDeviceAttribEXT(dev, attribute, value);
   RETURN_EGL_EVAL(NULL, ret);
}

static const char * EGLAPIENTRY
eglQueryDeviceStringEXT(EGLDeviceEXT device,
                        EGLint name)
{
   _EGLDevice *dev = _eglLookupDevice(device);

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
   if (!dev)
      RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, NULL);

   RETURN_EGL_EVAL(NULL, _eglQueryDeviceStringEXT(dev, name));
}

static EGLBoolean EGLAPIENTRY
eglQueryDevicesEXT(EGLint max_devices,
                   EGLDeviceEXT *devices,
                   EGLint *num_devices)
{
   EGLBoolean ret;

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
   ret = _eglQueryDevicesEXT(max_devices, (_EGLDevice **) devices,
                             num_devices);
   RETURN_EGL_EVAL(NULL, ret);
}

static EGLBoolean EGLAPIENTRY
eglQueryDisplayAttribEXT(EGLDisplay dpy,
                         EGLint attribute,
                         EGLAttrib *value)
{
   _EGLDisplay *disp = _eglLockDisplay(dpy);
   const _EGLDriver *drv;

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);

   switch (attribute) {
   case EGL_DEVICE_EXT:
      *value = (EGLAttrib) disp->Device;
      break;
   default:
      RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_FALSE);
   }
   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
}

static char * EGLAPIENTRY
eglGetDisplayDriverConfig(EGLDisplay dpy)
{
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    const _EGLDriver *drv;
    char *ret;

    _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
    _EGL_CHECK_DISPLAY(disp, NULL, drv);

    assert(disp->Extensions.MESA_query_driver);

    ret = drv->QueryDriverConfig(disp);
    RETURN_EGL_EVAL(disp, ret);
}

static const char * EGLAPIENTRY
eglGetDisplayDriverName(EGLDisplay dpy)
{
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    const _EGLDriver *drv;
    const char *ret;

    _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
    _EGL_CHECK_DISPLAY(disp, NULL, drv);

    assert(disp->Extensions.MESA_query_driver);

    ret = drv->QueryDriverName(disp);
    RETURN_EGL_EVAL(disp, ret);
}

__eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname)
{
   static const struct _egl_entrypoint egl_functions[] = {
#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f },
#include "eglentrypoint.h"
#undef EGL_ENTRYPOINT
   };
   _EGLProc ret = NULL;

   if (!procname)
      RETURN_EGL_SUCCESS(NULL, NULL);

   _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);

   if (strncmp(procname, "egl", 3) == 0) {
      const struct _egl_entrypoint *entrypoint =
         bsearch(procname,
                 egl_functions, ARRAY_SIZE(egl_functions),
                 sizeof(egl_functions[0]),
                 _eglFunctionCompare);
      if (entrypoint)
         ret = entrypoint->function;
   }

   if (!ret)
      ret = _eglGetDriverProc(procname);

   RETURN_EGL_SUCCESS(NULL, ret);
}

static int
_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
                       _EGLDisplay **disp, const _EGLDriver **drv,
                       _EGLContext **ctx)
{

   *disp = _eglLockDisplay(dpy);
   if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
      if (*disp)
         _eglUnlockDisplay(*disp);
      return MESA_GLINTEROP_INVALID_DISPLAY;
   }

   *drv = (*disp)->Driver;

   *ctx = _eglLookupContext(context, *disp);
   if (!*ctx ||
       ((*ctx)->ClientAPI != EGL_OPENGL_API &&
        (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
      _eglUnlockDisplay(*disp);
      return MESA_GLINTEROP_INVALID_CONTEXT;
   }

   return MESA_GLINTEROP_SUCCESS;
}

PUBLIC int
MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
                                struct mesa_glinterop_device_info *out)
{
   _EGLDisplay *disp;
   const _EGLDriver *drv;
   _EGLContext *ctx;
   int ret;

   ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
   if (ret != MESA_GLINTEROP_SUCCESS)
      return ret;

   if (drv->GLInteropQueryDeviceInfo)
      ret = drv->GLInteropQueryDeviceInfo(disp, ctx, out);
   else
      ret = MESA_GLINTEROP_UNSUPPORTED;

   _eglUnlockDisplay(disp);
   return ret;
}

PUBLIC int
MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
                             struct mesa_glinterop_export_in *in,
                             struct mesa_glinterop_export_out *out)
{
   _EGLDisplay *disp;
   const _EGLDriver *drv;
   _EGLContext *ctx;
   int ret;

   ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
   if (ret != MESA_GLINTEROP_SUCCESS)
      return ret;

   if (drv->GLInteropExportObject)
      ret = drv->GLInteropExportObject(disp, ctx, in, out);
   else
      ret = MESA_GLINTEROP_UNSUPPORTED;

   _eglUnlockDisplay(disp);
   return ret;
}
