egl: replace `&_eglDriver`/`NULL` tested against `NULL` with simple `true`/`false`
[mesa.git] / src / egl / main / eglapi.c
index 35618680e853629dc988a5da93759728850f6800..9c78e9c343e7e78fd3d7be667d9c751d171bc1c8 100644 (file)
  */
 
 
+#ifdef USE_LIBGLVND
+#define EGLAPI
+#undef PUBLIC
+#define PUBLIC
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -90,7 +96,6 @@
 #include "c11/threads.h"
 #include "util/macros.h"
 
-#include "eglapi.h"
 #include "egldefines.h"
 #include "eglglobals.h"
 #include "eglcontext.h"
  * A bunch of macros and checks to simplify error checking.
  */
 
-#define _EGL_CHECK_DISPLAY(disp, ret, drv)         \
+#define _EGL_CHECK_DISPLAY(disp, ret)              \
    do {                                            \
-      drv = _eglCheckDisplay(disp, __func__);      \
-      if (!drv)                                    \
+      if (!_eglCheckDisplay(disp, __func__))       \
          RETURN_EGL_ERROR(disp, 0, ret);           \
    } while (0)
 
-#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv)      \
+#define _EGL_CHECK_OBJECT(disp, type, obj, ret)           \
    do {                                                   \
-      drv = _eglCheck ## type(disp, obj, __func__);       \
-      if (!drv)                                           \
+      if (!_eglCheck ## type(disp, obj, __func__))        \
          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_SURFACE(disp, surf, ret) \
+   _EGL_CHECK_OBJECT(disp, Surface, surf, ret)
 
-#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
-   _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
+#define _EGL_CHECK_CONTEXT(disp, context, ret) \
+   _EGL_CHECK_OBJECT(disp, Context, context, ret)
 
-#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
-   _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
+#define _EGL_CHECK_CONFIG(disp, conf, ret) \
+   _EGL_CHECK_OBJECT(disp, Config, conf, ret)
 
-#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
-   _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
+#define _EGL_CHECK_SYNC(disp, s, ret) \
+   _EGL_CHECK_OBJECT(disp, Sync, s, ret)
 
 
 struct _egl_entrypoint {
@@ -166,74 +169,70 @@ struct _egl_entrypoint {
 };
 
 
-static inline _EGLDriver *
+static inline bool
 _eglCheckDisplay(_EGLDisplay *disp, const char *msg)
 {
    if (!disp) {
       _eglError(EGL_BAD_DISPLAY, msg);
-      return NULL;
+      return false;
    }
    if (!disp->Initialized) {
       _eglError(EGL_NOT_INITIALIZED, msg);
-      return NULL;
+      return false;
    }
-   return disp->Driver;
+   return true;
 }
 
 
-static inline _EGLDriver *
+static inline bool
 _eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
 {
-   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
-   if (!drv)
-      return NULL;
+   if (!_eglCheckDisplay(disp, msg))
+      return false;
    if (!surf) {
       _eglError(EGL_BAD_SURFACE, msg);
-      return NULL;
+      return false;
    }
-   return drv;
+   return true;
 }
 
 
-static inline _EGLDriver *
+static inline bool
 _eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
 {
-   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
-   if (!drv)
-      return NULL;
+   if (!_eglCheckDisplay(disp, msg))
+      return false;
    if (!context) {
       _eglError(EGL_BAD_CONTEXT, msg);
-      return NULL;
+      return false;
    }
-   return drv;
+   return true;
 }
 
 
-static inline _EGLDriver *
+static inline bool
 _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
 {
-   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
-   if (!drv)
-      return NULL;
+   if (!_eglCheckDisplay(disp, msg))
+      return false;
    if (!conf) {
       _eglError(EGL_BAD_CONFIG, msg);
-      return NULL;
+      return false;
    }
-   return drv;
+   return true;
 }
 
 
-static inline _EGLDriver *
+static inline bool
 _eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
 {
-   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
-   if (!drv)
-      return NULL;
+   if (!_eglCheckDisplay(disp, msg))
+      return false;
    if (!s) {
       _eglError(EGL_BAD_PARAMETER, msg);
-      return NULL;
+      return false;
    }
-   return drv;
+   return true;
 }
 
 
@@ -241,12 +240,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;
 }
 
 
@@ -254,9 +253,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
@@ -334,22 +333,16 @@ _eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
 static EGLint *
 _eglConvertAttribsToInt(const EGLAttrib *attr_list)
 {
+   size_t size = _eglNumAttribs(attr_list);
    EGLint *int_attribs = NULL;
 
    /* Convert attributes from EGLAttrib[] to EGLint[] */
-   if (attr_list) {
-      int i, size = 0;
-
-      while (attr_list[size] != EGL_NONE)
-         size += 2;
-
-      size += 1; /* add space for EGL_NONE */
-
+   if (size) {
       int_attribs = calloc(size, sizeof(int_attribs[0]));
       if (!int_attribs)
          return NULL;
 
-      for (i = 0; i < size; i++)
+      for (size_t i = 0; i < size; i++)
          int_attribs[i] = attr_list[i];
    }
    return int_attribs;
@@ -364,7 +357,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);
@@ -373,44 +366,50 @@ 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, NULL);
+   return _eglGetDisplayHandle(disp);
 }
 
 static EGLDisplay
 _eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
                              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;
+#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(dpy);
+   return _eglGetDisplayHandle(disp);
 }
 
 static EGLDisplay EGLAPIENTRY
