/**************************************************************************
 *
 * 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) {
      disp->Driver->Terminate(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;
}
