egl: use coherent variable names
[mesa.git] / src / egl / main / eglapi.c
index 6c9033399870df2e4a08d7f2f32dcf89212ce510..f99078febb3958f13c5e97127fb8cbf2e4eed4da 100644 (file)
 #include <string.h>
 #include "c99_compat.h"
 #include "c11/threads.h"
-#include "GL/mesa_glinterop.h"
-#include "eglcompiler.h"
+#include "util/macros.h"
 
+#include "eglapi.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.
    _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
 
 
+struct _egl_entrypoint {
+   const char *name;
+   _EGLProc function;
+};
+
+
 static inline _EGLDriver *
 _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
 {
@@ -232,12 +241,12 @@ _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
  * Lookup and lock a display.
  */
 static inline _EGLDisplay *
-_eglLockDisplay(EGLDisplay display)
+_eglLockDisplay(EGLDisplay dpy)
 {
-   _EGLDisplay *dpy = _eglLookupDisplay(display);
-   if (dpy)
-      mtx_lock(&dpy->Mutex);
-   return dpy;
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   if (disp)
+      mtx_lock(&disp->Mutex);
+   return disp;
 }
 
 
@@ -245,9 +254,9 @@ _eglLockDisplay(EGLDisplay display)
  * Unlock a display.
  */
 static inline void
-_eglUnlockDisplay(_EGLDisplay *dpy)
+_eglUnlockDisplay(_EGLDisplay *disp)
 {
-   mtx_unlock(&dpy->Mutex);
+   mtx_unlock(&disp->Mutex);
 }
 
 static EGLBoolean
@@ -268,8 +277,7 @@ _eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EG
       return EGL_TRUE;
    }
 
-   _eglDebugReportFull(EGL_BAD_ALLOC, funcName, funcName,
-                      EGL_DEBUG_MSG_CRITICAL_KHR, NULL, NULL);
+   _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL);
    return EGL_FALSE;
 }
 
@@ -356,7 +364,7 @@ EGLDisplay EGLAPIENTRY
 eglGetDisplay(EGLNativeDisplayType nativeDisplay)
 {
    _EGLPlatformType plat;
-   _EGLDisplay *dpy;
+   _EGLDisplay *disp;
    void *native_display_ptr;
 
    _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
@@ -365,70 +373,69 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
    native_display_ptr = (void*) nativeDisplay;
 
    plat = _eglGetNativePlatform(native_display_ptr);
-   dpy = _eglFindDisplay(plat, native_display_ptr);
-   return _eglGetDisplayHandle(dpy);
+   disp = _eglFindDisplay(plat, native_display_ptr);
+   return _eglGetDisplayHandle(disp);
 }
 
 static EGLDisplay
 _eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
-                            const EGLint *attrib_list)
+                             const EGLAttrib *attrib_list)
 {
-   _EGLDisplay *dpy;
+   _EGLDisplay *disp;
 
    switch (platform) {
 #ifdef HAVE_X11_PLATFORM
    case EGL_PLATFORM_X11_EXT:
-      dpy = _eglGetX11Display((Display*) native_display, attrib_list);
+      disp = _eglGetX11Display((Display*) native_display, attrib_list);
       break;
 #endif
 #ifdef HAVE_DRM_PLATFORM
    case EGL_PLATFORM_GBM_MESA:
-      dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
+      disp = _eglGetGbmDisplay((struct gbm_device*) native_display,
                               attrib_list);
       break;
 #endif
 #ifdef HAVE_WAYLAND_PLATFORM
    case EGL_PLATFORM_WAYLAND_EXT:
-      dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
+      disp = _eglGetWaylandDisplay((struct wl_display*) native_display,
                                   attrib_list);
       break;
 #endif
 #ifdef HAVE_SURFACELESS_PLATFORM
    case EGL_PLATFORM_SURFACELESS_MESA:
-      dpy = _eglGetSurfacelessDisplay(native_display, attrib_list);
+      disp = _eglGetSurfacelessDisplay(native_display, attrib_list);
       break;
 #endif
    default:
       RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
    }
 
-   return _eglGetDisplayHandle(dpy);
+   return _eglGetDisplayHandle(disp);
 }
 
 static EGLDisplay EGLAPIENTRY
 eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