@@ -418,16 +417,16 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
                          const EGLint *int_attribs)
 {
    EGLAttrib *attrib_list;
-   EGLDisplay display;
+   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);
 
-   display = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
+   disp = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
    free(attrib_list);
-   return display;
+   return disp;
 }
 
 EGLDisplay EGLAPIENTRY
@@ -466,17 +465,17 @@ _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);
@@ -509,8 +508,8 @@ _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)
-      dpy->Extensions.KHR_image = EGL_TRUE;
+   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);
@@ -519,12 +518,12 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
    _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);
@@ -542,29 +541,29 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
 }
 
 static void
-_eglCreateAPIsString(_EGLDisplay *dpy)
+_eglCreateAPIsString(_EGLDisplay *disp)
 {
 #define addstr(str) \
    { \
-      const size_t old_len = strlen(dpy->ClientAPIsString); \
+      const size_t old_len = strlen(disp->ClientAPIsString); \
       const size_t add_len = sizeof(str); \
-      const size_t max_len = sizeof(dpy->ClientAPIsString) - 1; \
+      const size_t max_len = sizeof(disp->ClientAPIsString) - 1; \
       if (old_len + add_len <= max_len) \
-         strcat(dpy->ClientAPIsString, str " "); \
+         strcat(disp->ClientAPIsString, str " "); \
       else \
-         assert(!"dpy->ClientAPIsString is not large enough"); \
+         assert(!"disp->ClientAPIsString is not large enough"); \
    }
 
-   if (dpy->ClientAPIs & EGL_OPENGL_BIT)
+   if (disp->ClientAPIs & EGL_OPENGL_BIT)
       addstr("OpenGL");
 
-   if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT ||
-       dpy->ClientAPIs & EGL_OPENGL_ES2_BIT ||
-       dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
+   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)
+   if (disp->ClientAPIs & EGL_OPENVG_BIT)
       addstr("OpenVG");
 
 #undef addstr
@@ -589,6 +588,11 @@ _eglComputeVersion(_EGLDisplay *disp)
        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
 }
 
 /**
@@ -606,7 +610,7 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
 
    if (!disp->Initialized) {
-      if (!_eglMatchDriver(disp))
+      if (!_eglInitializeDisplay(disp))
          RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
 
       /* limit to APIs supported by core */
