Not actually working yet, but it's a snapshot to start from.macos/v1.5.9
parent
db667aa8b8
commit
a909eb4a22
@ -0,0 +1,90 @@ |
|||||||
|
# |
||||||
|
# X.Org module default exclusion patterns |
||||||
|
# The next section if for module specific patterns |
||||||
|
# |
||||||
|
# Do not edit the following section |
||||||
|
# GNU Build System (Autotools) |
||||||
|
aclocal.m4 |
||||||
|
autom4te.cache/ |
||||||
|
autoscan.log |
||||||
|
ChangeLog |
||||||
|
compile |
||||||
|
config.guess |
||||||
|
config.h |
||||||
|
config.h.in |
||||||
|
config.log |
||||||
|
config-ml.in |
||||||
|
config.py |
||||||
|
config.status |
||||||
|
config.status.lineno |
||||||
|
config.sub |
||||||
|
configure |
||||||
|
configure.scan |
||||||
|
depcomp |
||||||
|
.deps/ |
||||||
|
INSTALL |
||||||
|
install-sh |
||||||
|
.libs/ |
||||||
|
libtool |
||||||
|
libtool.m4 |
||||||
|
ltmain.sh |
||||||
|
lt~obsolete.m4 |
||||||
|
ltoptions.m4 |
||||||
|
ltsugar.m4 |
||||||
|
ltversion.m4 |
||||||
|
Makefile |
||||||
|
Makefile.in |
||||||
|
mdate-sh |
||||||
|
missing |
||||||
|
mkinstalldirs |
||||||
|
*.pc |
||||||
|
py-compile |
||||||
|
stamp-h? |
||||||
|
symlink-tree |
||||||
|
texinfo.tex |
||||||
|
ylwrap |
||||||
|
src/sna/git_version.h |
||||||
|
src/sna/brw/brw_test |
||||||
|
|
||||||
|
# Do not edit the following section |
||||||
|
# Edit Compile Debug Document Distribute |
||||||
|
*~ |
||||||
|
*.[0-9] |
||||||
|
*.[0-9]x |
||||||
|
*.bak |
||||||
|
*.bin |
||||||
|
core |
||||||
|
*.dll |
||||||
|
*.exe |
||||||
|
*-ISO*.bdf |
||||||
|
*-JIS*.bdf |
||||||
|
*-KOI8*.bdf |
||||||
|
*.kld |
||||||
|
*.ko |
||||||
|
*.ko.cmd |
||||||
|
*.lai |
||||||
|
*.l[oa] |
||||||
|
*.[oa] |
||||||
|
*.obj |
||||||
|
*.patch |
||||||
|
*.so |
||||||
|
*.pcf.gz |
||||||
|
*.pdb |
||||||
|
*.tar.bz2 |
||||||
|
*.tar.gz |
||||||
|
# |
||||||
|
# Add & Override patterns for gldispatch |
||||||
|
# |
||||||
|
# Edit the following section as needed |
||||||
|
# For example, !report.pc overrides *.pc. See 'man gitignore' |
||||||
|
# |
||||||
|
configure.lineno |
||||||
|
.dirstamp |
||||||
|
|
||||||
|
gl_generated_dispatch.c |
||||||
|
gl_generated.h |
||||||
|
gl_generated_vtable_defines.h |
||||||
|
|
||||||
|
glx_generated_dispatch.c |
||||||
|
glx_generated.h |
||||||
|
glx_generated_vtable_defines.h |
@ -0,0 +1,36 @@ |
|||||||
|
# Copyright 2005 Adam Jackson.
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# ADAM JACKSON 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.
|
||||||
|
|
||||||
|
SUBDIRS = src
|
||||||
|
|
||||||
|
#if HAVE_X11
|
||||||
|
#SUBDIRS += test
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = epoxy.pc
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
epoxy.pc.in \
|
||||||
|
registry/egl.xml \
|
||||||
|
registry/gl.xml \
|
||||||
|
registry/glx.xml \
|
||||||
|
registry/wgl.xml \
|
||||||
|
$()
|
@ -0,0 +1,61 @@ |
|||||||
|
Epoxy is a library for handling OpenGL function pointer management for |
||||||
|
you. |
||||||
|
|
||||||
|
It hides the complexity of dlopen(), dlsym(), glXGetProcAddress(), |
||||||
|
eglGetProcAddress(), etc. from the app developer, with very little |
||||||
|
knowledge needed on their part. Just read your GL specs and write |
||||||
|
code using undecorated function names like glCompileShader(). |
||||||
|
|
||||||
|
Don't forget to check for your extensions or versions being present |
||||||
|
before you use them, just like before! We'll tell you what you forgot |
||||||
|
to check for instead of just segfaulting, though. |
||||||
|
|
||||||
|
Why does this library exist? |
||||||
|
---------------------------- |
||||||
|
|
||||||
|
OpenGL on Linux (and other platforms) made some ABI decisions back in |
||||||
|
the days when symbol versioning and dlsym() weren't as widely |
||||||
|
available, that resulted in window-systems-specific APIs that looked |
||||||
|
kind of like dlsym. They allowed you to build an app that required |
||||||
|
OpenGL 1.2, but could optionally use features of OpenGL 1.4 if the |
||||||
|
implementation made those available through the glXGetProcAddress() |
||||||
|
(or other similarly-named) mechanism. |
||||||
|
|
||||||
|
The downside is that the fixed OpenGL 1.2 ABI means that application |
||||||
|
developers have to GetProcAddress() out every modern GL entrypoint |
||||||
|
they want to use and stash that function pointer somewhere. Sometimes |
||||||
|
this is done in a pretty way (like libGLEW), sometimes it is done in |
||||||
|
an ad-hoc way (like most applications I've seen), but it's never done |
||||||
|
as well as we think it could be done. |
||||||
|
|
||||||
|
Additionally, the proliferation of OpenGL ABIs (desktop GL, GLESv1, |
||||||
|
GLESv2) and window systems (GLX, AGL, WGL, all versus EGL) means that |
||||||
|
|
||||||
|
Switching your code to using epoxy |
||||||
|
---------------------------------- |
||||||
|
|
||||||
|
It should be as easy as replacing: |
||||||
|
|
||||||
|
> #include <GL/gl.h> |
||||||
|
> #include <GL/glx.h> |
||||||
|
> #include <GL/glext.h> |
||||||
|
|
||||||
|
with: |
||||||
|
|
||||||
|
> #include <epoxy/gl.h> |
||||||
|
> #include <epoxy/glx.h> |
||||||
|
|
||||||
|
Additionally, some new helpers become available, so you don't have to |
||||||
|
write them: |
||||||
|
|
||||||
|
int epoxy_gl_version() returns the GL version: |
||||||
|
|
||||||
|
12 for GL 1.2 |
||||||
|
20 for GL 2.0 |
||||||
|
44 for GL 4.4 |
||||||
|
|
||||||
|
bool epoxy_has_gl_extension() returns whether a GL extension is |
||||||
|
available ("GL_ARB_texture_buffer_object", for example). |
||||||
|
|
||||||
|
Note that this is not terribly fast, so keep it out of your hot paths, |
||||||
|
ok? |
@ -0,0 +1,14 @@ |
|||||||
|
#! /bin/sh |
||||||
|
|
||||||
|
srcdir=`dirname $0` |
||||||
|
test -z "$srcdir" && srcdir=. |
||||||
|
|
||||||
|
ORIGDIR=`pwd` |
||||||
|
cd $srcdir |
||||||
|
|
||||||
|
autoreconf -v --install || exit 1 |
||||||
|
cd $ORIGDIR || exit $? |
||||||
|
|
||||||
|
if test -z "$NOCONFIGURE"; then |
||||||
|
$srcdir/configure "$@" |
||||||
|
fi |
@ -0,0 +1,75 @@ |
|||||||
|
# Copyright © 2013 Intel Corporation |
||||||
|
# |
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
# copy of this software and associated documentation files (the "Software"), |
||||||
|
# to deal in the Software without restriction, including without limitation |
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
# Software is furnished to do so, subject to the following conditions: |
||||||
|
# |
||||||
|
# The above copyright notice and this permission notice (including the next |
||||||
|
# paragraph) shall be included in all copies or substantial portions of the |
||||||
|
# Software. |
||||||
|
# |
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
# IN THE SOFTWARE. |
||||||
|
|
||||||
|
# Initialize Autoconf |
||||||
|
AC_PREREQ([2.60]) |
||||||
|
AC_INIT([libepoxy], |
||||||
|
[1.0], |
||||||
|
[https://people.freedesktop.org/~anholt/libepoxy], |
||||||
|
[libepoxy]) |
||||||
|
AC_CONFIG_SRCDIR([Makefile.am]) |
||||||
|
AC_CONFIG_HEADERS([config.h]) |
||||||
|
|
||||||
|
# Initialize Automake |
||||||
|
AM_INIT_AUTOMAKE([foreign dist-bzip2 subdir-objects]) |
||||||
|
|
||||||
|
# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS |
||||||
|
m4_ifndef([XORG_MACROS_VERSION], |
||||||
|
[m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen. |
||||||
|
Hint: either install from source, git://anongit.freedesktop.org/xorg/util/macros or, |
||||||
|
depending on you distribution, try package 'xutils-dev' or 'xorg-x11-util-macros'])]) |
||||||
|
|
||||||
|
XORG_MACROS_VERSION(1.8) |
||||||
|
XORG_DEFAULT_OPTIONS |
||||||
|
|
||||||
|
AC_CHECK_PROGS([PYTHON], [python3 python2 python]) |
||||||
|
|
||||||
|
# Initialize libtool |
||||||
|
AC_DISABLE_STATIC |
||||||
|
AC_PROG_LIBTOOL |
||||||
|
AC_SYS_LARGEFILE |
||||||
|
|
||||||
|
if test "x$GCC" = xyes; then |
||||||
|
save_CFLAGS="$CFLAGS" |
||||||
|
AC_MSG_CHECKING([whether $CC supports -fvisibility=hidden]) |
||||||
|
VISIBILITY_CFLAGS="-fvisibility=hidden" |
||||||
|
CFLAGS="$CFLAGS $VISIBILITY_CFLAGS" |
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM()], AC_MSG_RESULT([yes]), |
||||||
|
[VISIBILITY_CFLAGS=""; AC_MSG_RESULT([no])]); |
||||||
|
|
||||||
|
# Restore CFLAGS; VISIBILITY_CFLAGS are added to it where needed. |
||||||
|
CFLAGS=$save_CFLAGS |
||||||
|
fi |
||||||
|
|
||||||
|
AC_SUBST([VISIBILITY_CFLAGS]) |
||||||
|
|
||||||
|
PKG_CHECK_MODULES(X11, [x11], [x11=yes], [x11=no]) |
||||||
|
AM_CONDITIONAL(HAVE_X11, test x$x11 = xyes) |
||||||
|
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([ |
||||||
|
epoxy.pc |
||||||
|
Makefile |
||||||
|
src/Makefile |
||||||
|
]) |
||||||
|
AC_OUTPUT |
||||||
|
|
||||||
|
echo " PYTHON: $PYTHON" |
@ -0,0 +1,10 @@ |
|||||||
|
prefix=@prefix@ |
||||||
|
exec_prefix=@exec_prefix@ |
||||||
|
libdir=@libdir@ |
||||||
|
includedir=@includedir@ |
||||||
|
|
||||||
|
Name: epoxy |
||||||
|
Description: epoxy GL dispatch Library |
||||||
|
Version: @PACKAGE_VERSION@ |
||||||
|
Cflags: -I${includedir} |
||||||
|
Libs: -L${libdir} -lepoxy |
@ -0,0 +1,52 @@ |
|||||||
|
/*
|
||||||
|
* Copyright © 2013 Intel Corporation |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice (including the next |
||||||
|
* paragraph) shall be included in all copies or substantial portions of the |
||||||
|
* Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
* IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file gl.h
|
||||||
|
* |
||||||
|
* Provides an implementation of a GL dispatch layer using a hidden |
||||||
|
* vtable. |
||||||
|
* |
||||||
|
* This is a lower performance path than ifuncs when they are |
||||||
|
* available, but it is required if you might have multiple return |
||||||
|
* values for GetProcAddress/dlsym()ed functions. That is the case if |
||||||
|
* you're using WGL (which can return different function pointers per |
||||||
|
* context), or if you dlclose() and re-dlopen() libGL (which means |
||||||
|
* you'll get different dynamically allocated dispatch stubs). |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __EPOXY_GL_H |
||||||
|
#define __EPOXY_GL_H |
||||||
|
|
||||||
|
#if defined(__gl_h_) || defined(__glext_h_) |
||||||
|
#error epoxy/gl.h must be included before (or in place of) GL/gl.h |
||||||
|
#else |
||||||
|
#define __gl_h_ |
||||||
|
#define __glext_h_ |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#include "epoxy/gl_common.h" |
||||||
|
#include "epoxy/gl_generated.h" |
||||||
|
#include "epoxy/gl_generated_vtable_defines.h" |
||||||
|
|
||||||
|
#endif /* __EPOXY_GL_H */ |
@ -0,0 +1,38 @@ |
|||||||
|
/*
|
||||||
|
* Copyright © 2013 Intel Corporation |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice (including the next |
||||||
|
* paragraph) shall be included in all copies or substantial portions of the |
||||||
|
* Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
* IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file gl_common.h
|
||||||
|
* |
||||||
|
* Provides prototypes for epoxy GL functions independent of dispatch mechanism. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef EPOXY_GL_COMMON_H |
||||||
|
#define EPOXY_GL_COMMON_H |
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
|
||||||
|
bool epoxy_has_gl_extension(const char *extension); |
||||||
|
int epoxy_gl_version(void); |
||||||
|
|
||||||
|
#endif /* EPOXY_GL_COMMON_H */ |
||||||
|
|
@ -0,0 +1,51 @@ |
|||||||
|
/*
|
||||||
|
* Copyright © 2013 Intel Corporation |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice (including the next |
||||||
|
* paragraph) shall be included in all copies or substantial portions of the |
||||||
|
* Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
* IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file glx.h
|
||||||
|
* |
||||||
|
* Provides an implementation of a GLX dispatch layer using a hidden |
||||||
|
* vtable. |
||||||
|
* |
||||||
|
* This is a lower performance path than ifuncs when they are |
||||||
|
* available, but it is required if you might have multiple return |
||||||
|
* values for GetProcAddress/dlsym()ed functions (for example, if you |
||||||
|
* unload libGL.so.1). |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __EPOXY_GLX_H |
||||||
|
#define __EPOXY_GLX_H |
||||||
|
|
||||||
|
#if defined(__glx_h_) || defined(__glxext_h_) |
||||||
|
#error epoxy/glx.h must be included before (or in place of) GL/glx.h |
||||||
|
#else |
||||||
|
#define __glext_h_ |
||||||
|
#define __glxext_h_ |
||||||
|
#endif |
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "epoxy/glx_common.h" |
||||||
|
#include "epoxy/glx_generated.h" |
||||||
|
#include "epoxy/glx_generated_vtable_defines.h" |
||||||
|
|
||||||
|
#endif /* __EPOXY_GLX_H */ |
@ -0,0 +1,38 @@ |
|||||||
|
/*
|
||||||
|
* Copyright © 2013 Intel Corporation |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice (including the next |
||||||
|
* paragraph) shall be included in all copies or substantial portions of the |
||||||
|
* Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
* IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file gl_common.h
|
||||||
|
* |
||||||
|
* Provides prototypes for epoxy GL functions independent of dispatch mechanism. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef EPOXY_GLX_COMMON_H |
||||||
|
#define EPOXY_GLX_COMMON_H |
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
|
||||||
|
bool epoxy_has_glx_extension(const char *extension); |
||||||
|
int epoxy_glx_version(void); |
||||||
|
|
||||||
|
#endif /* EPOXY_GLX_COMMON_H */ |
||||||
|
|
@ -0,0 +1,84 @@ |
|||||||
|
# Copyright 2005 Adam Jackson.
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# ADAM JACKSON 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.
|
||||||
|
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-I$(top_srcdir)/include \
|
||||||
|
-I$(top_builddir)/include \
|
||||||
|
$()
|
||||||
|
|
||||||
|
AM_CFLAGS = $(CWARNFLAGS) $(VISIBILITY_CFLAGS)
|
||||||
|
|
||||||
|
epoxyincludedir = $(includedir)/epoxy
|
||||||
|
lib_LTLIBRARIES = libepoxy.la
|
||||||
|
|
||||||
|
epoxyinclude_DATA = \
|
||||||
|
$(GL_INCLUDES) \
|
||||||
|
$(GLX_INCLUDES) \
|
||||||
|
$()
|
||||||
|
|
||||||
|
GL_INCLUDES = \
|
||||||
|
../include/epoxy/gl.h \
|
||||||
|
../include/epoxy/gl_common.h \
|
||||||
|
$(GENERATED_GL_INCLUDES) \
|
||||||
|
$()
|
||||||
|
|
||||||
|
GLX_INCLUDES = \
|
||||||
|
../include/epoxy/glx.h \
|
||||||
|
../include/epoxy/glx_common.h \
|
||||||
|
$(GENERATED_GLX_INCLUDES) \
|
||||||
|
$()
|
||||||
|
|
||||||
|
GENERATED_GL_INCLUDES = \
|
||||||
|
$(builddir)/../include/epoxy/gl_generated.h \
|
||||||
|
$(builddir)/../include/epoxy/gl_generated_vtable_defines.h \
|
||||||
|
$()
|
||||||
|
|
||||||
|
GENERATED_GLX_INCLUDES = \
|
||||||
|
$(builddir)/../include/epoxy/glx_generated.h \
|
||||||
|
$(builddir)/../include/epoxy/glx_generated_vtable_defines.h \
|
||||||
|
$()
|
||||||
|
|
||||||
|
GENERATED_GL = \
|
||||||
|
$(builddir)/gl_generated_dispatch.c \
|
||||||
|
$(GENERATED_GL_INCLUDES) \
|
||||||
|
$()
|
||||||
|
|
||||||
|
GENERATED_GLX = \
|
||||||
|
$(builddir)/glx_generated_dispatch.c \
|
||||||
|
$(GENERATED_GLX_INCLUDES) \
|
||||||
|
$()
|
||||||
|
|
||||||
|
BUILT_SOURCES = \
|
||||||
|
$(GENERATED_GL) \
|
||||||
|
$(GENERATED_GLX) \
|
||||||
|
$()
|
||||||
|
CLEANFILES = $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
libepoxy_la_SOURCES = \
|
||||||
|
dispatch_common.c \
|
||||||
|
dispatch_common.h \
|
||||||
|
$(BUILT_SOURCES)
|
||||||
|
$()
|
||||||
|
|
||||||
|
$(GENERATED_GL): gen_dispatch.py ../registry/gl.xml |
||||||
|
$(AM_V_GEN)$(PYTHON) gen_dispatch.py --dir $(top_builddir) ../registry/gl.xml
|
||||||
|
|
||||||
|
$(GENERATED_GLX): gen_dispatch.py ../registry/glx.xml |
||||||
|
$(AM_V_GEN)$(PYTHON) gen_dispatch.py --dir $(top_builddir) ../registry/glx.xml
|
@ -0,0 +1,217 @@ |
|||||||
|
/*
|
||||||
|
* Copyright © 2013 Intel Corporation |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice (including the next |
||||||
|
* paragraph) shall be included in all copies or substantial portions of the |
||||||
|
* Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
* IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @file dispatch_common.c |
||||||
|
* |
||||||
|
* Implements common code shared by the generated GL/EGL/GLX dispatch code. |
||||||
|
* |
||||||
|
* A collection of some important specs on getting GL function pointers. |
||||||
|
* |
||||||
|
* From the linux GL ABI (http://www.opengl.org/registry/ABI/):
|
||||||
|
* |
||||||
|
* "3.4. The libraries must export all OpenGL 1.2, GLU 1.3, GLX 1.3, and |
||||||
|
* ARB_multitexture entry points statically. |
||||||
|
* |
||||||
|
* 3.5. Because non-ARB extensions vary so widely and are constantly |
||||||
|
* increasing in number, it's infeasible to require that they all be |
||||||
|
* supported, and extensions can always be added to hardware drivers |
||||||
|
* after the base link libraries are released. These drivers are |
||||||
|
* dynamically loaded by libGL, so extensions not in the base |
||||||
|
* library must also be obtained dynamically. |
||||||
|
* |
||||||
|
* 3.6. To perform the dynamic query, libGL also must export an entry |
||||||
|
* point called |
||||||
|
* |
||||||
|
* void (*glXGetProcAddressARB(const GLubyte *))();
|
||||||
|
* |
||||||
|
* The full specification of this function is available separately. It |
||||||
|
* takes the string name of a GL or GLX entry point and returns a pointer |
||||||
|
* to a function implementing that entry point. It is functionally |
||||||
|
* identical to the wglGetProcAddress query defined by the Windows OpenGL |
||||||
|
* library, except that the function pointers returned are context |
||||||
|
* independent, unlike the WGL query." |
||||||
|
* |
||||||
|
* From the EGL 1.4 spec: |
||||||
|
* |
||||||
|
* "Client API function pointers returned by eglGetProcAddress are |
||||||
|
* independent of the display and the currently bound client API context, |
||||||
|
* and may be used by any client API context which supports the extension. |
||||||
|
* |
||||||
|
* eglGetProcAddress may be queried for all of the following functions: |
||||||
|
* |
||||||
|
* • All EGL and client API extension functions supported by the |
||||||
|
* implementation (whether those extensions are supported by the current |
||||||
|
* client API context or not). This includes any mandatory OpenGL ES |
||||||
|
* extensions. |
||||||
|
* |
||||||
|
* eglGetProcAddress may not be queried for core (non-extension) functions |
||||||
|
* in EGL or client APIs 20 . |
||||||
|
* |
||||||
|
* For functions that are queryable with eglGetProcAddress, |
||||||
|
* implementations may choose to also export those functions statically |
||||||
|
* from the object libraries im- plementing those functions. However, |
||||||
|
* portable clients cannot rely on this behavior. |
||||||
|
* |
||||||
|
* From the GLX 1.4 spec: |
||||||
|
* |
||||||
|
* "glXGetProcAddress may be queried for all of the following functions: |
||||||
|
* |
||||||
|
* • All GL and GLX extension functions supported by the implementation |
||||||
|
* (whether those extensions are supported by the current context or |
||||||
|
* not). |
||||||
|
* |
||||||
|
* • All core (non-extension) functions in GL and GLX from version 1.0 up |
||||||
|
* to and including the versions of those specifications supported by |
||||||
|
* the implementation, as determined by glGetString(GL VERSION) and |
||||||
|
* glXQueryVersion queries." |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <assert.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <dlfcn.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include "epoxy/gl.h" |
||||||
|
#include "epoxy/glx.h" |
||||||
|
#include "dispatch_common.h" |
||||||
|
|
||||||
|
/* XXX: Make this thread local */ |
||||||
|
struct api local_api; |
||||||
|
|
||||||
|
struct api *api = &local_api; |
||||||
|
|
||||||
|
bool |
||||||
|
epoxy_is_desktop_gl(void) |
||||||
|
{ |
||||||
|
const char *es_prefix = "OpenGL ES "; |
||||||
|
const char *version = (const char *)glGetString(GL_VERSION); |
||||||
|
|
||||||
|
printf("VERSION %s\n", version); |
||||||
|
return !strncmp(es_prefix, version, strlen(es_prefix)); |
||||||
|
} |
||||||
|
|
||||||
|
PUBLIC int |
||||||
|
epoxy_gl_version(void) |
||||||
|
{ |
||||||
|
GLint major, minor; |
||||||
|
|
||||||
|
glGetIntegerv(GL_MAJOR_VERSION, &major); |
||||||
|
glGetIntegerv(GL_MAJOR_VERSION, &minor); |
||||||
|
|
||||||
|
return major * 10 + minor; |
||||||
|
} |
||||||
|
|
||||||
|
bool |
||||||
|
epoxy_is_glx(void) |
||||||
|
{ |
||||||
|
return true; /* XXX */ |
||||||
|
} |
||||||
|
|
||||||
|
int |
||||||
|
epoxy_glx_version(void) |
||||||
|
{ |
||||||
|
return 14; /* XXX */ |
||||||
|
} |
||||||
|
|
||||||
|
static bool |
||||||
|
epoxy_extension_in_string(const char *extension_list, const char *ext) |
||||||
|
{ |
||||||
|
const char *ptr = extension_list; |
||||||
|
int len = strlen(ext); |
||||||
|
|
||||||
|
/* Make sure that don't just find an extension with our name as a prefix. */ |
||||||
|
do { |
||||||
|
ptr = strstr(ptr, ext); |
||||||
|
} while (ptr && (ptr[len] != ' ' && ptr[len] != 0)); |
||||||
|
|
||||||
|
return ptr != NULL; |
||||||
|
} |
||||||
|
|
||||||
|
PUBLIC bool |
||||||
|
epoxy_has_gl_extension(const char *ext) |
||||||
|
{ |
||||||
|
return epoxy_extension_in_string((const char *)glGetString(GL_EXTENSIONS), |
||||||
|
ext); |
||||||
|
} |
||||||
|
|
||||||
|
#if 0 |
||||||
|
PUBLIC bool |
||||||
|
epoxy_has_egl_extension(const char *ext) |
||||||
|
{ |
||||||
|
return epoxy_extension_in_string(eglQueryString(EGL_EXTENSIONS), ext); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
PUBLIC bool |
||||||
|
epoxy_has_glx_extension(const char *ext) |
||||||
|
{ |
||||||
|
Display *dpy = glXGetCurrentDisplay(); |
||||||
|
int screen = 0; |
||||||
|
|
||||||
|
if (!dpy) { |
||||||
|
fprintf(stderr, "waffle needs a display!"); /* XXX */ |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/* No, you can't just use glXGetClientString or glXGetServerString() here.
|
||||||
|
* Those each tell you about one half of what's needed for an extension to |
||||||
|
* be supported, and glXQueryExtensionsString(). |
||||||
|
*/ |
||||||
|
return epoxy_extension_in_string(glXQueryExtensionsString(dpy, screen), ext); |
||||||
|
} |
||||||
|
|
||||||
|
void * |
||||||
|
epoxy_dlsym(const char *name) |
||||||
|
{ |
||||||
|
assert(api->gl_handle); |
||||||
|
return dlsym(api->gl_handle, name); |
||||||
|
} |
||||||
|
|
||||||
|
void * |
||||||
|
epoxy_get_proc_address(const char *name) |
||||||
|
{ |
||||||
|
return glXGetProcAddress((const GLubyte *)name); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
epoxy_glx_autoinit(void) |
||||||
|
{ |
||||||
|
if (api->gl_handle) |
||||||
|
return; |
||||||
|
|
||||||
|
api->gl_handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL); |
||||||
|
if (!api->gl_handle) { |
||||||
|
fprintf(stderr, "Couldn't open libGL.so.1: %s", dlerror()); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
api->winsys_handle = api->gl_handle; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
epoxy_platform_autoinit(void) |
||||||
|
{ |
||||||
|
epoxy_glx_autoinit(); |
||||||
|
} |
||||||
|
|
@ -0,0 +1,55 @@ |
|||||||
|
/*
|
||||||
|
* Copyright © 2013 Intel Corporation |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice (including the next |
||||||
|
* paragraph) shall be included in all copies or substantial portions of the |
||||||
|
* Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
* IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
#include "epoxy/gl_common.h" |
||||||
|
#include "epoxy/glx_common.h" |
||||||
|
|
||||||
|
#ifndef PUBLIC |
||||||
|
# if (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) |
||||||
|
# define PUBLIC __attribute__((visibility("default"))) |
||||||
|
# else |
||||||
|
# define PUBLIC |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
struct api { |
||||||
|
bool is_glx; |
||||||
|
bool is_gl; |
||||||
|
bool is_gles1; |
||||||
|
bool is_gles2; /**< Also GLES3 */ |
||||||
|
|
||||||
|
/** dlopen() return value for libGL.so.1, libGLESv2.so.1, etc. */ |
||||||
|
void *gl_handle; |
||||||
|
|
||||||
|
/** dlopen() return value for libGL.so.1 or libEGL.so.1 */ |
||||||
|
void *winsys_handle; |
||||||
|
}; |
||||||
|
|
||||||
|
bool epoxy_is_desktop_gl(void); |
||||||
|
bool epoxy_is_glx(void); |
||||||
|
|
||||||
|
void *epoxy_get_proc_address(const char *name); |
||||||
|
void *epoxy_dlsym(const char *name); |
||||||
|
void epoxy_glx_autoinit(void); |
||||||
|
void epoxy_platform_autoinit(void); |
@ -0,0 +1,456 @@ |
|||||||
|
#!/usr/bin/env python |
||||||
|
# -*- coding: utf-8 -*- |
||||||
|
|
||||||
|
# Copyright © 2013 Intel Corporation |
||||||
|
# |
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
# copy of this software and associated documentation files (the "Software"), |
||||||
|
# to deal in the Software without restriction, including without limitation |
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
# Software is furnished to do so, subject to the following conditions: |
||||||
|
# |
||||||
|
# The above copyright notice and this permission notice (including the next |
||||||
|
# paragraph) shall be included in all copies or substantial portions of the |
||||||
|
# Software. |
||||||
|
# |
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||||
|
# IN THE SOFTWARE. |
||||||
|
|
||||||
|
import sys |
||||||
|
import argparse |
||||||
|
import xml.etree.ElementTree as ET |
||||||
|
import re |
||||||
|
import os |
||||||
|
|
||||||
|
class GLFunction(object): |
||||||
|
def __init__(self, ret_type, name): |
||||||
|
self.name = name |
||||||
|
self.ptr_type = 'PFN' + name.upper() |
||||||
|
self.ret_type = ret_type |
||||||
|
self.providers = [] |
||||||
|
self.args = [] |
||||||
|
self.args_list = '' |
||||||
|
self.args_decl = 'void' |
||||||
|
|
||||||
|
# For an alias group, alias_func is the function they are all |
||||||
|
# marked as the alias of. |
||||||
|
self.alias_func = None |
||||||
|
# For an alias group, the shared alias_func has this list of |
||||||
|
# functions (of different names) that are marked as aliases of |
||||||
|
# it, so that it can write a resolver for all of them. |
||||||
|
self.alias_exts = [] |
||||||
|
|
||||||
|
def add_arg(self, type, name): |
||||||
|
self.args.append((type, name)) |
||||||
|
if self.args_decl == 'void': |
||||||
|
self.args_list = name |
||||||
|
self.args_decl = type + ' ' + name |
||||||
|
else: |
||||||
|
self.args_list += ', ' + name |
||||||
|
self.args_decl += ', ' + type + ' ' + name |
||||||
|
|
||||||
|
def add_provider(self, condition, loader, human_name): |
||||||
|
self.providers.append((condition, loader, human_name)) |
||||||
|
|
||||||
|
def add_alias(self, ext): |
||||||
|
# We don't support transitivity of aliases. |
||||||
|
assert not ext.alias_exts |
||||||
|
assert self.alias_func is None |
||||||
|
|
||||||
|
self.alias_exts.append(ext) |
||||||
|
ext.alias_func = self |
||||||
|
|
||||||
|
class Generator(object): |
||||||
|
def __init__(self): |
||||||
|
self.enums = {} |
||||||
|
self.functions = {} |
||||||
|
self.max_enum_name_len = 1 |
||||||
|
self.copyright_comment = None |
||||||
|
self.typedefs = '' |
||||||
|
self.out_file = None |
||||||
|
|
||||||
|
self.dlsym_loader = 'epoxy_dlsym("{0}")' |
||||||
|
self.gpa_loader = 'epoxy_get_proc_address("{0}")' |
||||||
|
|
||||||
|
def all_text_until_element_name(self, element, element_name): |
||||||
|
text = '' |
||||||
|
|
||||||
|
if element.text is not None: |
||||||
|
text += element.text |
||||||
|
|
||||||
|
for child in element: |
||||||
|
if child.tag == element_name: |
||||||
|
break |
||||||
|
if child.text: |
||||||
|
text += child.text |
||||||
|
if child.tail: |
||||||
|
text += child.tail |
||||||
|
return text |
||||||
|
|
||||||
|
def out(self, text): |
||||||
|
self.out_file.write(text) |
||||||
|
|
||||||
|
def outln(self, text): |
||||||
|
self.out_file.write(text + '\n') |
||||||
|
|
||||||
|
def parse_typedefs(self, reg): |
||||||
|
for t in reg.findall('types/type'): |
||||||
|
if 'name' in t.attrib and t.attrib['name'] not in {'GLhandleARB'}: |
||||||
|
continue |
||||||
|
|
||||||
|
if t.text is not None: |
||||||
|
self.typedefs += t.text |
||||||
|
|
||||||
|
for child in t: |
||||||
|
if child.text: |
||||||
|
self.typedefs += child.text |
||||||
|
if child.tail: |
||||||
|
self.typedefs += child.tail |
||||||
|
self.typedefs += '\n' |
||||||
|
|
||||||
|
def parse_enums(self, reg): |
||||||
|
for enum in reg.findall('enums/enum'): |
||||||
|
name = enum.get('name') |
||||||
|
self.max_enum_name_len = max(self.max_enum_name_len, len(name)) |
||||||
|
self.enums[name] = enum.get('value') |
||||||
|
|
||||||
|
def get_function_return_type(self, proto): |
||||||
|
# Everything up to the start of the name element is the return type. |
||||||
|
return self.all_text_until_element_name(proto, 'name').strip() |
||||||
|
|
||||||
|
def parse_function_definitions(self, reg): |
||||||
|
for command in reg.findall('commands/command'): |
||||||
|
proto = command.find('proto') |
||||||
|
name = proto.find('name').text |
||||||
|
ret_type = self.get_function_return_type(proto) |
||||||
|
|
||||||
|
func = GLFunction(ret_type, name) |
||||||
|
|
||||||
|
for arg in command.findall('param'): |
||||||
|
func.add_arg(self.all_text_until_element_name(arg, 'name').strip(), |
||||||
|
arg.find('name').text) |
||||||
|
|
||||||
|
alias = command.find('alias') |
||||||
|
if alias is not None: |
||||||
|
alias_func = self.functions[alias.get('name')] |
||||||
|
alias_func.add_alias(func) |
||||||
|
|
||||||
|
self.functions[name] = func |
||||||
|
|
||||||
|
def drop_weird_glx_functions(self): |
||||||
|
# Drop a few ancient SGIX GLX extensions that use types not defined |
||||||
|
# anywhere in Xlib. In glxext.h, they're protected by #ifdefs for the |
||||||
|
# headers that defined them. |
||||||
|
weird_functions = [name for name, func in self.functions.items() |
||||||
|
if 'VLServer' in func.args_decl |
||||||
|
or 'DMparams' in func.args_decl] |
||||||
|
|
||||||
|
for name in weird_functions: |
||||||
|
del self.functions[name] |
||||||
|
|
||||||
|
def process_require_statements(self, feature, condition, loader, human_name): |
||||||
|
for command in feature.findall('require/command'): |
||||||
|
name = command.get('name') |
||||||
|
func = self.functions[name] |
||||||
|
func.add_provider(condition, loader.format(name), human_name) |
||||||
|
|
||||||
|
def parse_function_providers(self, reg): |
||||||
|
for feature in reg.findall('feature'): |
||||||
|
api = feature.get('api') # string gl, gles1, gles2, glx |
||||||
|
m = re.match('([0-9])\.([0-9])', feature.get('number')) |
||||||
|
version = int(m.group(1)) * 10 + int(m.group(2)) |
||||||
|
|
||||||
|
if api == 'gl': |
||||||
|
human_name = 'Desktop OpenGL {0}'.format(feature.get('number')) |
||||||
|
condition = 'epoxy_is_desktop_gl()' |
||||||
|
|
||||||
|
# Everything in GL 1.2 is guaranteed to be present as |
||||||
|
# public symbols in the Linux libGL ABI. Everything |
||||||
|
# else is supposed to not be present, so you have to |
||||||
|
# glXGetProcAddress() it. |
||||||
|
if version <= 12: |
||||||
|
loader = self.dlsym_loader |
||||||
|
else: |
||||||
|
loader = self.gpa_loader |
||||||
|
condition += ' && epoxy_gl_version() >= {0}'.format(version) |
||||||
|
elif api == 'gles2': |
||||||
|
human_name = 'OpenGL ES {0}'.format(feature.get('number')) |
||||||
|
condition = '!epoxy_is_desktop_gl() && epoxy_gl_version() >= {0}'.format(version) |
||||||
|
|
||||||
|
if version <= 20: |
||||||
|
loader = self.dlsym_loader |
||||||
|
else: |
||||||
|
loader = self.gpa_loader |
||||||
|
elif api == 'gles1': |
||||||
|
human_name = 'OpenGL ES 1.0' |
||||||
|
condition = '!epoxy_is_desktop_gl() && epoxy_gl_version() == 10' |
||||||
|
|
||||||
|
if version <= 20: |
||||||
|
loader = self.dlsym_loader |
||||||
|
else: |
||||||
|
loader = self.gpa_loader |
||||||
|
elif api == 'glx': |
||||||
|
human_name = 'GLX {0}'.format(version) |
||||||
|
condition = 'epoxy_glx_version() >= {0}'.format(version) |
||||||
|
loader = self.dlsym_loader |
||||||
|
|
||||||
|
if version <= 13: |
||||||
|
loader = self.dlsym_loader |
||||||
|
else: |
||||||
|
loader = self.gpa_loader |
||||||
|
else: |
||||||
|
sys.exit('unknown API: "{0}"'.format(api)) |
||||||
|
|
||||||
|
self.process_require_statements(feature, condition, loader, human_name) |
||||||
|
|
||||||
|
for extension in reg.findall('extensions/extension'): |
||||||
|
extname = extension.get('name') |
||||||
|
# 'supported' is a set of strings like gl, gles1, gles2, or glx, which are |
||||||
|
# separated by '|' |
||||||
|
apis = extension.get('supported').split('|') |
||||||
|
if 'glx' in apis: |
||||||
|
human_name = 'GLX extension \\"{0}\\"'.format(extname) |
||||||
|
condition = 'epoxy_has_glx_extension("{0}")'.format(extname) |
||||||
|
loader = 'epoxy_get_proc_address("{0}")' |
||||||
|
self.process_require_statements(extension, condition, loader, human_name) |
||||||
|
if 'gl' in apis: |
||||||
|
human_name = 'GL extension \\"{0}\\"'.format(extname) |
||||||
|
condition = 'epoxy_has_gl_extension("{0}")'.format(extname) |
||||||
|
loader = 'epoxy_get_proc_address("{0}")' |
||||||
|
self.process_require_statements(extension, condition, loader, human_name) |
||||||
|
|
||||||
|
def fixup_bootstrap_function(self, name): |
||||||
|
# We handle glGetString() and glGetIntegerv() specially, because we |
||||||
|
# need to use them in the process of deciding on loaders for |
||||||
|
# resolving, and the naive code generation would result in their |
||||||
|
# resolvers calling their own resolvers. |
||||||
|
if name not in self.functions: |
||||||
|
return |
||||||
|
|
||||||
|
func = self.functions[name] |
||||||
|
func.providers = [] |
||||||
|
func.add_provider('true', self.dlsym_loader.format(func.name), |
||||||
|
'always present') |
||||||
|
|
||||||
|
def parse(self, file): |
||||||
|
reg = ET.parse(file) |
||||||
|
if reg.find('comment') != None: |
||||||
|
self.copyright_comment = reg.find('comment').text |
||||||
|
else: |
||||||
|
self.copyright_comment = '' |
||||||
|
self.parse_typedefs(reg) |
||||||
|
self.parse_enums(reg) |
||||||
|
self.parse_function_definitions(reg) |
||||||
|
self.parse_function_providers(reg) |
||||||
|
|
||||||
|
def write_copyright_comment_body(self): |
||||||
|
for line in self.copyright_comment.splitlines(): |
||||||
|
if '-----' in line: |
||||||
|
break |
||||||
|
self.outln(' * ' + line) |
||||||
|
|
||||||
|
def write_enums(self): |
||||||
|
for name, value in self.enums.items(): |
||||||
|
self.outln('#define ' + name.ljust(self.max_enum_name_len + 3) + value + '') |
||||||
|
|
||||||
|
def write_function_ptr_typedefs(self): |
||||||
|
for func in self.functions.values(): |
||||||
|
self.outln('typedef {0} (*{1})({2});'.format(func.ret_type, func.ptr_type, |
||||||
|
func.args_decl)) |
||||||
|
|
||||||
|
def write_header_header(self, file): |
||||||
|
self.out_file = open(file, 'w') |
||||||
|
|
||||||
|
self.outln('/* GL dispatch header.') |
||||||
|
self.outln(' * This is code-generated from the GL API XML files from Khronos.') |
||||||
|
self.write_copyright_comment_body() |
||||||
|
self.outln(' */') |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
self.outln('#pragma once') |
||||||
|
|
||||||
|
self.outln('#include <inttypes.h>') |
||||||
|
self.outln('#include <stddef.h>') |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
def write_header(self, file): |
||||||
|
self.write_header_header(file) |
||||||
|
|
||||||
|
if 'gl_' not in file: |
||||||
|
self.outln('#include "epoxy/gl_generated.h"') |
||||||
|
else: |
||||||
|
# Add some ridiculous inttypes.h redefinitions that are from |
||||||
|
# khrplatform.h and not included in the XML. |
||||||
|
self.outln('typedef int8_t khronos_int8_t;') |
||||||
|
self.outln('typedef int16_t khronos_int16_t;') |
||||||
|
self.outln('typedef int32_t khronos_int32_t;') |
||||||
|
self.outln('typedef int64_t khronos_int64_t;') |
||||||
|
self.outln('typedef uint8_t khronos_uint8_t;') |
||||||
|
self.outln('typedef uint16_t khronos_uint16_t;') |
||||||
|
self.outln('typedef uint32_t khronos_uint32_t;') |
||||||
|
self.outln('typedef uint64_t khronos_uint64_t;') |
||||||
|
self.outln('typedef float khronos_float_t;') |
||||||
|
self.outln('typedef intptr_t khronos_intptr_t;') |
||||||
|
self.outln('typedef ptrdiff_t khronos_ssize_t;') |
||||||
|
|
||||||
|
if 'glx_' in file: |
||||||
|
self.outln('#include <X11/Xlib.h>') |
||||||
|
self.outln('#include <X11/Xutil.h>') |
||||||
|
|
||||||
|
self.out(self.typedefs) |
||||||
|
self.outln('') |
||||||
|
self.write_enums() |
||||||
|
self.outln('') |
||||||
|
self.write_function_ptr_typedefs() |
||||||
|
|
||||||
|
for func in self.functions.values(): |
||||||
|
self.outln('{0} epoxy_{1}({2});'.format(func.ret_type, func.name, |
||||||
|
func.args_decl)) |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
def write_proto_define_header(self, file, style): |
||||||
|
self.write_header_header(file) |
||||||
|
|
||||||
|
for func in self.functions.values(): |
||||||
|
self.outln('#define {0} epoxy_{1}{0}'.format(func.name, style)) |
||||||
|
|
||||||
|
def write_function_ptr_resolver(self, func): |
||||||
|
self.outln('static {0}'.format(func.ptr_type)) |
||||||
|
self.outln('epoxy_{0}_resolver(void)'.format(func.name)) |
||||||
|
self.outln('{') |
||||||
|
if 'glX' in func.name: |
||||||
|
self.outln(' epoxy_glx_autoinit();') |
||||||
|
else: |
||||||
|
self.outln(' epoxy_platform_autoinit();') |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
providers = [] |
||||||
|
# Make a local list of all the providers for this alias group |
||||||
|
for provider in func.providers: |
||||||
|
providers.append(provider) |
||||||
|
for alias_func in func.alias_exts: |
||||||
|
for provider in alias_func.providers: |
||||||
|
providers.append(provider) |
||||||
|
|
||||||
|
# Check if there's any alias of this that's built into our |
||||||
|
# ABI, and just use that one if available. This is important |
||||||
|
# for avoiding loops of |
||||||
|
# glXGetProcAddress(glXGetProcAddress()), or |
||||||
|
# glGetIntegerv(glGetIntegerv()). |
||||||
|
global_loader = None |
||||||
|
for condition, loader, human_name in providers: |
||||||
|
if condition == 'true': |
||||||
|
global_loader = loader |
||||||
|
|
||||||
|
if global_loader: |
||||||
|
self.outln(' return {0};'.format(loader)) |
||||||
|
else: |
||||||
|
for condition, loader, human_name in providers: |
||||||
|
self.outln(' if ({0})'.format(condition)) |
||||||
|
self.outln(' return {0};'.format(loader)) |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
# If the function isn't provided by any known extension, print |
||||||
|
# something useful for the poor application developer before |
||||||
|
# aborting. (In non-epoxy GL usage, the app developer would |
||||||
|
# call into some blank stub function and segfault). |
||||||
|
self.outln(' printf("No provider of \\"{0}()\\" found. Requires one of:\\n");'.format(func.name)) |
||||||
|
if len(func.providers) == 0: |
||||||
|
self.outln(' printf(" unknown\\n");') |
||||||
|
else: |
||||||
|
for provider in func.providers: |
||||||
|
self.outln(' printf(" {0}\\n");'.format(provider[2])) |
||||||
|
|
||||||
|
self.outln(' abort();') |
||||||
|
|
||||||
|
self.outln('}') |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
def write_dispatch_table_stub(self, func): |
||||||
|
dispatch_table_entry = 'dispatch_table->p{0}'.format(func.name) |
||||||
|
|
||||||
|
# Use the same resolver for all the aliases of a particular |
||||||
|
# function. |
||||||
|
alias_func = func |
||||||
|
if func.alias_func: |
||||||
|
alias_func = func |
||||||
|
|
||||||
|
self.outln('PUBLIC {0}'.format(func.ret_type)) |
||||||
|
self.outln('epoxy_{0}({1})'.format(func.name, func.args_decl)) |
||||||
|
self.outln('{') |
||||||
|
self.outln(' if (!{0})'.format(dispatch_table_entry)) |
||||||
|
self.outln(' {0} = epoxy_{1}_resolver();'.format(dispatch_table_entry, |
||||||
|
alias_func.name)) |
||||||
|
self.outln('') |
||||||
|
if func.ret_type == 'void': |
||||||
|
self.outln(' {0}({1});'.format(dispatch_table_entry, func.args_list)) |
||||||
|
else: |
||||||
|
self.outln(' return {0}({1});'.format(dispatch_table_entry, func.args_list)) |
||||||
|
self.outln('}') |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
def write_source(self, file): |
||||||
|
self.out_file = open(file, 'w') |
||||||
|
|
||||||
|
self.outln('/* GL dispatch code.') |
||||||
|
self.outln(' * This is code-generated from the GL API XML files from Khronos.') |
||||||
|
self.write_copyright_comment_body() |
||||||
|
self.outln(' */') |
||||||
|
self.outln('') |
||||||
|
self.outln('#include <stdlib.h>') |
||||||
|
self.outln('#include <stdio.h>') |
||||||
|
self.outln('') |
||||||
|
self.outln('#include "dispatch_common.h"') |
||||||
|
if 'glx_' in file: |
||||||
|
self.outln('#include "epoxy/glx_generated.h"') |
||||||
|
else: |
||||||
|
self.outln('#include "epoxy/gl_generated.h"') |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
self.outln('struct dispatch_table {') |
||||||
|
for func in self.functions.values(): |
||||||
|
self.outln(' {0} p{1};'.format(func.ptr_type, func.name)) |
||||||
|
self.outln('};') |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
self.outln('/* XXX: Make this thread-local and swapped on makecurrent. */') |
||||||
|
self.outln('static struct dispatch_table local_dispatch_table;') |
||||||
|
self.outln('static struct dispatch_table *dispatch_table = &local_dispatch_table;') |
||||||
|
self.outln('') |
||||||
|
|
||||||
|
for func in self.functions.values(): |
||||||
|
if not func.alias_func: |
||||||
|
self.write_function_ptr_resolver(func) |
||||||
|
|
||||||
|
self.write_dispatch_table_stub(func) |
||||||
|
|
||||||
|
argparser = argparse.ArgumentParser(description='Generate GL dispatch wrappers.') |
||||||
|
argparser.add_argument('files', metavar='file.xml', nargs='+', help='GL API XML files to be parsed') |
||||||
|
argparser.add_argument('--dir', metavar='dir', required=True, help='Destination directory') |
||||||
|
args = argparser.parse_args() |
||||||
|
|
||||||
|
srcdir = args.dir + '/src/' |
||||||
|
incdir = args.dir + '/include/epoxy/' |
||||||
|
|
||||||
|
for file in args.files: |
||||||
|
name = os.path.basename(file).split('.xml')[0] |
||||||
|
generator = Generator() |
||||||
|
generator.parse(file) |
||||||
|
generator.drop_weird_glx_functions() |
||||||
|
generator.fixup_bootstrap_function('glGetString') |
||||||
|
generator.fixup_bootstrap_function('glGetIntegerv') |
||||||
|
|
||||||
|
# While this is technically exposed as a GLX extension, it's |
||||||
|
# required to be present as a public symbol by the Linux OpenGL |
||||||
|
# ABI. |
||||||
|
generator.fixup_bootstrap_function('glXGetProcAddressARB') |
||||||
|
|
||||||
|
generator.write_header(incdir + name + '_generated.h') |
||||||
|
generator.write_proto_define_header(incdir + name + '_generated_vtable_defines.h', '') |
||||||
|
generator.write_source(srcdir + name + '_generated_dispatch.c') |
Loading…
Reference in new issue