-                         const EGLint *attrib_list)
+                         const EGLint *int_attribs)
 {
+   EGLAttrib *attrib_list;
+   EGLDisplay disp;
+
    _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
-   return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
+
+   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)
 {
-   EGLDisplay display;
-   EGLint *int_attribs;
-
    _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
-
-   int_attribs = _eglConvertAttribsToInt(attrib_list);
-   if (attrib_list && !int_attribs)
-      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
-
-   display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs);
-   free(int_attribs);
-   return display;
+   return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
 }
 
 /**
@@ -459,19 +466,20 @@ _eglAppendExtension(char **str, const char *ext)
  * the driver's Extensions string.
  */
 static void
-_eglCreateExtensionsString(_EGLDisplay *dpy)
+_eglCreateExtensionsString(_EGLDisplay *disp)
 {
 #define _EGL_CHECK_EXTENSION(ext)                                          \
    do {                                                                    \
-      if (dpy->Extensions.ext) {                                           \
+      if (disp->Extensions.ext) {                                           \
          _eglAppendExtension(&exts, "EGL_" #ext);                          \
-         assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN);  \
+         assert(exts <= disp->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN);  \
       }                                                                    \
    } while (0)
 
-   char *exts = dpy->ExtensionsString;
+   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);
@@ -482,11 +490,18 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
    _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);
@@ -494,21 +509,26 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
    _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 (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
-      _eglAppendExtension(&exts, "EGL_KHR_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 (dpy->Extensions.EXT_swap_buffers_with_damage)
+   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 (dpy->Extensions.KHR_no_config_context)
+   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);
@@ -522,21 +542,32 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
 }
 
 static void
-_eglCreateAPIsString(_EGLDisplay *dpy)
-{
-   if (dpy->ClientAPIs & EGL_OPENGL_BIT)
-      strcat(dpy->ClientAPIsString, "OpenGL ");
+_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 (dpy->ClientAPIs & EGL_OPENGL_ES_BIT ||
-       dpy->ClientAPIs & EGL_OPENGL_ES2_BIT ||
-       dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
-      strcat(dpy->ClientAPIsString, "OpenGL_ES ");
+   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 (dpy->ClientAPIs & EGL_OPENVG_BIT)
-      strcat(dpy->ClientAPIsString, "OpenVG ");
+   if (disp->ClientAPIs & EGL_OPENVG_BIT)
+      addstr("OpenVG");
 
-   assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
+#undef addstr
 }
 
 static void
@@ -575,7 +606,7 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
 
    if (!disp->Initialized) {
-      if (!_eglMatchDriver(disp, EGL_FALSE))
+      if (!_eglMatchDriver(disp))
          RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
 
       /* limit to APIs supported by core */
@@ -607,8 +638,7 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       _eglCreateExtensionsString(disp);
       _eglCreateAPIsString(disp);
       snprintf(disp->VersionString, sizeof(disp->VersionString),
-              "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
-              disp->Driver->Name);
+               "%d.%d", disp->Version / 10, disp->Version % 10);
    }
 
    /* Update applications version of major and minor if not NULL */
@@ -651,7 +681,11 @@ eglQueryString(EGLDisplay dpy, EGLint name)
    _EGLDriver *drv;
 
    if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
-      RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
+      const char *ret = _eglGetClientExtensionString();
+      if (ret != NULL)
+         RETURN_EGL_SUCCESS(NULL, ret);
+      else
+         RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
    }
 
    disp = _eglLockDisplay(dpy);
@@ -702,7 +736,7 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
 
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
-                                config_size, num_config);
+                               config_size, num_config);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -818,6 +852,14 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
          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->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
 
    RETURN_EGL_EVAL(disp, ret);
