diff --git a/configure.ac b/configure.ac
index ab33ca03805..ba09cc32535 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1348,10 +1348,11 @@ dnl Libglvnd configuration
dnl
AC_ARG_ENABLE([libglvnd],
[AS_HELP_STRING([--enable-libglvnd],
- [Build for libglvnd @<:@default=disabled@:>@])],
+ [Build GLX and EGL for libglvnd @<:@default=disabled@:>@])],
[enable_libglvnd="$enableval"],
[enable_libglvnd=no])
-AM_CONDITIONAL(USE_LIBGLVND_GLX, test "x$enable_libglvnd" = xyes)
+AM_CONDITIONAL(USE_LIBGLVND, test "x$enable_libglvnd" = xyes)
+
if test "x$enable_libglvnd" = xyes ; then
dnl XXX: update once we can handle more than libGL/glx.
dnl Namely: we should error out if neither of the glvnd enabled libraries
@@ -1367,8 +1368,11 @@ if test "x$enable_libglvnd" = xyes ; then
;;
esac
- PKG_CHECK_MODULES([GLVND], libglvnd >= 0.1.0)
- DEFINES="${DEFINES} -DUSE_LIBGLVND_GLX=1"
+ PKG_CHECK_MODULES([GLVND], libglvnd >= 0.2.0)
+ PKG_CHECK_VAR(LIBGLVND_DATADIR, libglvnd, datadir)
+ AC_SUBST([LIBGLVND_DATADIR])
+
+ DEFINES="${DEFINES} -DUSE_LIBGLVND=1"
DEFAULT_GL_LIB_NAME=GLX_mesa
fi
diff --git a/src/egl/Makefile.am b/src/egl/Makefile.am
index 3477f797d77..e607b83fb99 100644
--- a/src/egl/Makefile.am
+++ b/src/egl/Makefile.am
@@ -32,19 +32,16 @@ AM_CFLAGS = \
$(EGL_CFLAGS) \
-D_EGL_NATIVE_PLATFORM=$(EGL_NATIVE_PLATFORM)
-lib_LTLIBRARIES = libEGL.la
-
-libEGL_la_SOURCES = \
+# Depending on whether libglvnd is enabled, we'll build the EGL library as
+# either libEGL.so.1 or libEGL_mesa.so.0. Using an automake substitution
+# in the variable names breaks "make dist" target, so use a conenience library
+# instead.
+noinst_LTLIBRARIES = libEGL_common.la
+libEGL_common_la_SOURCES = \
$(LIBEGL_C_FILES)
-libEGL_la_LIBADD = \
+libEGL_common_la_LIBADD = \
$(EGL_LIB_DEPS)
-libEGL_la_LDFLAGS = \
- -no-undefined \
- -version-number 1:0 \
- $(BSYMBOLIC) \
- $(GC_SECTIONS) \
- $(LD_NO_UNDEFINED)
dri2_backend_FILES =
dri3_backend_FILES =
@@ -52,7 +49,7 @@ dri3_backend_FILES =
if HAVE_PLATFORM_X11
AM_CFLAGS += -DHAVE_X11_PLATFORM
AM_CFLAGS += $(XCB_DRI2_CFLAGS)
-libEGL_la_LIBADD += $(XCB_DRI2_LIBS)
+libEGL_common_la_LIBADD += $(XCB_DRI2_LIBS)
dri2_backend_FILES += drivers/dri2/platform_x11.c
if HAVE_DRI3
@@ -60,22 +57,22 @@ dri3_backend_FILES += \
drivers/dri2/platform_x11_dri3.c \
drivers/dri2/platform_x11_dri3.h
-libEGL_la_LIBADD += $(top_builddir)/src/loader/libloader_dri3_helper.la
+libEGL_common_la_LIBADD += $(top_builddir)/src/loader/libloader_dri3_helper.la
endif
endif
if HAVE_PLATFORM_WAYLAND
AM_CFLAGS += -DHAVE_WAYLAND_PLATFORM
AM_CFLAGS += $(WAYLAND_CFLAGS)
-libEGL_la_LIBADD += $(WAYLAND_LIBS)
-libEGL_la_LIBADD += $(LIBDRM_LIBS)
-libEGL_la_LIBADD += $(top_builddir)/src/egl/wayland/wayland-drm/libwayland-drm.la
+libEGL_common_la_LIBADD += $(WAYLAND_LIBS)
+libEGL_common_la_LIBADD += $(LIBDRM_LIBS)
+libEGL_common_la_LIBADD += $(top_builddir)/src/egl/wayland/wayland-drm/libwayland-drm.la
dri2_backend_FILES += drivers/dri2/platform_wayland.c
endif
if HAVE_EGL_PLATFORM_DRM
AM_CFLAGS += -DHAVE_DRM_PLATFORM
-libEGL_la_LIBADD += $(top_builddir)/src/gbm/libgbm.la
+libEGL_common_la_LIBADD += $(top_builddir)/src/gbm/libgbm.la
dri2_backend_FILES += drivers/dri2/platform_drm.c
endif
@@ -87,7 +84,7 @@ endif
if HAVE_EGL_PLATFORM_ANDROID
AM_CFLAGS += -DHAVE_ANDROID_PLATFORM
AM_CFLAGS += $(ANDROID_CFLAGS)
-libEGL_la_LIBADD += $(ANDROID_LIBS)
+libEGL_common_la_LIBADD += $(ANDROID_LIBS)
dri2_backend_FILES += drivers/dri2/platform_android.c
endif
@@ -101,13 +98,68 @@ AM_CFLAGS += \
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
-D_EGL_BUILT_IN_DRIVER_DRI2
-libEGL_la_SOURCES += \
+libEGL_common_la_SOURCES += \
$(dri2_backend_core_FILES) \
$(dri2_backend_FILES) \
$(dri3_backend_FILES)
-libEGL_la_LIBADD += $(top_builddir)/src/loader/libloader.la
-libEGL_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS) $(CLOCK_LIB)
+libEGL_common_la_LIBADD += $(top_builddir)/src/loader/libloader.la
+libEGL_common_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS) $(CLOCK_LIB)
+
+GLVND_GEN_DEPS = generate/gen_egl_dispatch.py \
+ generate/egl.xml generate/eglFunctionList.py generate/genCommon.py \
+ generate/egl_other.xml
+
+PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS)
+g_egldispatchstubs.c: $(GLVND_GEN_DEPS)
+ $(PYTHON_GEN) $(top_srcdir)/src/egl/generate/gen_egl_dispatch.py source \
+ $(top_srcdir)/src/egl/generate/eglFunctionList.py \
+ $(top_srcdir)/src/egl/generate/egl.xml \
+ $(top_srcdir)/src/egl/generate/egl_other.xml > $@
+
+g_egldispatchstubs.h: $(GLVND_GEN_DEPS)
+ $(PYTHON_GEN) $(top_srcdir)/src/egl/generate/gen_egl_dispatch.py header \
+ $(top_srcdir)/src/egl/generate/eglFunctionList.py \
+ $(top_srcdir)/src/egl/generate/egl.xml \
+ $(top_srcdir)/src/egl/generate/egl_other.xml > $@
+
+BUILT_SOURCES = g_egldispatchstubs.c g_egldispatchstubs.h
+CLEANFILES = $(BUILT_SOURCES)
+
+if USE_LIBGLVND
+AM_CFLAGS += \
+ $(GLVND_CFLAGS)
+
+vendorjsondir = @LIBGLVND_DATADIR@/glvnd/egl_vendor.d
+vendorjson_DATA = main/50_mesa.json
+
+lib_LTLIBRARIES = libEGL_mesa.la
+libEGL_mesa_la_SOURCES = \
+ main/eglglvnd.c \
+ main/egldispatchstubs.h \
+ main/egldispatchstubs.c \
+ g_egldispatchstubs.c
+libEGL_mesa_la_LIBADD = libEGL_common.la
+libEGL_mesa_la_LDFLAGS = \
+ -no-undefined \
+ -version-number 0 \
+ $(BSYMBOLIC) \
+ $(GC_SECTIONS) \
+ $(LD_NO_UNDEFINED)
+
+else # USE_LIBGLVND
+
+lib_LTLIBRARIES = libEGL.la
+libEGL_la_SOURCES =
+libEGL_la_LIBADD = libEGL_common.la
+libEGL_la_LDFLAGS = \
+ -no-undefined \
+ -version-number 1:0 \
+ $(BSYMBOLIC) \
+ $(GC_SECTIONS) \
+ $(LD_NO_UNDEFINED)
+
+endif # USE_LIBGLVND
include $(top_srcdir)/install-lib-links.mk
@@ -134,4 +186,6 @@ EXTRA_DIST = \
SConscript \
drivers/haiku \
main/egl.def \
- main/README.txt
+ main/README.txt \
+ $(GLVND_GEN_DEPS) \
+ main/50_mesa.json
diff --git a/src/egl/generate/egl.xml b/src/egl/generate/egl.xml
new file mode 100644
index 00000000000..f6dbbc0f269
--- /dev/null
+++ b/src/egl/generate/egl.xml
@@ -0,0 +1,2412 @@
+
+
+
+
+
+
+
+
+ #include <KHR/khrplatform.h>
+ #include <EGL/eglplatform.h>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ typedef unsigned int EGLBoolean;
+ typedef unsigned int EGLenum;
+ typedef intptr_t EGLAttribKHR;
+ typedef intptr_t EGLAttrib;
+ typedef void *EGLClientBuffer;
+ typedef void *EGLConfig;
+ typedef void *EGLContext;
+ typedef void *EGLDeviceEXT;
+ typedef void *EGLDisplay;
+ typedef void *EGLImage;
+ typedef void *EGLImageKHR;
+ typedef void *EGLLabelKHR;
+ typedef void *EGLObjectKHR;
+ typedef void *EGLOutputLayerEXT;
+ typedef void *EGLOutputPortEXT;
+ typedef void *EGLStreamKHR;
+ typedef void *EGLSurface;
+ typedef void *EGLSync;
+ typedef void *EGLSyncKHR;
+ typedef void *EGLSyncNV;
+ typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+ typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+ typedef khronos_utime_nanoseconds_t EGLTime;
+ typedef khronos_utime_nanoseconds_t EGLTimeNV;
+ typedef khronos_utime_nanoseconds_t EGLuint64NV;
+ typedef khronos_uint64_t EGLuint64KHR;
+ typedef int EGLNativeFileDescriptorKHR;
+ typedef khronos_ssize_t EGLsizeiANDROID;
+ typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
+ typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
+ struct EGLClientPixmapHI {
+ void *pData;
+ EGLint iWidth;
+ EGLint iHeight;
+ EGLint iStride;
+};
+ typedef void ( *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ EGLBoolean eglBindAPI
+ EGLenum api
+
+
+ EGLBoolean eglBindTexImage
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint buffer
+
+
+ EGLBoolean eglChooseConfig
+ EGLDisplay dpy
+ const EGLint *attrib_list
+ EGLConfig *configs
+ EGLint config_size
+ EGLint *num_config
+
+
+ EGLint eglClientWaitSync
+ EGLDisplay dpy
+ EGLSync sync
+ EGLint flags
+ EGLTime timeout
+
+
+ EGLint eglClientWaitSyncKHR
+ EGLDisplay dpy
+ EGLSyncKHR sync
+ EGLint flags
+ EGLTimeKHR timeout
+
+
+
+ EGLint eglClientWaitSyncNV
+ EGLSyncNV sync
+ EGLint flags
+ EGLTimeNV timeout
+
+
+ EGLBoolean eglCopyBuffers
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLNativePixmapType target
+
+
+ EGLContext eglCreateContext
+ EGLDisplay dpy
+ EGLConfig config
+ EGLContext share_context
+ const EGLint *attrib_list
+
+
+ EGLImageKHR eglCreateDRMImageMESA
+ EGLDisplay dpy
+ const EGLint *attrib_list
+
+
+ EGLSyncNV eglCreateFenceSyncNV
+ EGLDisplay dpy
+ EGLenum condition
+ const EGLint *attrib_list
+
+
+ EGLImage eglCreateImage
+ EGLDisplay dpy
+ EGLContext ctx
+ EGLenum target
+ EGLClientBuffer buffer
+ const EGLAttrib *attrib_list
+
+
+ EGLImageKHR eglCreateImageKHR
+ EGLDisplay dpy
+ EGLContext ctx
+ EGLenum target
+ EGLClientBuffer buffer
+ const EGLint *attrib_list
+
+
+ EGLSurface eglCreatePbufferFromClientBuffer
+ EGLDisplay dpy
+ EGLenum buftype
+ EGLClientBuffer buffer
+ EGLConfig config
+ const EGLint *attrib_list
+
+
+ EGLSurface eglCreatePbufferSurface
+ EGLDisplay dpy
+ EGLConfig config
+ const EGLint *attrib_list
+
+
+ EGLSurface eglCreatePixmapSurface
+ EGLDisplay dpy
+ EGLConfig config
+ EGLNativePixmapType pixmap
+ const EGLint *attrib_list
+
+
+ EGLSurface eglCreatePixmapSurfaceHI
+ EGLDisplay dpy
+ EGLConfig config
+ struct EGLClientPixmapHI *pixmap
+
+
+ EGLSurface eglCreatePlatformPixmapSurface
+ EGLDisplay dpy
+ EGLConfig config
+ void *native_pixmap
+ const EGLAttrib *attrib_list
+
+
+ EGLSurface eglCreatePlatformPixmapSurfaceEXT
+ EGLDisplay dpy
+ EGLConfig config
+ void *native_pixmap
+ const EGLint *attrib_list
+
+
+ EGLSurface eglCreatePlatformWindowSurface
+ EGLDisplay dpy
+ EGLConfig config
+ void *native_window
+ const EGLAttrib *attrib_list
+
+
+ EGLSurface eglCreatePlatformWindowSurfaceEXT
+ EGLDisplay dpy
+ EGLConfig config
+ void *native_window
+ const EGLint *attrib_list
+
+
+ EGLStreamKHR eglCreateStreamFromFileDescriptorKHR
+ EGLDisplay dpy
+ EGLNativeFileDescriptorKHR file_descriptor
+
+
+ EGLStreamKHR eglCreateStreamKHR
+ EGLDisplay dpy
+ const EGLint *attrib_list
+
+
+ EGLSurface eglCreateStreamProducerSurfaceKHR
+ EGLDisplay dpy
+ EGLConfig config
+ EGLStreamKHR stream
+ const EGLint *attrib_list
+
+
+ EGLSyncKHR eglCreateStreamSyncNV
+ EGLDisplay dpy
+ EGLStreamKHR stream
+ EGLenum type
+ const EGLint *attrib_list
+
+
+ EGLSync eglCreateSync
+ EGLDisplay dpy
+ EGLenum type
+ const EGLAttrib *attrib_list
+
+
+ EGLSyncKHR eglCreateSyncKHR
+ EGLDisplay dpy
+ EGLenum type
+ const EGLint *attrib_list
+
+
+ EGLSyncKHR eglCreateSync64KHR
+ EGLDisplay dpy
+ EGLenum type
+ const EGLAttribKHR *attrib_list
+
+
+
+ EGLSurface eglCreateWindowSurface
+ EGLDisplay dpy
+ EGLConfig config
+ EGLNativeWindowType win
+ const EGLint *attrib_list
+
+
+ EGLint eglDebugMessageControlKHR
+ EGLDEBUGPROCKHR callback
+ const EGLAttrib *attrib_list
+
+
+ EGLBoolean eglDestroyContext
+ EGLDisplay dpy
+ EGLContext ctx
+
+
+ EGLBoolean eglDestroyImage
+ EGLDisplay dpy
+ EGLImage image
+
+
+ EGLBoolean eglDestroyImageKHR
+ EGLDisplay dpy
+ EGLImageKHR image
+
+
+
+ EGLBoolean eglDestroyStreamKHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+
+
+ EGLBoolean eglDestroySurface
+ EGLDisplay dpy
+ EGLSurface surface
+
+
+ EGLBoolean eglDestroySync
+ EGLDisplay dpy
+ EGLSync sync
+
+
+ EGLBoolean eglDestroySyncKHR
+ EGLDisplay dpy
+ EGLSyncKHR sync
+
+
+
+ EGLBoolean eglDestroySyncNV
+ EGLSyncNV sync
+
+
+ EGLint eglDupNativeFenceFDANDROID
+ EGLDisplay dpy
+ EGLSyncKHR sync
+
+
+ EGLBoolean eglExportDMABUFImageMESA
+ EGLDisplay dpy
+ EGLImageKHR image
+ int *fds
+ EGLint *strides
+ EGLint *offsets
+
+
+ EGLBoolean eglExportDMABUFImageQueryMESA
+ EGLDisplay dpy
+ EGLImageKHR image
+ int *fourcc
+ int *num_planes
+ EGLuint64KHR *modifiers
+
+
+ EGLBoolean eglExportDRMImageMESA
+ EGLDisplay dpy
+ EGLImageKHR image
+ EGLint *name
+ EGLint *handle
+ EGLint *stride
+
+
+ EGLBoolean eglFenceNV
+ EGLSyncNV sync
+
+
+ EGLBoolean eglGetConfigAttrib
+ EGLDisplay dpy
+ EGLConfig config
+ EGLint attribute
+ EGLint *value
+
+
+ EGLBoolean eglGetConfigs
+ EGLDisplay dpy
+ EGLConfig *configs
+ EGLint config_size
+ EGLint *num_config
+
+
+ EGLContext eglGetCurrentContext
+
+
+ EGLDisplay eglGetCurrentDisplay
+
+
+ EGLSurface eglGetCurrentSurface
+ EGLint readdraw
+
+
+ EGLDisplay eglGetDisplay
+ EGLNativeDisplayType display_id
+
+
+ EGLint eglGetError
+
+
+ EGLBoolean eglGetOutputLayersEXT
+ EGLDisplay dpy
+ const EGLAttrib *attrib_list
+ EGLOutputLayerEXT *layers
+ EGLint max_layers
+ EGLint *num_layers
+
+
+ EGLBoolean eglGetOutputPortsEXT
+ EGLDisplay dpy
+ const EGLAttrib *attrib_list
+ EGLOutputPortEXT *ports
+ EGLint max_ports
+ EGLint *num_ports
+
+
+ EGLDisplay eglGetPlatformDisplay
+ EGLenum platform
+ void *native_display
+ const EGLAttrib *attrib_list
+
+
+ EGLDisplay eglGetPlatformDisplayEXT
+ EGLenum platform
+ void *native_display
+ const EGLint *attrib_list
+
+
+ __eglMustCastToProperFunctionPointerType eglGetProcAddress
+ const char *procname
+
+
+ EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+
+
+ EGLBoolean eglGetSyncAttrib
+ EGLDisplay dpy
+ EGLSync sync
+ EGLint attribute
+ EGLAttrib *value
+
+
+ EGLBoolean eglGetSyncAttribKHR
+ EGLDisplay dpy
+ EGLSyncKHR sync
+ EGLint attribute
+ EGLint *value
+
+
+ EGLBoolean eglGetSyncAttribNV
+ EGLSyncNV sync
+ EGLint attribute
+ EGLint *value
+
+
+ EGLuint64NV eglGetSystemTimeFrequencyNV
+
+
+ EGLuint64NV eglGetSystemTimeNV
+
+
+ EGLBoolean eglInitialize
+ EGLDisplay dpy
+ EGLint *major
+ EGLint *minor
+
+
+ EGLint eglLabelObjectKHR
+ EGLDisplay display
+ EGLenum objectType
+ EGLObjectKHR object
+ EGLLabelKHR label
+
+
+ EGLBoolean eglLockSurfaceKHR
+ EGLDisplay dpy
+ EGLSurface surface
+ const EGLint *attrib_list
+
+
+ EGLBoolean eglMakeCurrent
+ EGLDisplay dpy
+ EGLSurface draw
+ EGLSurface read
+ EGLContext ctx
+
+
+ EGLBoolean eglOutputLayerAttribEXT
+ EGLDisplay dpy
+ EGLOutputLayerEXT layer
+ EGLint attribute
+ EGLAttrib value
+
+
+ EGLBoolean eglOutputPortAttribEXT
+ EGLDisplay dpy
+ EGLOutputPortEXT port
+ EGLint attribute
+ EGLAttrib value
+
+
+ EGLBoolean eglPostSubBufferNV
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint x
+ EGLint y
+ EGLint width
+ EGLint height
+
+
+ EGLenum eglQueryAPI
+
+
+ EGLBoolean eglQueryContext
+ EGLDisplay dpy
+ EGLContext ctx
+ EGLint attribute
+ EGLint *value
+
+
+ EGLBoolean eglQueryDebugKHR
+ EGLint attribute
+ EGLAttrib *value
+
+
+ EGLBoolean eglQueryDeviceAttribEXT
+ EGLDeviceEXT device
+ EGLint attribute
+ EGLAttrib *value
+
+
+ const char *eglQueryDeviceStringEXT
+ EGLDeviceEXT device
+ EGLint name
+
+
+ EGLBoolean eglQueryDevicesEXT
+ EGLint max_devices
+ EGLDeviceEXT *devices
+ EGLint *num_devices
+
+
+ EGLBoolean eglQueryDisplayAttribEXT
+ EGLDisplay dpy
+ EGLint attribute
+ EGLAttrib *value
+
+
+ EGLBoolean eglQueryNativeDisplayNV
+ EGLDisplay dpy
+ EGLNativeDisplayType *display_id
+
+
+ EGLBoolean eglQueryNativePixmapNV
+ EGLDisplay dpy
+ EGLSurface surf
+ EGLNativePixmapType *pixmap
+
+
+ EGLBoolean eglQueryNativeWindowNV
+ EGLDisplay dpy
+ EGLSurface surf
+ EGLNativeWindowType *window
+
+
+ EGLBoolean eglQueryOutputLayerAttribEXT
+ EGLDisplay dpy
+ EGLOutputLayerEXT layer
+ EGLint attribute
+ EGLAttrib *value
+
+
+ const char *eglQueryOutputLayerStringEXT
+ EGLDisplay dpy
+ EGLOutputLayerEXT layer
+ EGLint name
+
+
+ EGLBoolean eglQueryOutputPortAttribEXT
+ EGLDisplay dpy
+ EGLOutputPortEXT port
+ EGLint attribute
+ EGLAttrib *value
+
+
+ const char *eglQueryOutputPortStringEXT
+ EGLDisplay dpy
+ EGLOutputPortEXT port
+ EGLint name
+
+
+ EGLBoolean eglQueryStreamKHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+ EGLenum attribute
+ EGLint *value
+
+
+ EGLBoolean eglQueryStreamTimeKHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+ EGLenum attribute
+ EGLTimeKHR *value
+
+
+ EGLBoolean eglQueryStreamu64KHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+ EGLenum attribute
+ EGLuint64KHR *value
+
+
+ const char *eglQueryString
+ EGLDisplay dpy
+ EGLint name
+
+
+ EGLBoolean eglQuerySurface
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint attribute
+ EGLint *value
+
+
+ EGLBoolean eglQuerySurface64KHR
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint attribute
+ EGLAttribKHR *value
+
+
+ EGLBoolean eglQuerySurfacePointerANGLE
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint attribute
+ void **value
+
+
+ EGLBoolean eglReleaseTexImage
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint buffer
+
+
+ EGLBoolean eglReleaseThread
+
+
+ void eglSetBlobCacheFuncsANDROID
+ EGLDisplay dpy
+ EGLSetBlobFuncANDROID set
+ EGLGetBlobFuncANDROID get
+
+
+ EGLBoolean eglSetDamageRegionKHR
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint *rects
+ EGLint n_rects
+
+
+ EGLBoolean eglSignalSyncKHR
+ EGLDisplay dpy
+ EGLSyncKHR sync
+ EGLenum mode
+
+
+ EGLBoolean eglSignalSyncNV
+ EGLSyncNV sync
+ EGLenum mode
+
+
+ EGLBoolean eglStreamAttribKHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+ EGLenum attribute
+ EGLint value
+
+
+ EGLBoolean eglStreamConsumerAcquireKHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+
+
+ EGLBoolean eglStreamConsumerGLTextureExternalKHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+
+
+ EGLBoolean eglStreamConsumerOutputEXT
+ EGLDisplay dpy
+ EGLStreamKHR stream
+ EGLOutputLayerEXT layer
+
+
+ EGLBoolean eglStreamConsumerReleaseKHR
+ EGLDisplay dpy
+ EGLStreamKHR stream
+
+
+ EGLBoolean eglSurfaceAttrib
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint attribute
+ EGLint value
+
+
+ EGLBoolean eglSwapBuffers
+ EGLDisplay dpy
+ EGLSurface surface
+
+
+ EGLBoolean eglSwapBuffersWithDamageEXT
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint *rects
+ EGLint n_rects
+
+
+ EGLBoolean eglSwapBuffersWithDamageKHR
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint *rects
+ EGLint n_rects
+
+
+ EGLBoolean eglSwapBuffersRegionNOK
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint numRects
+ const EGLint *rects
+
+
+ EGLBoolean eglSwapBuffersRegion2NOK
+ EGLDisplay dpy
+ EGLSurface surface
+ EGLint numRects
+ const EGLint *rects
+
+
+ EGLBoolean eglSwapInterval
+ EGLDisplay dpy
+ EGLint interval
+
+
+ EGLBoolean eglTerminate
+ EGLDisplay dpy
+
+
+ EGLBoolean eglUnlockSurfaceKHR
+ EGLDisplay dpy
+ EGLSurface surface
+
+
+ EGLBoolean eglWaitClient
+
+
+ EGLBoolean eglWaitGL
+
+
+ EGLBoolean eglWaitNative
+ EGLint engine
+
+
+ EGLBoolean eglWaitSync
+ EGLDisplay dpy
+ EGLSync sync
+ EGLint flags
+
+
+ EGLint eglWaitSyncKHR
+ EGLDisplay dpy
+ EGLSyncKHR sync
+ EGLint flags
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/egl/generate/eglFunctionList.py b/src/egl/generate/eglFunctionList.py
new file mode 100644
index 00000000000..80cb83437c0
--- /dev/null
+++ b/src/egl/generate/eglFunctionList.py
@@ -0,0 +1,199 @@
+#!/usr/bin/env python
+
+"""
+Contains a list of EGL functions to generate dispatch functions for.
+
+This is used from gen_egl_dispatch.py.
+
+EGL_FUNCTIONS is a sequence of (name, eglData) pairs, where name is the name
+of the function, and eglData is a dictionary containing data about that
+function.
+
+The values in the eglData dictionary are:
+- method (string):
+ How to select a vendor library. See "Method values" below.
+
+- prefix (string):
+ This string is prepended to the name of the dispatch function. If
+ unspecified, the default is "" (an empty string).
+
+- static (boolean)
+ If True, this function should be declared static.
+
+- "public" (boolean)
+ If True, the function should be exported from the library. Vendor libraries
+ generally should not use this.
+
+- extension (string):
+ If specified, this is the name of a macro to check for before defining a
+ function. Used for checking for extension macros and such.
+
+- retval (string):
+ If specified, this is a C expression with the default value to return if we
+ can't find a function to call. By default, it will try to guess from the
+ return type: EGL_NO_whatever for the various handle types, NULL for
+ pointers, and zero for everything else.
+
+method values:
+- "custom"
+ The dispatch stub will be hand-written instead of generated.
+
+- "none"
+ No dispatch function exists at all, but the function should still have an
+ entry in the index array. This is for other functions that a stub may need
+ to call that are implemented in libEGL itself.
+
+- "display"
+ Select a vendor from an EGLDisplay argument.
+
+- "device"
+ Select a vendor from an EGLDeviceEXT argument.
+
+- "current"
+ Select the vendor that owns the current context.
+"""
+
+def _eglFunc(name, method, static=None, public=False, inheader=None, prefix="dispatch_", extension=None, retval=None):
+ """
+ A convenience function to define an entry in the EGL function list.
+ """
+ if static is None:
+ static = (not public and method != "custom")
+ if inheader is None:
+ inheader = (not static)
+ values = {
+ "method" : method,
+ "prefix" : prefix,
+ "extension" : extension,
+ "retval" : retval,
+ "static" : static,
+ "public" : public,
+ "inheader" : inheader,
+ }
+ return (name, values)
+
+EGL_FUNCTIONS = (
+ # EGL_VERSION_1_0
+ _eglFunc("eglChooseConfig", "none"),
+ _eglFunc("eglCopyBuffers", "none"),
+ _eglFunc("eglCreateContext", "none"),
+ _eglFunc("eglCreatePbufferSurface", "none"),
+ _eglFunc("eglCreatePixmapSurface", "none"),
+ _eglFunc("eglCreateWindowSurface", "none"),
+ _eglFunc("eglDestroyContext", "none"),
+ _eglFunc("eglDestroySurface", "none"),
+ _eglFunc("eglGetConfigAttrib", "none"),
+ _eglFunc("eglGetConfigs", "none"),
+ _eglFunc("eglQueryContext", "none"),
+ _eglFunc("eglQuerySurface", "none"),
+ _eglFunc("eglSwapBuffers", "none"),
+ _eglFunc("eglWaitGL", "none"),
+ _eglFunc("eglWaitNative", "none"),
+ _eglFunc("eglTerminate", "none"),
+ _eglFunc("eglInitialize", "none"),
+
+ _eglFunc("eglGetCurrentDisplay", "none"),
+ _eglFunc("eglGetCurrentSurface", "none"),
+ _eglFunc("eglGetDisplay", "none"),
+ _eglFunc("eglGetError", "none"),
+ _eglFunc("eglGetProcAddress", "none"),
+ _eglFunc("eglMakeCurrent", "none"),
+ _eglFunc("eglQueryString", "none"),
+
+ # EGL_VERSION_1_1
+ _eglFunc("eglBindTexImage", "none"),
+ _eglFunc("eglReleaseTexImage", "none"),
+ _eglFunc("eglSurfaceAttrib", "none"),
+ _eglFunc("eglSwapInterval", "none"),
+
+ # EGL_VERSION_1_2
+ _eglFunc("eglCreatePbufferFromClientBuffer", "none"),
+ _eglFunc("eglWaitClient", "none"),
+ _eglFunc("eglBindAPI", "none"),
+ _eglFunc("eglQueryAPI", "none"),
+ _eglFunc("eglReleaseThread", "none"),
+
+ # EGL_VERSION_1_4
+ _eglFunc("eglGetCurrentContext", "none"),
+
+ # EGL_VERSION_1_5
+ _eglFunc("eglCreateSync", "none"),
+ _eglFunc("eglDestroySync", "none"),
+ _eglFunc("eglClientWaitSync", "none"),
+ _eglFunc("eglGetSyncAttrib", "none"),
+ _eglFunc("eglCreateImage", "none"),
+ _eglFunc("eglDestroyImage", "none"),
+ _eglFunc("eglCreatePlatformWindowSurface", "none"),
+ _eglFunc("eglCreatePlatformPixmapSurface", "none"),
+ _eglFunc("eglWaitSync", "none"),
+ _eglFunc("eglGetPlatformDisplay", "none"),
+
+ # EGL_EXT_platform_base
+ _eglFunc("eglCreatePlatformWindowSurfaceEXT", "display"),
+ _eglFunc("eglCreatePlatformPixmapSurfaceEXT", "display"),
+ _eglFunc("eglGetPlatformDisplayEXT", "none"),
+
+ # TODO: Most of these extensions should be provided by the vendor
+ # libraries, not by libEGL. They're here now to make testing everything
+ # else easier.
+
+ # EGL_EXT_swap_buffers_with_damage
+ _eglFunc("eglSwapBuffersWithDamageEXT", "display"),
+
+ # KHR_EXT_swap_buffers_with_damage
+ _eglFunc("eglSwapBuffersWithDamageKHR", "display"),
+
+ # EGL_KHR_cl_event2
+ _eglFunc("eglCreateSync64KHR", "display"),
+
+ # EGL_KHR_fence_sync
+ _eglFunc("eglCreateSyncKHR", "display"),
+ _eglFunc("eglDestroySyncKHR", "display"),
+ _eglFunc("eglClientWaitSyncKHR", "display"),
+ _eglFunc("eglGetSyncAttribKHR", "display"),
+
+ # EGL_KHR_image
+ _eglFunc("eglCreateImageKHR", "display"),
+ _eglFunc("eglDestroyImageKHR", "display"),
+
+ # EGL_KHR_image_base
+ # eglCreateImageKHR already defined in EGL_KHR_image
+ # eglDestroyImageKHR already defined in EGL_KHR_image
+
+ # EGL_KHR_reusable_sync
+ _eglFunc("eglSignalSyncKHR", "display"),
+ # eglCreateSyncKHR already defined in EGL_KHR_fence_sync
+ # eglDestroySyncKHR already defined in EGL_KHR_fence_sync
+ # eglClientWaitSyncKHR already defined in EGL_KHR_fence_sync
+ # eglGetSyncAttribKHR already defined in EGL_KHR_fence_sync
+
+ # EGL_KHR_wait_sync
+ _eglFunc("eglWaitSyncKHR", "display"),
+
+ # EGL_MESA_drm_image
+ _eglFunc("eglCreateDRMImageMESA", "display"),
+ _eglFunc("eglExportDRMImageMESA", "display"),
+
+ # EGL_MESA_image_dma_buf_export
+ _eglFunc("eglExportDMABUFImageQueryMESA", "display"),
+ _eglFunc("eglExportDMABUFImageMESA", "display"),
+
+ # EGL_NOK_swap_region
+ _eglFunc("eglSwapBuffersRegionNOK", "display"),
+
+ # EGL_NV_post_sub_buffer
+ _eglFunc("eglPostSubBufferNV", "display"),
+
+ # EGL_WL_bind_wayland_display
+ _eglFunc("eglCreateWaylandBufferFromImageWL", "display"),
+ _eglFunc("eglUnbindWaylandDisplayWL", "display"),
+ _eglFunc("eglQueryWaylandBufferWL", "display"),
+ _eglFunc("eglBindWaylandDisplayWL", "display"),
+
+ # EGL_CHROMIUM_get_sync_values
+ _eglFunc("eglGetSyncValuesCHROMIUM", "display"),
+
+ # EGL_ANDROID_native_fence_sync
+ _eglFunc("eglDupNativeFenceFDANDROID", "display"),
+)
+
diff --git a/src/egl/generate/egl_other.xml b/src/egl/generate/egl_other.xml
new file mode 100644
index 00000000000..7fe3a9e2722
--- /dev/null
+++ b/src/egl/generate/egl_other.xml
@@ -0,0 +1,47 @@
+
+
+
+ This file contains any EGL extension functions that are missing from
+ the normal egl.xml list.
+
+
+
+
+ struct wl_buffer * eglCreateWaylandBufferFromImageWL
+ EGLDisplay dpy
+ EGLImage image
+
+
+
+ EGLBoolean eglUnbindWaylandDisplayWL
+ EGLDisplay dpy
+ struct wl_display * display
+
+
+
+ EGLBoolean eglQueryWaylandBufferWL
+ EGLDisplay dpy
+ struct wl_resource * buffer
+ EGLint attribute
+ EGLint * value
+
+
+
+ EGLBoolean eglBindWaylandDisplayWL
+ EGLDisplay dpy
+ struct wl_display * display
+
+
+
+
+ EGLBoolean eglGetSyncValuesCHROMIUM
+ EGLDisplay display
+ EGLSurface surface
+ EGLuint64KHR * ust
+ EGLuint64KHR * msc
+ EGLuint64KHR * sbc
+
+
+
+
+
diff --git a/src/egl/generate/genCommon.py b/src/egl/generate/genCommon.py
new file mode 100644
index 00000000000..d493d7bf29a
--- /dev/null
+++ b/src/egl/generate/genCommon.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+
+# (C) Copyright 2015, NVIDIA CORPORATION.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# Authors:
+# Kyle Brenneman
+
+import collections
+import re
+import sys
+import xml.etree.cElementTree as etree
+
+MAPI_TABLE_NUM_DYNAMIC = 4096
+
+_LIBRARY_FEATURE_NAMES = {
+ # libGL and libGLdiapatch both include every function.
+ "gl" : None,
+ "gldispatch" : None,
+ "opengl" : frozenset(( "GL_VERSION_1_0", "GL_VERSION_1_1",
+ "GL_VERSION_1_2", "GL_VERSION_1_3", "GL_VERSION_1_4", "GL_VERSION_1_5",
+ "GL_VERSION_2_0", "GL_VERSION_2_1", "GL_VERSION_3_0", "GL_VERSION_3_1",
+ "GL_VERSION_3_2", "GL_VERSION_3_3", "GL_VERSION_4_0", "GL_VERSION_4_1",
+ "GL_VERSION_4_2", "GL_VERSION_4_3", "GL_VERSION_4_4", "GL_VERSION_4_5",
+ )),
+ "glesv1" : frozenset(("GL_VERSION_ES_CM_1_0", "GL_OES_point_size_array")),
+ "glesv2" : frozenset(("GL_ES_VERSION_2_0", "GL_ES_VERSION_3_0",
+ "GL_ES_VERSION_3_1" "GL_ES_VERSION_3_2",
+ )),
+}
+
+def getFunctions(xmlFiles):
+ """
+ Reads an XML file and returns all of the functions defined in it.
+
+ xmlFile should be the path to Khronos's gl.xml file. The return value is a
+ sequence of FunctionDesc objects, ordered by slot number.
+ """
+ roots = [ etree.parse(xmlFile).getroot() for xmlFile in xmlFiles ]
+ return getFunctionsFromRoots(roots)
+
+def getFunctionsFromRoots(roots):
+ functions = {}
+ for root in roots:
+ for func in _getFunctionList(root):
+ functions[func.name] = func
+ functions = functions.values()
+
+ # Sort the function list by name.
+ functions = sorted(functions, key=lambda f: f.name)
+
+ # Assign a slot number to each function. This isn't strictly necessary,
+ # since you can just look at the index in the list, but it makes it easier
+ # to include the slot when formatting output.
+ for i in range(len(functions)):
+ functions[i] = functions[i]._replace(slot=i)
+
+ return functions
+
+def getExportNamesFromRoots(target, roots):
+ """
+ Goes through the tags from gl.xml and returns a set of OpenGL
+ functions that a library should export.
+
+ target should be one of "gl", "gldispatch", "opengl", "glesv1", or
+ "glesv2".
+ """
+ featureNames = _LIBRARY_FEATURE_NAMES[target]
+ if featureNames is None:
+ return set(func.name for func in getFunctionsFromRoots(roots))
+
+ names = set()
+ for root in roots:
+ features = []
+ for featElem in root.findall("feature"):
+ if featElem.get("name") in featureNames:
+ features.append(featElem)
+ for featElem in root.findall("extensions/extension"):
+ if featElem.get("name") in featureNames:
+ features.append(featElem)
+ for featElem in features:
+ for commandElem in featElem.findall("require/command"):
+ names.add(commandElem.get("name"))
+ return names
+
+class FunctionArg(collections.namedtuple("FunctionArg", "type name")):
+ @property
+ def dec(self):
+ """
+ Returns a "TYPE NAME" string, suitable for a function prototype.
+ """
+ rv = str(self.type)
+ if not rv.endswith("*"):
+ rv += " "
+ rv += self.name
+ return rv
+
+class FunctionDesc(collections.namedtuple("FunctionDesc", "name rt args slot")):
+ def hasReturn(self):
+ """
+ Returns true if the function returns a value.
+ """
+ return (self.rt != "void")
+
+ @property
+ def decArgs(self):
+ """
+ Returns a string with the types and names of the arguments, as you
+ would use in a function declaration.
+ """
+ if not self.args:
+ return "void"
+ else:
+ return ", ".join(arg.dec for arg in self.args)
+
+ @property
+ def callArgs(self):
+ """
+ Returns a string with the names of the arguments, as you would use in a
+ function call.
+ """
+ return ", ".join(arg.name for arg in self.args)
+
+ @property
+ def basename(self):
+ assert self.name.startswith("gl")
+ return self.name[2:]
+
+def _getFunctionList(root):
+ for elem in root.findall("commands/command"):
+ yield _parseCommandElem(elem)
+
+def _parseCommandElem(elem):
+ protoElem = elem.find("proto")
+ (rt, name) = _parseProtoElem(protoElem)
+
+ args = []
+ for ch in elem.findall("param"):
+ # tags have the same format as a tag.
+ args.append(FunctionArg(*_parseProtoElem(ch)))
+ func = FunctionDesc(name, rt, tuple(args), slot=None)
+
+ return func
+
+def _parseProtoElem(elem):
+ # If I just remove the tags and string the text together, I'll get valid C code.
+ text = _flattenText(elem)
+ text = text.strip()
+ m = re.match(r"^(.+)\b(\w+)(?:\s*\[\s*(\d*)\s*\])?$", text, re.S)
+ if m:
+ typename = _fixupTypeName(m.group(1))
+ name = m.group(2)
+ if m.group(3):
+ # HACK: glPathGlyphIndexRangeNV defines an argument like this:
+ # GLuint baseAndCount[2]
+ # Convert it to a pointer and hope for the best.
+ typename += "*"
+ return (typename, name)
+ else:
+ raise ValueError("Can't parse element %r -> %r" % (elem, text))
+
+def _flattenText(elem):
+ """
+ Returns the text in an element and all child elements, with the tags
+ removed.
+ """
+ text = ""
+ if elem.text is not None:
+ text = elem.text
+ for ch in elem:
+ text += _flattenText(ch)
+ if ch.tail is not None:
+ text += ch.tail
+ return text
+
+def _fixupTypeName(typeName):
+ """
+ Converts a typename into a more consistent format.
+ """
+
+ rv = typeName.strip()
+
+ # Replace "GLvoid" with just plain "void".
+ rv = re.sub(r"\bGLvoid\b", "void", rv)
+
+ # Remove the vendor suffixes from types that have a suffix-less version.
+ rv = re.sub(r"\b(GLhalf|GLintptr|GLsizeiptr|GLint64|GLuint64)(?:ARB|EXT|NV|ATI)\b", r"\1", rv)
+
+ rv = re.sub(r"\bGLvoid\b", "void", rv)
+
+ # Clear out any leading and trailing whitespace.
+ rv = rv.strip()
+
+ # Remove any whitespace before a '*'
+ rv = re.sub(r"\s+\*", r"*", rv)
+
+ # Change "foo*" to "foo *"
+ rv = re.sub(r"([^\*])\*", r"\1 *", rv)
+
+ # Condense all whitespace into a single space.
+ rv = re.sub(r"\s+", " ", rv)
+
+ return rv
+
diff --git a/src/egl/generate/gen_egl_dispatch.py b/src/egl/generate/gen_egl_dispatch.py
new file mode 100644
index 00000000000..eeb3f3f9a5a
--- /dev/null
+++ b/src/egl/generate/gen_egl_dispatch.py
@@ -0,0 +1,250 @@
+#!/usr/bin/env python
+
+# (C) Copyright 2016, NVIDIA CORPORATION.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# Authors:
+# Kyle Brenneman
+
+"""
+Generates dispatch functions for EGL.
+
+The list of functions and arguments is read from the Khronos's XML files, with
+additional information defined in the module eglFunctionList.
+"""
+
+import argparse
+import collections
+import imp
+import sys
+import textwrap
+
+import genCommon
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("target", choices=("header", "source"),
+ help="Whether to build the source or header file.")
+ parser.add_argument("func_list_file", help="The function list .py file.")
+ parser.add_argument("xml_files", nargs="+", help="The XML files with the EGL function lists.")
+
+ args = parser.parse_args()
+
+ # The function list is a Python module, but it's specified on the command
+ # line.
+ eglFunctionList = imp.load_source("eglFunctionList", args.func_list_file)
+
+ xmlFunctions = genCommon.getFunctions(args.xml_files)
+ xmlByName = dict((f.name, f) for f in xmlFunctions)
+ functions = []
+ for (name, eglFunc) in eglFunctionList.EGL_FUNCTIONS:
+ func = xmlByName[name]
+ eglFunc = fixupEglFunc(func, eglFunc)
+ functions.append((func, eglFunc))
+
+ # Sort the function list by name.
+ functions = sorted(functions, key=lambda f: f[0].name)
+
+ if args.target == "header":
+ text = generateHeader(functions)
+ elif args.target == "source":
+ text = generateSource(functions)
+ sys.stdout.write(text)
+
+def fixupEglFunc(func, eglFunc):
+ result = dict(eglFunc)
+ if result.get("prefix") is None:
+ result["prefix"] = ""
+
+ if result.get("extension") is not None:
+ text = "defined(" + result["extension"] + ")"
+ result["extension"] = text
+
+ if result["method"] in ("none", "custom"):
+ return result
+
+ if result["method"] not in ("display", "device", "current"):
+ raise ValueError("Invalid dispatch method %r for function %r" % (result["method"], func.name))
+
+ if func.hasReturn():
+ if result.get("retval") is None:
+ result["retval"] = getDefaultReturnValue(func.rt)
+
+ return result
+
+def generateHeader(functions):
+ text = textwrap.dedent(r"""
+ #ifndef G_EGLDISPATCH_STUBS_H
+ #define G_EGLDISPATCH_STUBS_H
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ #include
+ #include
+ #include "glvnd/libeglabi.h"
+
+ """.lstrip("\n"))
+
+ text += "enum {\n"
+ for (func, eglFunc) in functions:
+ text += generateGuardBegin(func, eglFunc)
+ text += " __EGL_DISPATCH_" + func.name + ",\n"
+ text += generateGuardEnd(func, eglFunc)
+ text += " __EGL_DISPATCH_COUNT\n"
+ text += "};\n"
+
+ for (func, eglFunc) in functions:
+ if eglFunc["inheader"]:
+ text += generateGuardBegin(func, eglFunc)
+ text += "{f.rt} EGLAPIENTRY {ex[prefix]}{f.name}({f.decArgs});\n".format(f=func, ex=eglFunc)
+ text += generateGuardEnd(func, eglFunc)
+
+ text += textwrap.dedent(r"""
+ #ifdef __cplusplus
+ }
+ #endif
+ #endif // G_EGLDISPATCH_STUBS_H
+ """)
+ return text
+
+def generateSource(functions):
+ # First, sort the function list by name.
+ text = ""
+ text += '#include "egldispatchstubs.h"\n'
+ text += '#include "g_egldispatchstubs.h"\n'
+ text += "\n"
+
+ for (func, eglFunc) in functions:
+ if eglFunc["method"] not in ("custom", "none"):
+ text += generateGuardBegin(func, eglFunc)
+ text += generateDispatchFunc(func, eglFunc)
+ text += generateGuardEnd(func, eglFunc)
+
+ text += "\n"
+ text += "const char * const __EGL_DISPATCH_FUNC_NAMES[__EGL_DISPATCH_COUNT + 1] = {\n"
+ for (func, eglFunc) in functions:
+ text += generateGuardBegin(func, eglFunc)
+ text += ' "' + func.name + '",\n'
+ text += generateGuardEnd(func, eglFunc)
+ text += " NULL\n"
+ text += "};\n"
+
+ text += "const __eglMustCastToProperFunctionPointerType __EGL_DISPATCH_FUNCS[__EGL_DISPATCH_COUNT + 1] = {\n"
+ for (func, eglFunc) in functions:
+ text += generateGuardBegin(func, eglFunc)
+ if eglFunc["method"] != "none":
+ text += " (__eglMustCastToProperFunctionPointerType) " + eglFunc.get("prefix", "") + func.name + ",\n"
+ else:
+ text += " NULL, // " + func.name + "\n"
+ text += generateGuardEnd(func, eglFunc)
+ text += " NULL\n"
+ text += "};\n"
+
+ return text
+
+def generateGuardBegin(func, eglFunc):
+ ext = eglFunc.get("extension")
+ if ext is not None:
+ return "#if " + ext + "\n"
+ else:
+ return ""
+
+def generateGuardEnd(func, eglFunc):
+ if eglFunc.get("extension") is not None:
+ return "#endif\n"
+ else:
+ return ""
+
+def generateDispatchFunc(func, eglFunc):
+ text = ""
+
+ if eglFunc.get("static"):
+ text += "static "
+ elif eglFunc.get("public"):
+ text += "PUBLIC "
+ text += textwrap.dedent(
+ r"""
+ {f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs})
+ {{
+ typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs});
+ """).lstrip("\n").format(f=func, ef=eglFunc)
+
+ if func.hasReturn():
+ text += " {f.rt} _ret = {ef[retval]};\n".format(f=func, ef=eglFunc)
+
+ text += " _pfn_{f.name} _ptr_{f.name} = (_pfn_{f.name}) ".format(f=func)
+ if eglFunc["method"] == "current":
+ text += "__eglDispatchFetchByCurrent(__EGL_DISPATCH_{f.name});\n".format(f=func)
+
+ elif eglFunc["method"] in ("display", "device"):
+ if eglFunc["method"] == "display":
+ lookupFunc = "__eglDispatchFetchByDisplay"
+ lookupType = "EGLDisplay"
+ else:
+ assert eglFunc["method"] == "device"
+ lookupFunc = "__eglDispatchFetchByDevice"
+ lookupType = "EGLDeviceEXT"
+
+ lookupArg = None
+ for arg in func.args:
+ if arg.type == lookupType:
+ lookupArg = arg.name
+ break
+ if lookupArg is None:
+ raise ValueError("Can't find %s argument for function %s" % (lookupType, func.name,))
+
+ text += "{lookupFunc}({lookupArg}, __EGL_DISPATCH_{f.name});\n".format(
+ f=func, lookupFunc=lookupFunc, lookupArg=lookupArg)
+ else:
+ raise ValueError("Unknown dispatch method: %r" % (eglFunc["method"],))
+
+ text += " if(_ptr_{f.name} != NULL) {{\n".format(f=func)
+ text += " "
+ if func.hasReturn():
+ text += "_ret = "
+ text += "_ptr_{f.name}({f.callArgs});\n".format(f=func)
+ text += " }\n"
+
+ if func.hasReturn():
+ text += " return _ret;\n"
+ text += "}\n"
+ return text
+
+def getDefaultReturnValue(typename):
+ if typename.endswith("*"):
+ return "NULL"
+ elif typename == "EGLDisplay":
+ return "EGL_NO_DISPLAY"
+ elif typename == "EGLContext":
+ return "EGL_NO_CONTEXT"
+ elif typename == "EGLSurface":
+ return "EGL_NO_SURFACE"
+ elif typename == "EGLBoolean":
+ return "EGL_FALSE";
+
+ return "0"
+
+if __name__ == "__main__":
+ main()
+
diff --git a/src/egl/main/50_mesa.json b/src/egl/main/50_mesa.json
new file mode 100644
index 00000000000..8aaaa100ffa
--- /dev/null
+++ b/src/egl/main/50_mesa.json
@@ -0,0 +1,6 @@
+{
+ "file_format_version" : "1.0.0",
+ "ICD" : {
+ "library_path" : "libEGL_mesa.so.0"
+ }
+}
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 5694b5a4ca3..fc243a58e8c 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -657,7 +657,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);
diff --git a/src/egl/main/egldispatchstubs.c b/src/egl/main/egldispatchstubs.c
new file mode 100644
index 00000000000..e02abd7a9e0
--- /dev/null
+++ b/src/egl/main/egldispatchstubs.c
@@ -0,0 +1,110 @@
+#include "egldispatchstubs.h"
+#include "g_egldispatchstubs.h"
+
+#include
+
+#include "eglcurrent.h"
+
+static const __EGLapiExports *exports;
+
+const int __EGL_DISPATCH_FUNC_COUNT = __EGL_DISPATCH_COUNT;
+int __EGL_DISPATCH_FUNC_INDICES[__EGL_DISPATCH_COUNT + 1];
+
+static int FindProcIndex(const char *name)
+{
+ unsigned first = 0;
+ unsigned last = __EGL_DISPATCH_COUNT - 1;
+
+ while (first <= last) {
+ unsigned middle = (first + last) / 2;
+ int comp = strcmp(name,
+ __EGL_DISPATCH_FUNC_NAMES[middle]);
+
+ if (comp > 0)
+ first = middle + 1;
+ else if (comp < 0)
+ last = middle - 1;
+ else
+ return middle;
+ }
+
+ /* Just point to the dummy entry at the end of the respective table */
+ return __EGL_DISPATCH_COUNT;
+}
+
+void __eglInitDispatchStubs(const __EGLapiExports *exportsTable)
+{
+ int i;
+ exports = exportsTable;
+ for (i=0; i<__EGL_DISPATCH_FUNC_COUNT; i++) {
+ __EGL_DISPATCH_FUNC_INDICES[i] = -1;
+ }
+}
+
+void __eglSetDispatchIndex(const char *name, int dispatchIndex)
+{
+ int index = FindProcIndex(name);
+ __EGL_DISPATCH_FUNC_INDICES[index] = dispatchIndex;
+}
+
+void *__eglDispatchFindDispatchFunction(const char *name)
+{
+ int index = FindProcIndex(name);
+ return (void *) __EGL_DISPATCH_FUNCS[index];
+}
+
+static __eglMustCastToProperFunctionPointerType FetchVendorFunc(__EGLvendorInfo *vendor,
+ int index, EGLint errorCode)
+{
+ __eglMustCastToProperFunctionPointerType func = NULL;
+
+ if (vendor != NULL) {
+ func = exports->fetchDispatchEntry(vendor, __EGL_DISPATCH_FUNC_INDICES[index]);
+ }
+ if (func == NULL) {
+ if (errorCode != EGL_SUCCESS) {
+ _eglError(errorCode, __EGL_DISPATCH_FUNC_NAMES[index]);
+ }
+ return NULL;
+ }
+
+ if (!exports->setLastVendor(vendor)) {
+ // Don't bother trying to set an error code in libglvnd. If
+ // setLastVendor failed, then setEGLError would also fail.
+ _eglError(errorCode, __EGL_DISPATCH_FUNC_NAMES[index]);
+ return NULL;
+ }
+
+ return func;
+}
+
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByCurrent(int index)
+{
+ __EGLvendorInfo *vendor;
+
+ // Note: This is only used for the eglWait* functions. For those, if
+ // there's no current context, then they're supposed to do nothing but
+ // return success.
+ exports->threadInit();
+ vendor = exports->getCurrentVendor();
+ return FetchVendorFunc(vendor, index, EGL_SUCCESS);
+}
+
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByDisplay(EGLDisplay dpy, int index)
+{
+ __EGLvendorInfo *vendor;
+
+ exports->threadInit();
+ vendor = exports->getVendorFromDisplay(dpy);
+ return FetchVendorFunc(vendor, index, EGL_BAD_DISPLAY);
+}
+
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByDevice(EGLDeviceEXT dev, int index)
+{
+ __EGLvendorInfo *vendor;
+
+ exports->threadInit();
+ vendor = exports->getVendorFromDevice(dev);
+ return FetchVendorFunc(vendor, index, EGL_BAD_DEVICE_EXT);
+}
+
diff --git a/src/egl/main/egldispatchstubs.h b/src/egl/main/egldispatchstubs.h
new file mode 100644
index 00000000000..7861ea5e61a
--- /dev/null
+++ b/src/egl/main/egldispatchstubs.h
@@ -0,0 +1,26 @@
+#ifndef EGLDISPATCHSTUBS_H
+#define EGLDISPATCHSTUBS_H
+
+#include "glvnd/libeglabi.h"
+
+// These variables are all generated along with the dispatch stubs.
+extern const int __EGL_DISPATCH_FUNC_COUNT;
+extern const char * const __EGL_DISPATCH_FUNC_NAMES[];
+extern int __EGL_DISPATCH_FUNC_INDICES[];
+extern const __eglMustCastToProperFunctionPointerType __EGL_DISPATCH_FUNCS[];
+
+void __eglInitDispatchStubs(const __EGLapiExports *exportsTable);
+void __eglSetDispatchIndex(const char *name, int index);
+
+/**
+ * Returns the dispatch function for the given name, or \c NULL if the function
+ * isn't supported.
+ */
+void *__eglDispatchFindDispatchFunction(const char *name);
+
+// Helper functions used by the generated stubs.
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByDisplay(EGLDisplay dpy, int index);
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByDevice(EGLDeviceEXT dpy, int index);
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByCurrent(int index);
+
+#endif // EGLDISPATCHSTUBS_H
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index cb41063e321..baf96bb1ec5 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -29,6 +29,8 @@
#include
+#include
+#include
#include
#include "c11/threads.h"
@@ -50,9 +52,13 @@ struct _egl_global _eglGlobal =
_eglFiniDisplay
},
- /* ClientExtensionString */
+ /* ClientOnlyExtensionString */
"EGL_EXT_client_extensions"
" EGL_EXT_platform_base"
+ " EGL_KHR_client_get_all_proc_addresses"
+ " EGL_KHR_debug",
+
+ /* PlatformExtensionString */
#ifdef HAVE_WAYLAND_PLATFORM
" EGL_EXT_platform_wayland"
#endif
@@ -65,8 +71,9 @@ struct _egl_global _eglGlobal =
#ifdef HAVE_SURFACELESS_PLATFORM
" EGL_MESA_platform_surfaceless"
#endif
- " EGL_KHR_client_get_all_proc_addresses"
- " EGL_KHR_debug",
+ "",
+
+ NULL, /* ClientExtensionsString */
NULL, /* debugCallback */
_EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR, /* debugTypesEnabled */
@@ -101,3 +108,37 @@ _eglAddAtExitCall(void (*func)(void))
mtx_unlock(_eglGlobal.Mutex);
}
}
+
+const char *
+_eglGetClientExtensionString(void)
+{
+ const char *ret;
+
+ mtx_lock(_eglGlobal.Mutex);
+
+ if (_eglGlobal.ClientExtensionString == NULL) {
+ size_t clientLen = strlen(_eglGlobal.ClientOnlyExtensionString);
+ size_t platformLen = strlen(_eglGlobal.PlatformExtensionString);
+
+ _eglGlobal.ClientExtensionString = (char *) malloc(clientLen + platformLen + 1);
+ if (_eglGlobal.ClientExtensionString != NULL) {
+ char *ptr = _eglGlobal.ClientExtensionString;
+
+ memcpy(ptr, _eglGlobal.ClientOnlyExtensionString, clientLen);
+ ptr += clientLen;
+
+ if (platformLen > 0) {
+ // Note that if PlatformExtensionString is not empty, then it will
+ // already have a leading space.
+ assert(_eglGlobal.PlatformExtensionString[0] == ' ');
+ memcpy(ptr, _eglGlobal.PlatformExtensionString, platformLen);
+ ptr += platformLen;
+ }
+ *ptr = '\0';
+ }
+ }
+ ret = _eglGlobal.ClientExtensionString;
+
+ mtx_unlock(_eglGlobal.Mutex);
+ return ret;
+}
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index ec4f3d04a36..c6ef59d4820 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -57,7 +57,15 @@ struct _egl_global
EGLint NumAtExitCalls;
void (*AtExitCalls[10])(void);
- const char *ClientExtensionString;
+ /*
+ * Under libglvnd, the client extension string has to be split into two
+ * strings, one for platform extensions, and one for everything else. So,
+ * define separate strings for them. _eglGetClientExtensionString will
+ * concatenate them together for a non-libglvnd build.
+ */
+ const char *ClientOnlyExtensionString;
+ const char *PlatformExtensionString;
+ char *ClientExtensionString;
EGLDEBUGPROCKHR debugCallback;
unsigned int debugTypesEnabled;
@@ -76,4 +84,7 @@ static inline unsigned int DebugBitFromType(EGLenum type)
return (1 << (type - EGL_DEBUG_MSG_CRITICAL_KHR));
}
+extern const char *
+_eglGetClientExtensionString(void);
+
#endif /* EGLGLOBALS_INCLUDED */
diff --git a/src/egl/main/eglglvnd.c b/src/egl/main/eglglvnd.c
new file mode 100644
index 00000000000..6b984ed6c28
--- /dev/null
+++ b/src/egl/main/eglglvnd.c
@@ -0,0 +1,82 @@
+#include
+#include
+
+#include
+
+#include "eglcurrent.h"
+#include "egldispatchstubs.h"
+#include "eglglobals.h"
+
+static const __EGLapiExports *__eglGLVNDApiExports = NULL;
+
+static const char * EGLAPIENTRY
+__eglGLVNDQueryString(EGLDisplay dpy, EGLenum name)
+{
+ // For client extensions, return the list of non-platform extensions. The
+ // platform extensions are returned by __eglGLVNDGetVendorString.
+ if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
+ return _eglGlobal.ClientOnlyExtensionString;
+
+ // For everything else, forward to the normal eglQueryString function.
+ return eglQueryString(dpy, name);
+}
+
+static const char *
+__eglGLVNDGetVendorString(int name)
+{
+ if (name == __EGL_VENDOR_STRING_PLATFORM_EXTENSIONS) {
+ const char *str = _eglGlobal.PlatformExtensionString;
+ // The platform extension string may have a leading space. If it does,
+ // then skip over it.
+ while (*str == ' ') {
+ str++;
+ }
+ return str;
+ }
+
+ return NULL;
+}
+
+static EGLDisplay
+__eglGLVNDGetPlatformDisplay(EGLenum platform, void *native_display,
+ const EGLAttrib *attrib_list)
+{
+ if (platform == EGL_NONE) {
+ assert(native_display == (void *) EGL_DEFAULT_DISPLAY);
+ assert(attrib_list == NULL);
+ return eglGetDisplay((EGLNativeDisplayType) native_display);
+ } else {
+ return eglGetPlatformDisplay(platform, native_display, attrib_list);
+ }
+}
+
+static void *
+__eglGLVNDGetProcAddress(const char *procName)
+{
+ if (strcmp(procName, "eglQueryString") == 0)
+ return (void *) __eglGLVNDQueryString;
+
+ return (void *) eglGetProcAddress(procName);
+}
+
+EGLAPI EGLBoolean
+__egl_Main(uint32_t version, const __EGLapiExports *exports,
+ __EGLvendorInfo *vendor, __EGLapiImports *imports)
+{
+ if (EGL_VENDOR_ABI_GET_MAJOR_VERSION(version) !=
+ EGL_VENDOR_ABI_MAJOR_VERSION)
+ return EGL_FALSE;
+
+ __eglGLVNDApiExports = exports;
+ __eglInitDispatchStubs(exports);
+
+ imports->getPlatformDisplay = __eglGLVNDGetPlatformDisplay;
+ imports->getSupportsAPI = _eglIsApiValid;
+ imports->getVendorString = __eglGLVNDGetVendorString;
+ imports->getProcAddress = __eglGLVNDGetProcAddress;
+ imports->getDispatchAddress = __eglDispatchFindDispatchFunction;
+ imports->setDispatchIndex = __eglSetDispatchIndex;
+
+ return EGL_TRUE;
+}
+
diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am
index 5c0376408cc..41e4939a0b7 100644
--- a/src/glx/Makefile.am
+++ b/src/glx/Makefile.am
@@ -155,7 +155,7 @@ libglx_la_LIBADD += \
$(builddir)/windows/libwindowsglx.la
endif
-if USE_LIBGLVND_GLX
+if USE_LIBGLVND
AM_CFLAGS += \
-DGL_LIB_NAME=\"lib@GL_LIB@.so.0\" \
$(GLVND_CFLAGS)
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 70733acb23f..0d29e5635e9 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -56,7 +56,7 @@
#include "glxextensions.h"
-#if defined(USE_LIBGLVND_GLX)
+#if defined(USE_LIBGLVND)
#define _GLX_PUBLIC _X_HIDDEN
#else
#define _GLX_PUBLIC _X_EXPORT