@@ -662,12 +666,14 @@ eglTerminate(EGLDisplay dpy)
       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
 
    if (disp->Initialized) {
-      _EGLDriver *drv = disp->Driver;
-
-      drv->API.Terminate(drv, disp);
+      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);
@@ -678,19 +684,16 @@ const char * EGLAPIENTRY
 eglQueryString(EGLDisplay dpy, EGLint name)
 {
    _EGLDisplay *disp;
-   _EGLDriver *drv;
 
+#if !USE_LIBGLVND
    if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
-      const char *ret = _eglGetClientExtensionString();
-      if (ret != NULL)
-         RETURN_EGL_SUCCESS(NULL, ret);
-      else
-         RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
+      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);
+   _EGL_CHECK_DISPLAY(disp, NULL);
 
    switch (name) {
    case EGL_VENDOR:
@@ -712,13 +715,16 @@ eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
               EGLint config_size, EGLint *num_config)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
-   ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
+
+   if (!num_config)
+      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+   ret = _eglGetConfigs(disp, configs, config_size, num_config);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -729,14 +735,17 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
                 EGLint config_size, EGLint *num_config)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
-   ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
-                               config_size, num_config);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
+
+   if (!num_config)
+      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+   ret = _eglChooseConfig(disp, attrib_list, configs,
+                          config_size, num_config);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -748,13 +757,13 @@ eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
 
-   _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
-   ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
+   _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE);
+
+   ret = _eglGetConfigAttrib(disp, conf, attribute, value);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -767,23 +776,22 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
    _EGLContext *share = _eglLookupContext(share_list, disp);
-   _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);
+   _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT);
 
    if (config != EGL_NO_CONFIG_KHR)
-      _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
+      _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT);
    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->API.CreateContext(drv, disp, conf, share, attrib_list);
+   context = disp->Driver->CreateContext(disp, conf, share, attrib_list);
    ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -795,14 +803,13 @@ eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *context = _eglLookupContext(ctx, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
 
-   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
+   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
    _eglUnlinkContext(context);
-   ret = drv->API.DestroyContext(drv, disp, context);
+   ret = disp->Driver->DestroyContext(disp, context);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -816,14 +823,12 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
    _EGLContext *context = _eglLookupContext(ctx, disp);
    _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
    _EGLSurface *read_surf = _eglLookupSurface(read, disp);
-   _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) {
@@ -831,7 +836,7 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
           ctx != EGL_NO_CONTEXT)
          RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
    }
-   if (!drv)
+   if (!disp->Driver)
       RETURN_EGL_SUCCESS(disp, EGL_TRUE);
 
    if (!context && ctx != EGL_NO_CONTEXT)
@@ -860,7 +865,7 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
    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);
+   ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -872,24 +877,49 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *context = _eglLookupContext(ctx, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
 
-   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
-   ret = drv->API.QueryContext(drv, disp, context, attribute, value);
+   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
+
+   ret = _eglQueryContext(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);
-   _EGLDriver *drv;
    _EGLSurface *surf;
    EGLSurface ret;
 
@@ -897,8 +927,8 @@ _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
    if (native_window == NULL)
       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
 
-#ifdef HAVE_SURFACELESS_PLATFORM
-   if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+   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>
@@ -913,15 +943,16 @@ _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
        */
       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
    }
-#endif
 
-   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
    if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
 
-   surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
-                                       attrib_list);
+   if (_eglNativeSurfaceAlreadyUsed(disp, native_window))
+      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+   surf = disp->Driver->CreateWindowSurface(disp, conf, native_window, attrib_list);
    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -1017,12 +1048,11 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
                               void *native_pixmap, const EGLint *attrib_list)
 {
    _EGLConfig *conf = _eglLookupConfig(config, disp);
-   _EGLDriver *drv;
    _EGLSurface *surf;
    EGLSurface ret;
 
-#if HAVE_SURFACELESS_PLATFORM
-   if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
+   if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
+                disp->Platform == _EGL_PLATFORM_DEVICE)) {
       /* From the EGL_MESA_platform_surfaceless spec (v1):
        *
        *   [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
@@ -1035,9 +1065,8 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
        */
       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
    }