@@ -902,7 +944,7 @@ static void *
 _fixupNativeWindow(_EGLDisplay *disp, void *native_window)
 {
 #ifdef HAVE_X11_PLATFORM
-   if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
+   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
@@ -957,14 +999,14 @@ 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->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
+   /* 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;
@@ -1000,6 +1042,9 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
    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);
+
    surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
                                        attrib_list);
    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
@@ -1017,13 +1062,13 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
    _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);
+                                        attrib_list);
 }
 
 static EGLSurface EGLAPIENTRY
 eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
-                                   void *native_pixmap,
-                                   const EGLint *attrib_list)
+                                  void *native_pixmap,
+                                  const EGLint *attrib_list)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
 
@@ -1180,7 +1225,20 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
    if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
 
-   ret = drv->API.SwapInterval(drv, disp, surf, interval);
+   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)
+      ret = drv->API.SwapInterval(drv, disp, surf, interval);
+   else
+      ret = EGL_TRUE;
+
+   if (ret)
+      surf->SwapInterval = interval;
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1205,8 +1263,29 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
       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->API.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);
 }
 
@@ -1226,11 +1305,23 @@ _eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
        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->API.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);
 }
 
@@ -1254,6 +1345,67 @@ eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
    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();
+   _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->API.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)
 {
@@ -1268,8 +1420,6 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
    native_pixmap_ptr = (void*) target;
 
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
-   if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
-      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
    ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
 
    RETURN_EGL_EVAL(disp, ret);
@@ -1519,7 +1669,7 @@ eglReleaseThread(void)
 
 static EGLImage
 _eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
-                  EGLClientBuffer buffer, const EGLint *attr_list)
+                      EGLClientBuffer buffer, const EGLint *attr_list)
 {
    _EGLContext *context = _eglLookupContext(ctx, disp);
    _EGLDriver *drv;
@@ -1537,8 +1687,8 @@ _eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
    if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
 
-   img = drv->API.CreateImageKHR(drv,
-         disp, context, target, buffer, attr_list);
+   img = drv->API.CreateImageKHR(drv, disp, context, target,
+                                 buffer, attr_list);
    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -1646,7 +1796,7 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
 
    /* return an error if the client API doesn't support GL_OES_EGL_sync */
    if (ctx && (ctx->Resource.Display != disp ||
-       ctx->ClientAPI != EGL_OPENGL_ES_API))
+               ctx->ClientAPI != EGL_OPENGL_ES_API))
       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
 
    switch (type) {
@@ -1961,7 +2111,7 @@ eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
 
 static EGLBoolean EGLAPIENTRY
 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
-                       EGLint numRects, const EGLint *rects)
+                        EGLint numRects, const EGLint *rects)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -2009,7 +2159,7 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
 
 static EGLBoolean EGLAPIENTRY
 eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
-                     EGLint *name, EGLint *handle, EGLint *stride)
+                      EGLint *name, EGLint *handle, EGLint *stride)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img = _eglLookupImage(image, disp);
@@ -2105,7 +2255,8 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
 
    _EGL_CHECK_DISPLAY(disp, NULL, drv);
-   assert(disp->Extensions.WL_create_wayland_buffer_from_image);
+   if (!disp->Extensions.WL_create_wayland_buffer_from_image)
+      RETURN_EGL_EVAL(disp, NULL);
 
    img = _eglLookupImage(image, disp);
 
@@ -2139,11 +2290,11 @@ eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
 }
 
 static EGLBoolean EGLAPIENTRY
-eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
+eglGetSyncValuesCHROMIUM(EGLDisplay dpy, EGLSurface surface,
                          EGLuint64KHR *ust, EGLuint64KHR *msc,
                          EGLuint64KHR *sbc)
 {
-   _EGLDisplay *disp = _eglLockDisplay(display);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
    _EGLDriver *drv;
    EGLBoolean ret;
@@ -2210,7 +2361,7 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
 
 static EGLint EGLAPIENTRY
 eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
-                 EGLLabelKHR label)
+                  EGLLabelKHR label)
 {
    _EGLDisplay *disp = NULL;
    _EGLResourceType type;
@@ -2268,16 +2419,9 @@ eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
    RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
 }
 
