From 06c325b36bd6563a41cbc0261a8f9dd4e00f5572 Mon Sep 17 00:00:00 2001 From: Kyle Brenneman Date: Fri, 8 Jul 2016 15:21:17 -0600 Subject: [PATCH] egl: glvnd support [hdegoede@redhat.com: Rebased on 13.0 branch] --- configure.ac | 159 ++- src/egl/Makefile.am | 65 +- src/egl/generate/egl.xml | 2412 ++++++++++++++++++++++++++++++++++ src/egl/generate/eglFunctionList.py | 191 +++ src/egl/generate/egl_other.xml | 47 + src/egl/generate/genCommon.py | 223 ++++ src/egl/generate/gen_egl_dispatch.py | 223 ++++ src/egl/main/50_mesa.json.in | 6 + src/egl/main/eglapi.c | 6 +- src/egl/main/egldispatchstubs.c | 110 ++ src/egl/main/egldispatchstubs.h | 26 + src/egl/main/eglglobals.c | 42 +- src/egl/main/eglglobals.h | 13 +- src/egl/main/eglglvnd.c | 75 ++ 14 files changed, 3512 insertions(+), 86 deletions(-) create mode 100644 src/egl/generate/egl.xml create mode 100644 src/egl/generate/eglFunctionList.py create mode 100644 src/egl/generate/egl_other.xml create mode 100644 src/egl/generate/genCommon.py create mode 100644 src/egl/generate/gen_egl_dispatch.py create mode 100644 src/egl/main/50_mesa.json.in create mode 100644 src/egl/main/egldispatchstubs.c create mode 100644 src/egl/main/egldispatchstubs.h create mode 100644 src/egl/main/eglglvnd.c diff --git a/configure.ac b/configure.ac index d215b63..e49711d 100644 --- a/configure.ac +++ b/configure.ac @@ -521,8 +521,6 @@ else DEFINES="$DEFINES -DNDEBUG" fi -DEFAULT_GL_LIB_NAME=GL - dnl dnl Check if linker supports -Bsymbolic dnl @@ -620,23 +618,6 @@ esac AM_CONDITIONAL(HAVE_COMPAT_SYMLINKS, test "x$HAVE_COMPAT_SYMLINKS" = xyes) -DEFAULT_GL_LIB_NAME=GL - -dnl -dnl Libglvnd configuration -dnl -AC_ARG_ENABLE([libglvnd], - [AS_HELP_STRING([--enable-libglvnd], - [Build for libglvnd @<:@default=disabled@:>@])], - [enable_libglvnd="$enableval"], - [enable_libglvnd=no]) -AM_CONDITIONAL(USE_LIBGLVND_GLX, test "x$enable_libglvnd" = xyes) -#AM_COND_IF([USE_LIBGLVND_GLX], [DEFINES="${DEFINES} -DUSE_LIBGLVND_GLX=1"]) -if test "x$enable_libglvnd" = xyes ; then - DEFINES="${DEFINES} -DUSE_LIBGLVND_GLX=1" - DEFAULT_GL_LIB_NAME=GLX_mesa -fi - dnl dnl library names dnl @@ -670,36 +651,6 @@ esac AC_SUBST([LIB_EXT]) -AC_ARG_WITH([gl-lib-name], - [AS_HELP_STRING([--with-gl-lib-name@<:@=NAME@:>@], - [specify GL library name @<:@default=GL@:>@])], - [GL_LIB=$withval], - [GL_LIB="$DEFAULT_GL_LIB_NAME"]) -AC_ARG_WITH([osmesa-lib-name], - [AS_HELP_STRING([--with-osmesa-lib-name@<:@=NAME@:>@], - [specify OSMesa library name @<:@default=OSMesa@:>@])], - [OSMESA_LIB=$withval], - [OSMESA_LIB=OSMesa]) -AS_IF([test "x$GL_LIB" = xyes], [GL_LIB="$DEFAULT_GL_LIB_NAME"]) -AS_IF([test "x$OSMESA_LIB" = xyes], [OSMESA_LIB=OSMesa]) - -dnl -dnl Mangled Mesa support -dnl -AC_ARG_ENABLE([mangling], - [AS_HELP_STRING([--enable-mangling], - [enable mangled symbols and library name @<:@default=disabled@:>@])], - [enable_mangling="${enableval}"], - [enable_mangling=no] -) -if test "x${enable_mangling}" = "xyes" ; then - DEFINES="${DEFINES} -DUSE_MGL_NAMESPACE" - GL_LIB="Mangled${GL_LIB}" - OSMESA_LIB="Mangled${OSMESA_LIB}" -fi -AC_SUBST([GL_LIB]) -AC_SUBST([OSMESA_LIB]) - dnl dnl potentially-infringing-but-nobody-knows-for-sure stuff dnl @@ -1107,31 +1058,98 @@ AM_CONDITIONAL(HAVE_GALLIUM_XLIB_GLX, test "x$enable_glx" = xgallium-xlib) dnl dnl Libglvnd configuration dnl + +DEFAULT_GL_LIB_NAME=GL +EGL_LIB=EGL + 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) -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 - dnl are built - case "x$enable_glx" in - xno) - AC_MSG_ERROR([cannot build libglvnd without GLX]) - ;; - xxlib | xgallium-xlib ) - AC_MSG_ERROR([cannot build libgvnd when Xlib-GLX or Gallium-Xlib-GLX is enabled]) - ;; - xdri) - ;; - esac +AM_CONDITIONAL(USE_LIBGLVND_GLX, test "x$enable_libglvnd_glx" = xyes) + +AC_ARG_ENABLE([libglvnd-glx], + [AS_HELP_STRING([--enable-libglvnd-glx], + [Build GLX for libglvnd @<:@default=disabled@:>@])], + [enable_libglvnd_glx="$enableval"], + [enable_libglvnd_glx="$enable_libglvnd"]) +AM_CONDITIONAL(USE_LIBGLVND_GLX, test "x$enable_libglvnd_glx" = xyes) + +AC_ARG_ENABLE([libglvnd-egl], + [AS_HELP_STRING([--enable-libglvnd-egl], + [Build EGL for libglvnd @<:@default=disabled@:>@])], + [enable_libglvnd_egl="$enableval"], + [enable_libglvnd_egl="$enable_libglvnd"]) +AM_CONDITIONAL(USE_LIBGLVND_EGL, test "x$enable_libglvnd_egl" = xyes) + +if test "x$enable_libglvnd_glx" = xyes -o "x$enable_libglvnd_egl" = xyes ; then + PKG_CHECK_VAR(LIBGLVND_DATADIR, libglvnd, datadir) + AC_SUBST([LIBGLVND_DATADIR]) + + if test "x$enable_libglvnd_egl" = xyes ; then + PKG_CHECK_MODULES([GLVND], libglvnd >= 0.2.0) + + if test "x$enable_egl" != xyes ; then + AC_MSG_ERROR([cannot build libglvnd without EGL]) + fi + DEFINES="${DEFINES} -DUSE_LIBGLVND_EGL=1" + EGL_LIB=EGL_mesa + else + PKG_CHECK_MODULES([GLVND], libglvnd >= 0.1.0) + fi + + if test "x$enable_libglvnd_glx" = 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 + dnl are built + case "x$enable_glx" in + xno) + AC_MSG_ERROR([cannot build libglvnd without GLX]) + ;; + xxlib | xgallium-xlib ) + AC_MSG_ERROR([cannot build libgvnd when Xlib-GLX or Gallium-Xlib-GLX is enabled]) + ;; + xdri) + ;; + esac + + DEFINES="${DEFINES} -DUSE_LIBGLVND_GLX=1" + DEFAULT_GL_LIB_NAME=GLX_mesa + fi +fi + +AC_SUBST([EGL_LIB]) + +AC_ARG_WITH([gl-lib-name], + [AS_HELP_STRING([--with-gl-lib-name@<:@=NAME@:>@], + [specify GL library name @<:@default=GL@:>@])], + [GL_LIB=$withval], + [GL_LIB="$DEFAULT_GL_LIB_NAME"]) +AC_ARG_WITH([osmesa-lib-name], + [AS_HELP_STRING([--with-osmesa-lib-name@<:@=NAME@:>@], + [specify OSMesa library name @<:@default=OSMesa@:>@])], + [OSMESA_LIB=$withval], + [OSMESA_LIB=OSMesa]) +AS_IF([test "x$GL_LIB" = xyes], [GL_LIB="$DEFAULT_GL_LIB_NAME"]) +AS_IF([test "x$OSMESA_LIB" = xyes], [OSMESA_LIB=OSMesa]) - PKG_CHECK_MODULES([GLVND], libglvnd >= 0.1.0) - DEFINES="${DEFINES} -DUSE_LIBGLVND_GLX=1" - DEFAULT_GL_LIB_NAME=GLX_mesa +dnl +dnl Mangled Mesa support +dnl +AC_ARG_ENABLE([mangling], + [AS_HELP_STRING([--enable-mangling], + [enable mangled symbols and library name @<:@default=disabled@:>@])], + [enable_mangling="${enableval}"], + [enable_mangling=no] +) +if test "x${enable_mangling}" = "xyes" ; then + DEFINES="${DEFINES} -DUSE_MGL_NAMESPACE" + GL_LIB="Mangled${GL_LIB}" + OSMESA_LIB="Mangled${OSMESA_LIB}" fi +AC_SUBST([GL_LIB]) +AC_SUBST([OSMESA_LIB]) # Check for libdrm PKG_CHECK_MODULES([LIBDRM], [libdrm >= $LIBDRM_REQUIRED], @@ -2685,6 +2703,7 @@ AC_CONFIG_FILES([Makefile src/compiler/Makefile src/egl/Makefile src/egl/main/egl.pc + src/egl/main/50_mesa.json src/egl/wayland/wayland-drm/Makefile src/egl/wayland/wayland-egl/Makefile src/egl/wayland/wayland-egl/wayland-egl.pc @@ -2846,11 +2865,15 @@ xgallium-xlib) echo " GLX: $enable_glx" ;; esac +if test "x$enable_glx" != xno; then + echo " GLX libglvnd: $enable_libglvnd_glx" +fi dnl EGL echo "" echo " EGL: $enable_egl" if test "$enable_egl" = yes; then + echo " EGL libglvnd: $enable_libglvnd_egl" echo " EGL platforms: $egl_platforms" egl_drivers="" diff --git a/src/egl/Makefile.am b/src/egl/Makefile.am index 304b0d3..1839155 100644 --- a/src/egl/Makefile.am +++ b/src/egl/Makefile.am @@ -32,16 +32,53 @@ AM_CFLAGS = \ $(EGL_CFLAGS) \ -D_EGL_NATIVE_PLATFORM=$(EGL_NATIVE_PLATFORM) -lib_LTLIBRARIES = libEGL.la +if USE_LIBGLVND_EGL +AM_CFLAGS += \ + $(GLVND_CFLAGS) + +LIBEGL_C_FILES += \ + main/eglglvnd.c \ + main/egldispatchstubs.h \ + main/egldispatchstubs.c \ + g_egldispatchstubs.c + +EGL_LIB_VERSION=0 + +PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) +g_egldispatchstubs.c: generate/gen_egl_dispatch.py generate/egl.xml \ + generate/eglFunctionList.py generate/genCommon.py + $(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: generate/gen_egl_dispatch.py generate/egl.xml \ + generate/eglFunctionList.py generate/genCommon.py + $(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) + +vendorjsondir = @LIBGLVND_DATADIR@/glvnd/egl_vendor.d +vendorjson_DATA = main/50_mesa.json + +else +EGL_LIB_VERSION=1:0 +endif + +lib_LTLIBRARIES = lib@EGL_LIB@.la -libEGL_la_SOURCES = \ +lib@EGL_LIB@_la_SOURCES = \ $(LIBEGL_C_FILES) -libEGL_la_LIBADD = \ +lib@EGL_LIB@_la_LIBADD = \ $(EGL_LIB_DEPS) -libEGL_la_LDFLAGS = \ +lib@EGL_LIB@_la_LDFLAGS = \ -no-undefined \ - -version-number 1:0 \ + -version-number $(EGL_LIB_VERSION) \ $(BSYMBOLIC) \ $(GC_SECTIONS) \ $(LD_NO_UNDEFINED) @@ -52,7 +89,7 @@ dri3_backend_FILES = if HAVE_PLATFORM_X11 AM_CFLAGS += -DHAVE_X11_PLATFORM AM_CFLAGS += $(XCB_DRI2_CFLAGS) -libEGL_la_LIBADD += $(XCB_DRI2_LIBS) +lib@EGL_LIB@_la_LIBADD += $(XCB_DRI2_LIBS) dri2_backend_FILES += drivers/dri2/platform_x11.c if HAVE_DRI3 @@ -60,22 +97,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 +lib@EGL_LIB@_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 +lib@EGL_LIB@_la_LIBADD += $(WAYLAND_LIBS) +lib@EGL_LIB@_la_LIBADD += $(LIBDRM_LIBS) +lib@EGL_LIB@_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 +lib@EGL_LIB@_la_LIBADD += $(top_builddir)/src/gbm/libgbm.la dri2_backend_FILES += drivers/dri2/platform_drm.c endif @@ -100,13 +137,13 @@ AM_CFLAGS += \ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ -D_EGL_BUILT_IN_DRIVER_DRI2 -libEGL_la_SOURCES += \ +lib@EGL_LIB@_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) +lib@EGL_LIB@_la_LIBADD += $(top_builddir)/src/loader/libloader.la +lib@EGL_LIB@_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS) $(CLOCK_LIB) endif include $(top_srcdir)/install-lib-links.mk diff --git a/src/egl/generate/egl.xml b/src/egl/generate/egl.xml new file mode 100644 index 0000000..f6dbbc0 --- /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 0000000..39d3dd5 --- /dev/null +++ b/src/egl/generate/eglFunctionList.py @@ -0,0 +1,191 @@ +#!/usr/bin/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=False, public=False, inheader=None, prefix="", extension=None, retval=None): + """ + A convenience function to define an entry in the EGL function list. + """ + if (inheader == None): + inheader = (not public) + 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"), + + # 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"), +) + diff --git a/src/egl/generate/egl_other.xml b/src/egl/generate/egl_other.xml new file mode 100644 index 0000000..7fe3a9e --- /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 0000000..5781275 --- /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 sys +import collections +import re +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 xrange(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 == 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(len(self.args) == 0): + 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 != None): + text = elem.text + for ch in elem: + text += _flattenText(ch) + if(ch.tail != 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 0000000..1e145aa --- /dev/null +++ b/src/egl/generate/gen_egl_dispatch.py @@ -0,0 +1,223 @@ +#!/usr/bin/python + +""" +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 sys +import collections +import imp + +import genCommon + +def main(): + if (len(sys.argv) < 4): + print("Usage: %r source|header [xml_file...]" % (sys.argv[0],)) + sys.exit(2) + + target = sys.argv[1] + funcListFile = sys.argv[2] + xmlFiles = sys.argv[3:] + + # The function list is a Python module, but it's specified on the command + # line. + eglFunctionList = imp.load_source("eglFunctionList", funcListFile) + + xmlFunctions = genCommon.getFunctions(xmlFiles) + 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 (target == "header"): + text = generateHeader(functions) + elif (target == "source"): + text = generateSource(functions) + else: + raise ValueError("Invalid target: %r" % (target,)) + sys.stdout.write(text) + +def fixupEglFunc(func, eglFunc): + result = dict(eglFunc) + if (result.get("prefix") == None): + result["prefix"] = "" + + if (result.get("extension") != 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") == None): + result["retval"] = getDefaultReturnValue(func.rt) + + return result + +def generateHeader(functions): + text = 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 += 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 != None): + return "#if " + ext + "\n" + else: + return "" + +def generateGuardEnd(func, eglFunc): + if (eglFunc.get("extension") != None): + return "#endif\n" + else: + return "" + +def generateDispatchFunc(func, eglFunc): + text = "" + + if (eglFunc.get("static")): + text += "static " + elif (eglFunc.get("public")): + text += "PUBLIC " + text += r"""{f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs}) +{{ + typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs}); +""".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 == 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.in b/src/egl/main/50_mesa.json.in new file mode 100644 index 0000000..58e2bd2 --- /dev/null +++ b/src/egl/main/50_mesa.json.in @@ -0,0 +1,6 @@ +{ + "file_format_version" : "1.0.0", + "ICD" : { + "library_path" : "lib@EGL_LIB@.so.0" + } +} diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 471cf7e..7ee9d87 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -644,7 +644,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 0000000..e02abd7 --- /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 0000000..7861ea5 --- /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 cb41063..e59e8f3 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,8 +52,11 @@ struct _egl_global _eglGlobal = _eglFiniDisplay }, - /* ClientExtensionString */ + /* ClientOnlyExtensionString */ "EGL_EXT_client_extensions" + " EGL_KHR_client_get_all_proc_addresses", + + /* PlatformExtensionString */ " EGL_EXT_platform_base" #ifdef HAVE_WAYLAND_PLATFORM " EGL_EXT_platform_wayland" @@ -65,9 +70,10 @@ 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 +107,35 @@ _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 + 2); + if (_eglGlobal.ClientExtensionString != NULL) { + char *ptr = _eglGlobal.ClientExtensionString; + + memcpy(ptr, _eglGlobal.ClientOnlyExtensionString, clientLen); + ptr += clientLen; + + if (platformLen > 0) { + *ptr++ = ' '; + 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 ec4f3d0..e3a7f58 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -57,12 +57,23 @@ 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; }; +extern const char * +_eglGetClientExtensionString(void); + extern struct _egl_global _eglGlobal; diff --git a/src/egl/main/eglglvnd.c b/src/egl/main/eglglvnd.c new file mode 100644 index 0000000..81fdb45 --- /dev/null +++ b/src/egl/main/eglglvnd.c @@ -0,0 +1,75 @@ +#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) + return _eglGlobal.PlatformExtensionString; + + 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; +} + -- 2.9.3