-#endif
 
-   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
    if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
@@ -1045,8 +1074,10 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
    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);
+   if (_eglNativeSurfaceAlreadyUsed(disp, native_pixmap))
+      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+   surf = disp->Driver->CreatePixmapSurface(disp, conf, native_pixmap, attrib_list);
    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -1108,17 +1139,16 @@ eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
-   _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);
+   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
    if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
 
-   surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
+   surf = disp->Driver->CreatePbufferSurface(disp, conf, attrib_list);
    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -1130,13 +1160,12 @@ eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
-   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
    _eglUnlinkSurface(surf);
-   ret = drv->API.DestroySurface(drv, disp, surf);
+   ret = disp->Driver->DestroySurface(disp, surf);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1147,12 +1176,15 @@ eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _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->API.QuerySurface(drv, disp, surf, attribute, value);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+
+   if (disp->Driver->QuerySurface)
+      ret = disp->Driver->QuerySurface(disp, surf, attribute, value);
+   else
+      ret = _eglQuerySurface(disp, surf, attribute, value);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1163,12 +1195,12 @@ eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _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->API.SurfaceAttrib(drv, disp, surf, attribute, value);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+
+   ret = _eglSurfaceAttrib(disp, surf, attribute, value);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1179,12 +1211,11 @@ eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _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->API.BindTexImage(drv, disp, surf, buffer);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+   ret = disp->Driver->BindTexImage(disp, surf, buffer);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1195,12 +1226,11 @@ eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _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->API.ReleaseTexImage(drv, disp, surf, buffer);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+   ret = disp->Driver->ReleaseTexImage(disp, surf, buffer);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1212,11 +1242,10 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
 
    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
        ctx->Resource.Display != disp)
@@ -1232,10 +1261,15 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
                     surf->Config->MinSwapInterval,
                     surf->Config->MaxSwapInterval);
 
-   if (surf->SwapInterval != interval)
-      ret = drv->API.SwapInterval(drv, disp, surf, interval);
-   else
+   if (surf->SwapInterval != interval) {
+      if (disp->Driver->SwapInterval)
+         ret = disp->Driver->SwapInterval(disp, surf, interval);
+      else
+         ret = _eglSwapInterval(disp, surf, interval);
+   }
+   else {
       ret = EGL_TRUE;
+   }
 
    if (ret)
       surf->SwapInterval = interval;
@@ -1250,11 +1284,10 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
-   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
 
    /* surface must be bound to current context in EGL 1.4 */
    #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
@@ -1275,7 +1308,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
    if (surf->Lost)
       RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
 
-   ret = drv->API.SwapBuffers(drv, disp, surf);
+   ret = disp->Driver->SwapBuffers(disp, surf);
 
    /* EGL_KHR_partial_update
     * Frame boundary successfully reached,
@@ -1292,13 +1325,12 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 
 static EGLBoolean
 _eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
-                                EGLint *rects, EGLint n_rects)
+                                const EGLint *rects, EGLint n_rects)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
-   _EGLDriver *drv;
    EGLBoolean ret;
 
-   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
 
    /* surface must be bound to current context in EGL 1.4 */
    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
@@ -1311,7 +1343,7 @@ _eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
    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);
+   ret = disp->Driver->SwapBuffersWithDamageEXT(disp, surf, rects, n_rects);
 
    /* EGL_KHR_partial_update
     * Frame boundary successfully reached,
@@ -1327,7 +1359,7 @@ _eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
 
 static EGLBoolean EGLAPIENTRY
 eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
-                            EGLint *rects, EGLint n_rects)
+                            const EGLint *rects, EGLint n_rects)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
@@ -1337,7 +1369,7 @@ eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
 
 static EGLBoolean EGLAPIENTRY
 eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
-                            EGLint *rects, EGLint n_rects)
+                            const EGLint *rects, EGLint n_rects)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
@@ -1350,7 +1382,7 @@ eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
  */
 
 static void