-static EGLBoolean
-_validDebugMessageLevel(EGLAttrib level)
-{
-   return (level >= EGL_DEBUG_MSG_CRITICAL_KHR &&
-           level <= EGL_DEBUG_MSG_INFO_KHR);
-}
-
 static EGLint EGLAPIENTRY
 eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
-                         const EGLAttrib *attrib_list)
+                          const EGLAttrib *attrib_list)
 {
    unsigned int newEnabled;
 
@@ -2290,20 +2434,24 @@ eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
       int i;
 
       for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
-         if (_validDebugMessageLevel(attrib_list[i])) {
+         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]);
-            continue;
+            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;
          }
-
-         // 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;
       }
    }
 
@@ -2326,134 +2474,239 @@ eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
 
    mtx_lock(_eglGlobal.Mutex);
 
-   do {
-      if (_validDebugMessageLevel(attribute)) {
-         if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
-            *value = EGL_TRUE;
-         else
-            *value = EGL_FALSE;
-         break;
-      }
-
-      if (attribute == EGL_DEBUG_CALLBACK_KHR) {
-         *value = (EGLAttrib) _eglGlobal.debugCallback;
-         break;
-      }
-
+   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);
+                      "Invalid attribute 0x%04lx", (unsigned long) attribute);
       return EGL_FALSE;
-   } while (0);
+   }
 
    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);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
