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