-_eglSetDamageRegionKHRClampRects(_EGLDisplay* disp, _EGLSurface* surf,
+_eglSetDamageRegionKHRClampRects(_EGLSurface* surf,
                                  EGLint *rects, EGLint n_rects)
 {
    EGLint i;
@@ -1379,9 +1411,8 @@ eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
    _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);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
 
    if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
        surf->Type != EGL_WINDOW_BIT ||
@@ -1397,8 +1428,8 @@ eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
    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);
+   _eglSetDamageRegionKHRClampRects(surf, rects, n_rects);
+   ret = disp->Driver->SetDamageRegion(disp, surf, rects, n_rects);
 
    if (ret)
       surf->SetDamageRegionCalled = EGL_TRUE;
@@ -1411,7 +1442,6 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
    void *native_pixmap_ptr;
 
@@ -1419,8 +1449,8 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
    STATIC_ASSERT(sizeof(void*) == sizeof(target));
    native_pixmap_ptr = (void*) target;
 
-   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
-   ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
+   ret = disp->Driver->CopyBuffers(disp, surf, native_pixmap_ptr);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1431,7 +1461,6 @@ _eglWaitClientCommon(void)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp;
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    if (!ctx)
@@ -1447,8 +1476,7 @@ _eglWaitClientCommon(void)
 
    /* a valid current context implies an initialized current display */
    assert(disp->Initialized);
-   drv = disp->Driver;
-   ret = drv->API.WaitClient(drv, disp, ctx);
+   ret = disp->Driver->WaitClient(disp, ctx);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1474,7 +1502,6 @@ eglWaitNative(EGLint engine)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp;
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    if (!ctx)
@@ -1492,8 +1519,7 @@ eglWaitNative(EGLint engine)
 
    /* a valid current context implies an initialized current display */
    assert(disp->Initialized);
-   drv = disp->Driver;
-   ret = drv->API.WaitNative(drv, disp, engine);
+   ret = disp->Driver->WaitNative(engine);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1624,19 +1650,13 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLConfig *conf = _eglLookupConfig(config, disp);
-   _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);
-
-   surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
-                                                 conf, attrib_list);
-   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
+   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
 
-   RETURN_EGL_EVAL(disp, ret);
+   /* OpenVG is not supported */
+   RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
 }
 
 
@@ -1652,11 +1672,9 @@ eglReleaseThread(void)
 
       if (ctx) {
          _EGLDisplay *disp = ctx->Resource.Display;
-         _EGLDriver *drv;
 
          mtx_lock(&disp->Mutex);
-         drv = disp->Driver;
-         (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+         (void) disp->Driver->MakeCurrent(disp, NULL, NULL, NULL);
          mtx_unlock(&disp->Mutex);
       }
    }
@@ -1672,11 +1690,10 @@ _eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
                       EGLClientBuffer buffer, const EGLint *attr_list)
 {
    _EGLContext *context = _eglLookupContext(ctx, disp);
-   _EGLDriver *drv;
    _EGLImage *img;
    EGLImage ret;
 
-   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR);
    if (!disp->Extensions.KHR_image_base)
       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
    if (!context && ctx != EGL_NO_CONTEXT)
@@ -1687,8 +1704,7 @@ _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 = disp->Driver->CreateImageKHR(disp, context, target, buffer, attr_list);
    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -1727,17 +1743,16 @@ eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
 static EGLBoolean
 _eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
 {
-   _EGLDriver *drv;
    EGLBoolean ret;
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
    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->API.DestroyImageKHR(drv, disp, img);
+   ret = disp->Driver->DestroyImageKHR(disp, img);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1767,11 +1782,10 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
                EGLenum invalid_type_error)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