+
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+   ret = drv->API.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);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
+
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+   ret = drv->API.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;
+   }
+
+   _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->API.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);
+   _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);
+    _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->API.QueryDriverConfig(disp);
+    RETURN_EGL_EVAL(disp, ret);
+}
+
+static const char * EGLAPIENTRY
+eglGetDisplayDriverName(EGLDisplay dpy)
+{
+    _EGLDisplay *disp = _eglLockDisplay(dpy);
+    _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->API.QueryDriverName(disp);
+    RETURN_EGL_EVAL(disp, ret);
+}
+
 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
 eglGetProcAddress(const char *procname)
 {
-   static const struct {
-      const char *name;
-      _EGLProc function;
-   } egl_functions[] = {
+   static const struct _egl_entrypoint egl_functions[] = {
 #define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f },
-      /* core functions queryable in the presence of
-       * EGL_KHR_get_all_proc_addresses or EGL 1.5
-       */
-      /* alphabetical order */
-      EGL_ENTRYPOINT(eglBindAPI)
-      EGL_ENTRYPOINT(eglBindTexImage)
-      EGL_ENTRYPOINT(eglChooseConfig)
-      EGL_ENTRYPOINT(eglCopyBuffers)
-      EGL_ENTRYPOINT(eglCreateContext)
-      EGL_ENTRYPOINT(eglCreatePbufferFromClientBuffer)
-      EGL_ENTRYPOINT(eglCreatePbufferSurface)
-      EGL_ENTRYPOINT(eglCreatePixmapSurface)
-      EGL_ENTRYPOINT(eglCreateWindowSurface)
-      EGL_ENTRYPOINT(eglDestroyContext)
-      EGL_ENTRYPOINT(eglDestroySurface)
-      EGL_ENTRYPOINT(eglGetConfigAttrib)
-      EGL_ENTRYPOINT(eglGetConfigs)
-      EGL_ENTRYPOINT(eglGetCurrentContext)
-      EGL_ENTRYPOINT(eglGetCurrentDisplay)
-      EGL_ENTRYPOINT(eglGetCurrentSurface)
-      EGL_ENTRYPOINT(eglGetDisplay)
-      EGL_ENTRYPOINT(eglGetError)
-      EGL_ENTRYPOINT(eglGetProcAddress)
-      EGL_ENTRYPOINT(eglInitialize)
-      EGL_ENTRYPOINT(eglMakeCurrent)
-      EGL_ENTRYPOINT(eglQueryAPI)
-      EGL_ENTRYPOINT(eglQueryContext)
-      EGL_ENTRYPOINT(eglQueryString)
-      EGL_ENTRYPOINT(eglQuerySurface)
-      EGL_ENTRYPOINT(eglReleaseTexImage)
-      EGL_ENTRYPOINT(eglReleaseThread)
-      EGL_ENTRYPOINT(eglSurfaceAttrib)
-      EGL_ENTRYPOINT(eglSwapBuffers)
-      EGL_ENTRYPOINT(eglSwapInterval)
-      EGL_ENTRYPOINT(eglTerminate)
-      EGL_ENTRYPOINT(eglWaitClient)
-      EGL_ENTRYPOINT(eglWaitGL)
-      EGL_ENTRYPOINT(eglWaitNative)
-      EGL_ENTRYPOINT(eglCreateSync)
-      EGL_ENTRYPOINT(eglDestroySync)
-      EGL_ENTRYPOINT(eglClientWaitSync)
-      EGL_ENTRYPOINT(eglGetSyncAttrib)
-      EGL_ENTRYPOINT(eglWaitSync)
-      EGL_ENTRYPOINT(eglCreateImage)
-      EGL_ENTRYPOINT(eglDestroyImage)
-      EGL_ENTRYPOINT(eglGetPlatformDisplay)
-      EGL_ENTRYPOINT(eglCreatePlatformWindowSurface)
-      EGL_ENTRYPOINT(eglCreatePlatformPixmapSurface)
-      EGL_ENTRYPOINT(eglCreateImageKHR)
-      EGL_ENTRYPOINT(eglDestroyImageKHR)
-      EGL_ENTRYPOINT(eglCreateSyncKHR)
-      EGL_ENTRYPOINT(eglCreateSync64KHR)
-      EGL_ENTRYPOINT(eglDestroySyncKHR)
-      EGL_ENTRYPOINT(eglClientWaitSyncKHR)
-      EGL_ENTRYPOINT(eglWaitSyncKHR)
-      EGL_ENTRYPOINT(eglSignalSyncKHR)
-      EGL_ENTRYPOINT(eglGetSyncAttribKHR)
-      EGL_ENTRYPOINT(eglSwapBuffersRegionNOK)
-      EGL_ENTRYPOINT(eglCreateDRMImageMESA)
-      EGL_ENTRYPOINT(eglExportDRMImageMESA)
-      EGL_ENTRYPOINT(eglBindWaylandDisplayWL)
-      EGL_ENTRYPOINT(eglUnbindWaylandDisplayWL)
-      EGL_ENTRYPOINT(eglQueryWaylandBufferWL)
-      EGL_ENTRYPOINT(eglCreateWaylandBufferFromImageWL)
-      EGL_ENTRYPOINT(eglPostSubBufferNV)
-      EGL_ENTRYPOINT(eglSwapBuffersWithDamageEXT)
-      EGL_ENTRYPOINT(eglSwapBuffersWithDamageKHR)
-      EGL_ENTRYPOINT(eglGetPlatformDisplayEXT)
-      EGL_ENTRYPOINT(eglCreatePlatformWindowSurfaceEXT)
-      EGL_ENTRYPOINT(eglCreatePlatformPixmapSurfaceEXT)
-      EGL_ENTRYPOINT(eglGetSyncValuesCHROMIUM)
-      EGL_ENTRYPOINT(eglExportDMABUFImageQueryMESA)
-      EGL_ENTRYPOINT(eglExportDMABUFImageMESA)
-      EGL_ENTRYPOINT(eglLabelObjectKHR)
-      EGL_ENTRYPOINT(eglDebugMessageControlKHR)
-      EGL_ENTRYPOINT(eglQueryDebugKHR)
-      EGL_ENTRYPOINT(eglDupNativeFenceFDANDROID)
+#include "eglentrypoint.h"
 #undef EGL_ENTRYPOINT
    };
-   EGLint i;
-   _EGLProc ret;
+   _EGLProc ret = NULL;
 
    if (!procname)
       RETURN_EGL_SUCCESS(NULL, NULL);
 
    _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
 
-   ret = NULL;
    if (strncmp(procname, "egl", 3) == 0) {
-      for (i = 0; egl_functions[i].name; i++) {
-         if (strcmp(egl_functions[i].name, procname) == 0) {
-            ret = egl_functions[i].function;
-            break;
-         }
-      }
+      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);