-   _EGLDriver *drv;
    _EGLSync *sync;
    EGLSync ret;
 
-   _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR);
 
    if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
       /* There exist two EGLAttrib variants of eglCreateSync*:
@@ -1794,9 +1808,10 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
        (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_EGL_sync */
+   /* 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_ES_API &&
+                ctx->ClientAPI != EGL_OPENGL_API)))
       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
 
    switch (type) {
@@ -1820,7 +1835,7 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
       RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
    }
 
-   sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
+   sync = disp->Driver->CreateSyncKHR(disp, type, attrib_list);
    ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -1879,16 +1894,15 @@ eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
 static EGLBoolean
 _eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
 {
-   _EGLDriver *drv;
    EGLBoolean ret;
 
-   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
    assert(disp->Extensions.KHR_reusable_sync ||
           disp->Extensions.KHR_fence_sync ||
           disp->Extensions.ANDROID_native_fence_sync);
 
    _eglUnlinkSync(s);
-   ret = drv->API.DestroySyncKHR(drv, disp, s);
+   ret = disp->Driver->DestroySyncKHR(disp, s);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1916,10 +1930,9 @@ static EGLint
 _eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
                          _EGLSync *s, EGLint flags, EGLTime timeout)
 {
-   _EGLDriver *drv;
    EGLint ret;
 
-   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
    assert(disp->Extensions.KHR_reusable_sync ||
           disp->Extensions.KHR_fence_sync ||
           disp->Extensions.ANDROID_native_fence_sync);
@@ -1935,7 +1948,7 @@ _eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
    if (s->Type == EGL_SYNC_REUSABLE_KHR)
       _eglUnlockDisplay(dpy);
 
-   ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
+   ret = disp->Driver->ClientWaitSyncKHR(disp, s, flags, timeout);
 
    /*
     * 'disp' is already unlocked for reusable sync type,
@@ -1972,21 +1985,22 @@ static EGLint
 _eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
-   _EGLDriver *drv;
    EGLint ret;
 
-   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
    assert(disp->Extensions.KHR_wait_sync);
 
-   /* return an error if the client API doesn't support GL_OES_EGL_sync */
-   if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
+   /* 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->API.WaitSyncKHR(drv, disp, s);
+   ret = disp->Driver->WaitSyncKHR(disp, s);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2020,14 +2034,13 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSync *s = _eglLookupSync(sync, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
 
-   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
    assert(disp->Extensions.KHR_reusable_sync);
-   ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
+   ret = disp->Driver->SignalSyncKHR(disp, s, mode);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2036,14 +2049,14 @@ eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
 static EGLBoolean
 _eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
 {
-   _EGLDriver *drv;
    EGLBoolean ret;
 
-   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
+   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
    assert(disp->Extensions.KHR_reusable_sync ||
           disp->Extensions.KHR_fence_sync ||
           disp->Extensions.ANDROID_native_fence_sync);
-   ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
+
+   ret = _eglGetSyncAttrib(disp, s, attribute, value);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2054,6 +2067,10 @@ eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *valu
    _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);
 }
 
@@ -2090,7 +2107,6 @@ eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSync *s = _eglLookupSync(sync, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
@@ -2102,9 +2118,9 @@ eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
    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);
+   _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID);
    assert(disp->Extensions.ANDROID_native_fence_sync);
-   ret = drv->API.DupNativeFenceFDANDROID(drv, disp, s);
+   ret = disp->Driver->DupNativeFenceFDANDROID(disp, s);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2116,12 +2132,11 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
 
-   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
 
    if (!disp->Extensions.NOK_swap_region)
       RETURN_EGL_EVAL(disp, EGL_FALSE);
@@ -2131,7 +2146,7 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
        surf != ctx->DrawSurface)
       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
 
-   ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
+   ret = disp->Driver->SwapBuffersRegionNOK(disp, surf, numRects, rects);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2141,17 +2156,16 @@ static EGLImage EGLAPIENTRY
 eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _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);
+   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR);
    if (!disp->Extensions.MESA_drm_image)
       RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
 
-   img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
+   img = disp->Driver->CreateDRMImageMESA(disp, attr_list);
    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -2163,18 +2177,17 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img = _eglLookupImage(image, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
    assert(disp->Extensions.MESA_drm_image);
 
    if (!img)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
 
-   ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
+   ret = disp->Driver->ExportDRMImageMESA(disp, img, name, handle, stride);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2186,18 +2199,17 @@ static EGLBoolean EGLAPIENTRY
 eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
    assert(disp->Extensions.WL_bind_wayland_display);
 
    if (!display)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
 
-   ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
+   ret = disp->Driver->BindWaylandDisplayWL(disp, display);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2206,18 +2218,17 @@ static EGLBoolean EGLAPIENTRY
 eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
    assert(disp->Extensions.WL_bind_wayland_display);
 
    if (!display)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
 
-   ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
+   ret = disp->Driver->UnbindWaylandDisplayWL(disp, display);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2227,18 +2238,17 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
                         EGLint attribute, EGLint *value)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
    assert(disp->Extensions.WL_bind_wayland_display);
 
    if (!buffer)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
 
-   ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
+   ret = disp->Driver->QueryWaylandBufferWL(disp, buffer, attribute, value);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2249,12 +2259,11 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img;
-   _EGLDriver *drv;
    struct wl_buffer *ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, NULL, drv);
+   _EGL_CHECK_DISPLAY(disp, NULL);
    if (!disp->Extensions.WL_create_wayland_buffer_from_image)
       RETURN_EGL_EVAL(disp, NULL);
 
@@ -2263,7 +2272,7 @@ eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
    if (!img)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
 
-   ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
+   ret = disp->Driver->CreateWaylandBufferFromImageWL(disp, img);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2274,41 +2283,39 @@ eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLSurface *surf = _eglLookupSurface(surface, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
 
-   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
 
    if (!disp->Extensions.NV_post_sub_buffer)
       RETURN_EGL_EVAL(disp, EGL_FALSE);
 
-   ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
+   ret = disp->Driver->PostSubBufferNV(disp, surf, x, y, width, height);
 
    RETURN_EGL_EVAL(disp, ret);
 }
 
 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;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
 
-   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
    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->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
+   ret = disp->Driver->GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2320,19 +2327,17 @@ eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img = _eglLookupImage(image, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
    assert(disp->Extensions.MESA_image_dma_buf_export);
 
    if (!img)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
 
-   ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
-                                             modifiers);
+   ret = disp->Driver->ExportDMABUFImageQueryMESA(disp, img, fourcc, nplanes, modifiers);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2343,18 +2348,17 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img = _eglLookupImage(image, disp);
-   _EGLDriver *drv;
    EGLBoolean ret;
 
    _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
 
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
    assert(disp->Extensions.MESA_image_dma_buf_export);
 
    if (!img)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
 
-   ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
+   ret = disp->Driver->ExportDMABUFImageMESA(disp, img, fds, strides, offsets);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2511,15 +2515,13 @@ 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);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
 
-   ret = drv->API.QueryDmaBufFormatsEXT(drv, disp, max_formats, formats,
-                                        num_formats);
+   ret = disp->Driver->QueryDmaBufFormatsEXT(disp, max_formats, formats, num_formats);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2530,16 +2532,14 @@ eglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers,
                            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);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
 
-   ret = drv->API.QueryDmaBufModifiersEXT(drv, disp, format, max_modifiers,
-                                          modifiers, external_only,
-                                          num_modifiers);
+   ret = disp->Driver->QueryDmaBufModifiersEXT(disp, format, max_modifiers, modifiers,
+                                      external_only, num_modifiers);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -2558,8 +2558,7 @@ eglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set,
       return;
    }
 
-   _EGLDriver *drv = _eglCheckDisplay(disp, __func__);
-   if (!drv) {
+   if (!_eglCheckDisplay(disp, __func__)) {
       if (disp)
          _eglUnlockDisplay(disp);
       return;
@@ -2582,7 +2581,7 @@ eglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set,
    disp->BlobCacheSet = set;
    disp->BlobCacheGet = get;
 
-   drv->API.SetBlobCacheFuncsANDROID(drv, disp, set, get);
+   disp->Driver->SetBlobCacheFuncsANDROID(disp, set, get);
 
    _eglUnlockDisplay(disp);
 }
@@ -2635,10 +2634,9 @@ eglQueryDisplayAttribEXT(EGLDisplay dpy,
                          EGLAttrib *value)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLDriver *drv;
 
    _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
-   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
 
    switch (attribute) {
    case EGL_DEVICE_EXT:
@@ -2650,35 +2648,33 @@ eglQueryDisplayAttribEXT(EGLDisplay dpy,
    RETURN_EGL_SUCCESS(disp, EGL_TRUE);
 }
 
-char * EGLAPIENTRY
+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);
+    _EGL_CHECK_DISPLAY(disp, NULL);
 
     assert(disp->Extensions.MESA_query_driver);
 
-    ret = drv->API.QueryDriverConfig(disp);
+    ret = disp->Driver->QueryDriverConfig(disp);
     RETURN_EGL_EVAL(disp, ret);
 }
 
-const char * EGLAPIENTRY
+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);
+    _EGL_CHECK_DISPLAY(disp, NULL);
 
     assert(disp->Extensions.MESA_query_driver);
 
-    ret = drv->API.QueryDriverName(disp);
+    ret = disp->Driver->QueryDriverName(disp);
     RETURN_EGL_EVAL(disp, ret);
 }
 
@@ -2715,8 +2711,7 @@ eglGetProcAddress(const char *procname)
 
 static int
 _eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
-                       _EGLDisplay **disp, _EGLDriver **drv,
-                       _EGLContext **ctx)
+                       _EGLDisplay **disp, _EGLContext **ctx)
 {
 
    *disp = _eglLockDisplay(dpy);
@@ -2726,8 +2721,6 @@ _eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
       return MESA_GLINTEROP_INVALID_DISPLAY;
    }
 
-   *drv = (*disp)->Driver;
-
    *ctx = _eglLookupContext(context, *disp);
    if (!*ctx ||
        ((*ctx)->ClientAPI != EGL_OPENGL_API &&
@@ -2744,16 +2737,15 @@ MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
                                 struct mesa_glinterop_device_info *out)
 {
    _EGLDisplay *disp;
-   _EGLDriver *drv;
    _EGLContext *ctx;
    int ret;
 
-   ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
+   ret = _eglLockDisplayInterop(dpy, context, &disp, &ctx);
    if (ret != MESA_GLINTEROP_SUCCESS)
       return ret;
 
-   if (drv->API.GLInteropQueryDeviceInfo)
-      ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
+   if (disp->Driver->GLInteropQueryDeviceInfo)
+      ret = disp->Driver->GLInteropQueryDeviceInfo(disp, ctx, out);
    else
       ret = MESA_GLINTEROP_UNSUPPORTED;
 
@@ -2767,16 +2759,15 @@ MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
                              struct mesa_glinterop_export_out *out)
 {
    _EGLDisplay *disp;
-   _EGLDriver *drv;
    _EGLContext *ctx;
    int ret;
 
-   ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
+   ret = _eglLockDisplayInterop(dpy, context, &disp, &ctx);
    if (ret != MESA_GLINTEROP_SUCCESS)
       return ret;
 
-   if (drv->API.GLInteropExportObject)
-      ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
+   if (disp->Driver->GLInteropExportObject)
+      ret = disp->Driver->GLInteropExportObject(disp, ctx, in, out);
    else
       ret = MESA_GLINTEROP_UNSUPPORTED;