├── .dir-locals.el ├── autogen.sh ├── epoxy.pc.in ├── meson_options.txt ├── .editorconfig ├── test ├── .gitignore ├── egl_common.h ├── wgl_common.h ├── glx_common.h ├── headerguards.c ├── khronos_typedefs.h ├── egl_common.c ├── miscdefines.c ├── glx_glxgetprocaddress_nocontext.c ├── glx_has_extension_nocontext.c ├── glx_static.c ├── khronos_typedefs_nonepoxy.c ├── wgl_usefontbitmaps.c ├── glx_alias_prefer_same_name.c ├── egl_has_extension_nocontext.c ├── wgl_core_and_exts.c ├── khronos_typedefs.c ├── dlwrap.h ├── glx_beginend.c ├── glx_gles2.c ├── glx_common.c ├── glx_public_api.c ├── egl_gl.c ├── wgl_common.c ├── egl_without_glx.c ├── wgl_per_context_funcptrs.c ├── glx_public_api_core.c ├── Makefile.am ├── meson.build ├── egl_and_glx_different_pointers.c └── dlwrap.c ├── registry └── README.md ├── cross └── fedora-mingw64.txt ├── doc ├── meson.build └── Doxyfile.in ├── .travis.yml ├── include └── epoxy │ ├── meson.build │ ├── Makefile.am │ ├── egl.h │ ├── wgl.h │ ├── glx.h │ ├── common.h │ └── gl.h ├── .gitignore ├── .appveyor.yml ├── Makefile.am ├── COPYING ├── src ├── meson.build ├── dispatch_egl.c ├── dispatch_glx.c ├── Makefile.am ├── dispatch_wgl.c └── dispatch_common.h ├── README.md ├── configure.ac └── meson.build /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((nil 2 | (indent-tabs-mode . nil) 3 | (tab-width . 8) 4 | (c-basic-offset . 4) 5 | ) 6 | ) 7 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | srcdir=`dirname $0` 4 | test -z "$srcdir" && srcdir=. 5 | 6 | ORIGDIR=`pwd` 7 | cd "$srcdir" 8 | 9 | mkdir m4 || exit 1 10 | 11 | autoreconf -v --install || exit $? 12 | cd "$ORIGDIR" || exit $? 13 | 14 | if test -z "$NOCONFIGURE"; then 15 | exec "$srcdir/configure" "$@" 16 | fi 17 | -------------------------------------------------------------------------------- /epoxy.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | epoxy_has_glx=@epoxy_has_glx@ 7 | epoxy_has_egl=@epoxy_has_egl@ 8 | epoxy_has_wgl=@epoxy_has_wgl@ 9 | 10 | Name: epoxy 11 | Description: epoxy GL dispatch Library 12 | Version: @PACKAGE_VERSION@ 13 | Cflags: -I${includedir} 14 | Libs: -L${libdir} -lepoxy 15 | Libs.private: @DLOPEN_LIBS@ 16 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('enable-docs', 2 | type: 'boolean', value: false, 3 | description: 'Enable generating the Epoxy API reference (depends on Doxygen)') 4 | option('enable-glx', 5 | type: 'combo', 6 | choices: [ 'auto', 'yes', 'no' ], 7 | value: 'auto', 8 | description: 'Enable GLX support') 9 | option('enable-egl', 10 | type: 'combo', 11 | choices: [ 'auto', 'yes', 'no' ], 12 | value: 'auto', 13 | description: 'Enable EGL support') 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | 6 | [*.{c,h}] 7 | indent_style = space 8 | indent_size = 4 9 | end_of_line = lf 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | 13 | [configure.ac] 14 | indent_style = tab 15 | indent_size = 8 16 | 17 | [Makefile.am] 18 | indent_style = tab 19 | indent_size = 8 20 | 21 | [.travis.yml] 22 | indent_style = space 23 | indent_size = 2 24 | 25 | [*.md] 26 | trim_trailing_whitespace = false 27 | 28 | [meson.build] 29 | indent_style = space 30 | indent_size = 8 31 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | egl_and_glx_different_pointers_egl 2 | egl_and_glx_different_pointers_egl_glx 3 | egl_and_glx_different_pointers_glx 4 | egl_has_extension_nocontext 5 | egl_gl 6 | egl_gles1_without_glx 7 | egl_gles2_without_glx 8 | glx_alias_prefer_same_name 9 | glx_beginend 10 | glx_gles2 11 | glx_glxgetprocaddress_nocontext 12 | glx_has_extension_nocontext 13 | glx_public_api 14 | glx_public_api_core 15 | glx_shared_znow 16 | glx_static 17 | headerguards 18 | khronos_typedefs 19 | miscdefines 20 | wgl_core_and_exts 21 | wgl_usefontbitmaps 22 | wgl_usefontbitmaps_unicode 23 | *.log 24 | *.trs 25 | -------------------------------------------------------------------------------- /registry/README.md: -------------------------------------------------------------------------------- 1 | ## Updating the registry XML 2 | 3 | In order to update the registry XML files and retain the history you cannot 4 | simply download the files the [Khronos website](https://khronos.org/registry/OpenGL/index_gl.php) 5 | and copy them into this directory. You should follow these steps, instead: 6 | 7 | 1. check out the `khronos-registry` branch 8 | 2. download the XML files from the Khronos repository 9 | 3. copy them under the `registry` directory 10 | 4. check the result for consistency and commit it 11 | 5. check out the `master` branch and merge the `khronos-registry` branch 12 | into it with the appropriate commit message 13 | 14 | -------------------------------------------------------------------------------- /cross/fedora-mingw64.txt: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = '/usr/bin/x86_64-w64-mingw32-gcc' 3 | cpp = '/usr/bin/x86_64-w64-mingw32-cpp' 4 | ar = '/usr/bin/x86_64-w64-mingw32-ar' 5 | strip = '/usr/bin/x86_64-w64-mingw32-strip' 6 | pkgconfig = '/usr/bin/x86_64-w64-mingw32-pkg-config' 7 | exe_wrapper = 'wine' 8 | 9 | [properties] 10 | root = '/usr/x86_64-w64-mingw32/sys-root/mingw' 11 | c_args = [ '-pipe', '-Wp,-D_FORTIFY_SOURCE=2', '-fexceptions', '--param=ssp-buffer-size=4', '-I/usr/x86_64-w64-mingw32/sys-root/mingw/include' ] 12 | c_link_args = [ '-L/usr/x86_64-w64-mingw32/sys-root/mingw/lib' ] 13 | 14 | [host_machine] 15 | system = 'windows' 16 | cpu_family = 'x86_64' 17 | cpu = 'x86_64' 18 | endian = 'little' 19 | -------------------------------------------------------------------------------- /doc/meson.build: -------------------------------------------------------------------------------- 1 | doxyfile_conf = configuration_data() 2 | doxyfile_conf.set('PACKAGE_NAME', meson.project_name()) 3 | doxyfile_conf.set('PACKAGE_VERSION', meson.project_version()) 4 | doxyfile_conf.set('top_srcdir', meson.source_root()) 5 | doxyfile_conf.set('top_builddir', meson.build_root()) 6 | 7 | if find_program('dot', required: false).found() 8 | doxyfile_conf.set('HAVE_DOT', 'YES') 9 | else 10 | doxyfile_conf.set('HAVE_DOT', 'NO') 11 | endif 12 | 13 | doxyfile = configure_file(input: 'Doxyfile.in', 14 | output: 'Doxyfile', 15 | configuration: doxyfile_conf, 16 | install: false) 17 | 18 | docdir = join_paths(epoxy_datadir, 'doc') 19 | 20 | html_target = custom_target('epoxy-docs', 21 | input: [ doxyfile ], 22 | output: [ 'html' ], 23 | command: [ doxygen, doxyfile ], 24 | install: true, 25 | install_dir: join_paths(docdir, 'epoxy')) 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | branches: 4 | except: 5 | - debian 6 | - khronos-registry 7 | 8 | os: 9 | - linux 10 | 11 | compiler: 12 | - gcc 13 | - clang 14 | 15 | language: 16 | - c 17 | 18 | services: 19 | - docker 20 | 21 | before_install: 22 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull ebassi/epoxyci ; fi 23 | 24 | before_script: 25 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM ebassi/epoxyci > Dockerfile ; fi 26 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile ; fi 27 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit . ; fi 28 | 29 | script: 30 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && CC=$CC ./epoxy-run-tests.sh" ; fi 31 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && CC=$CC ./epoxy-run-tests.sh -Denable-glx=no" ; fi 32 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && CC=$CC ./epoxy-run-tests.sh -Denable-egl=no" ; fi 33 | -------------------------------------------------------------------------------- /test/egl_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | EGLDisplay * 25 | get_egl_display_or_skip(void); 26 | -------------------------------------------------------------------------------- /test/wgl_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | 26 | void 27 | make_window_and_test(int (*callback)(HDC hdc)); 28 | -------------------------------------------------------------------------------- /include/epoxy/meson.build: -------------------------------------------------------------------------------- 1 | headers = [ 'common.h' ] 2 | 3 | # GL is always generated 4 | generated_headers = [ [ 'gl.h', 'gl_generated.h', gl_registry ] ] 5 | 6 | if build_egl 7 | generated_headers += [ [ 'egl.h', 'egl_generated.h', egl_registry ] ] 8 | endif 9 | 10 | if build_glx 11 | generated_headers += [ [ 'glx.h', 'glx_generated.h', glx_registry ] ] 12 | endif 13 | 14 | if build_wgl 15 | generated_headers += [ [ 'wgl.h', 'wgl_generated.h', wgl_registry ] ] 16 | endif 17 | 18 | gen_headers = [] 19 | 20 | foreach g: generated_headers 21 | header = g[0] 22 | gen_header = g[1] 23 | registry = g[2] 24 | generated = custom_target(gen_header, 25 | input: registry, 26 | output: [ gen_header ], 27 | command: [ 28 | python, 29 | gen_dispatch_py, 30 | '--header', 31 | '--no-source', 32 | '--outputdir=@OUTDIR@', 33 | '@INPUT@', 34 | ], 35 | install: true, 36 | install_dir: join_paths(epoxy_includedir, 'epoxy')) 37 | 38 | gen_headers += [ generated ] 39 | headers += [ header ] 40 | endforeach 41 | 42 | epoxy_headers = files(headers) + gen_headers 43 | 44 | install_headers(headers, subdir: 'epoxy') 45 | -------------------------------------------------------------------------------- /include/epoxy/Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright © 2013 Intel Corporation 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a 4 | # copy of this software and associated documentation files (the "Software"), 5 | # to deal in the Software without restriction, including without limitation 6 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | # and/or sell copies of the Software, and to permit persons to whom the 8 | # Software is furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice (including the next 11 | # paragraph) shall be included in all copies or substantial portions of the 12 | # Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | # IN THE SOFTWARE. 21 | 22 | epoxyincludedir = $(includedir)/epoxy 23 | 24 | epoxyinclude_HEADERS = \ 25 | common.h \ 26 | gl.h \ 27 | $(EGL_INCLUDES) \ 28 | $(GLX_INCLUDES) \ 29 | $(WGL_INCLUDES) \ 30 | $() 31 | 32 | if BUILD_EGL 33 | EGL_INCLUDES = egl.h 34 | endif 35 | 36 | if BUILD_GLX 37 | GLX_INCLUDES = glx.h 38 | endif 39 | 40 | if BUILD_WGL 41 | WGL_INCLUDES = wgl.h 42 | endif 43 | -------------------------------------------------------------------------------- /test/glx_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include "epoxy/glx.h" 25 | 26 | Display * 27 | get_display_or_skip(void); 28 | 29 | void 30 | make_glx_context_current_or_skip(Display *dpy); 31 | 32 | GLXFBConfig 33 | get_fbconfig_for_visinfo(Display *dpy, XVisualInfo *visinfo); 34 | 35 | XVisualInfo * 36 | get_glx_visual(Display *dpy); 37 | 38 | Window 39 | get_glx_window(Display *dpy, XVisualInfo *visinfo, bool map); 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # X.Org module default exclusion patterns 3 | # The next section if for module specific patterns 4 | # 5 | # Do not edit the following section 6 | # GNU Build System (Autotools) 7 | aclocal.m4 8 | autom4te.cache/ 9 | autoscan.log 10 | ChangeLog 11 | compile 12 | config.guess 13 | config.h 14 | config.h.in 15 | config.log 16 | config-ml.in 17 | config.py 18 | config.status 19 | config.status.lineno 20 | config.sub 21 | configure 22 | configure.scan 23 | depcomp 24 | .deps/ 25 | INSTALL 26 | install-sh 27 | .libs/ 28 | libtool 29 | libtool.m4 30 | ltmain.sh 31 | lt~obsolete.m4 32 | ltoptions.m4 33 | ltsugar.m4 34 | ltversion.m4 35 | Makefile 36 | Makefile.in 37 | mdate-sh 38 | missing 39 | mkinstalldirs 40 | *.pc 41 | py-compile 42 | stamp-h? 43 | symlink-tree 44 | texinfo.tex 45 | ylwrap 46 | src/sna/git_version.h 47 | src/sna/brw/brw_test 48 | 49 | # Do not edit the following section 50 | # Edit Compile Debug Document Distribute 51 | *~ 52 | *.[0-9] 53 | *.[0-9]x 54 | *.bak 55 | *.bin 56 | core 57 | *.dll 58 | *.exe 59 | *-ISO*.bdf 60 | *-JIS*.bdf 61 | *-KOI8*.bdf 62 | *.kld 63 | *.ko 64 | *.ko.cmd 65 | *.lai 66 | *.l[oa] 67 | *.[oa] 68 | *.obj 69 | *.patch 70 | *.so 71 | *.pcf.gz 72 | *.pdb 73 | *.tar.bz2 74 | *.tar.gz 75 | # 76 | # Add & Override patterns for gldispatch 77 | # 78 | # Edit the following section as needed 79 | # For example, !report.pc overrides *.pc. See 'man gitignore' 80 | # 81 | configure.lineno 82 | .dirstamp 83 | test-driver 84 | 85 | gl_generated_dispatch.c 86 | gl_generated.h 87 | 88 | glx_generated_dispatch.c 89 | glx_generated.h 90 | 91 | egl_generated_dispatch.c 92 | egl_generated.h 93 | 94 | wgl_generated_dispatch.c 95 | wgl_generated.h 96 | -------------------------------------------------------------------------------- /test/headerguards.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include "config.h" 25 | 26 | #include 27 | 28 | #ifdef BUILD_EGL 29 | #include 30 | #include 31 | #endif 32 | 33 | #ifdef BUILD_GLX 34 | #include 35 | #include 36 | #endif 37 | 38 | #ifdef BUILD_EGL 39 | #include 40 | #include 41 | #include 42 | #include 43 | #endif 44 | 45 | #ifdef BUILD_GLX 46 | #ifdef __APPLE__ 47 | #include 48 | #include 49 | #else 50 | #include 51 | #include 52 | #endif 53 | #include 54 | #include 55 | #endif 56 | 57 | int main(int argc, char **argv) 58 | { 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /test/khronos_typedefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2014 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | 26 | enum typedef_slot { 27 | khronos_int8_t_slot, 28 | khronos_uint8_t_slot, 29 | khronos_int16_t_slot, 30 | khronos_uint16_t_slot, 31 | khronos_int32_t_slot, 32 | khronos_uint32_t_slot, 33 | khronos_int64_t_slot, 34 | khronos_uint64_t_slot, 35 | khronos_intptr_t_slot, 36 | khronos_uintptr_t_slot, 37 | khronos_ssize_t_slot, 38 | khronos_usize_t_slot, 39 | khronos_float_t_slot, 40 | /* khrplatform.h claims it defines khronos_time_ns_t, but it doesn't. */ 41 | khronos_utime_nanoseconds_t_slot, 42 | khronos_stime_nanoseconds_t_slot, 43 | khronos_boolean_enum_t_slot, 44 | khronos_typedef_count 45 | }; 46 | 47 | void get_system_typedef_sizes(uint32_t *sizes); 48 | -------------------------------------------------------------------------------- /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | 3 | image: Visual Studio 2015 4 | 5 | configuration: Release 6 | 7 | # Configure both 32-bit and 64-bit builds 8 | environment: 9 | matrix: 10 | - platform: x86 11 | config: Win32 12 | pout: x86 13 | - platform: x64 14 | config: x64 15 | pout: x64 16 | 17 | shallow_clone: true 18 | 19 | # Download Meson and Ninja, create install directory 20 | before_build: 21 | - mkdir build 22 | - mkdir libepoxy-shared-%pout% 23 | - cd build 24 | - curl -LsSO https://github.com/mesonbuild/meson/releases/download/0.39.1/meson-0.39.1.tar.gz 25 | - 7z x meson-0.39.1.tar.gz 26 | - move dist\meson-0.39.1.tar . 27 | - 7z x meson-0.39.1.tar 28 | - rmdir dist 29 | - del meson-0.39.1.tar meson-0.39.1.tar.gz 30 | - curl -LsSO https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-win.zip 31 | - 7z x ninja-win.zip 32 | - del ninja-win.zip 33 | - cd .. 34 | 35 | # Build and install 36 | build_script: 37 | - cd build 38 | - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %PLATFORM% 39 | - C:\Python36\python.exe meson-0.39.1\meson.py .. . --backend=ninja --prefix=%APPVEYOR_BUILD_FOLDER%\libepoxy-shared-%pout% 40 | - ninja 41 | - ninja install 42 | - cd .. 43 | 44 | # Copy license into install directory and create .zip file 45 | after_build: 46 | - copy COPYING libepoxy-shared-%pout% 47 | - dir libepoxy-shared-%pout% /s /b 48 | - 7z a -tzip libepoxy-shared-%pout%.zip libepoxy-shared-%pout% 49 | 50 | artifacts: 51 | - path: libepoxy-shared-%pout%.zip 52 | name: libepoxy-shared-%pout% 53 | 54 | test: off 55 | 56 | # Upload .zip file to GitHub release 57 | deploy: 58 | release: $(APPVEYOR_REPO_TAG_NAME) 59 | description: "Epoxy $(APPVEYOR_REPO_TAG_NAME)" 60 | provider: GitHub 61 | auth_token: 62 | secure: X7Ro8Y2RWYo/M1AAn93f9X0dEQFvu7gPb6li2eKRtzPYLGj/JKm7MNWRw2cCcjm6 63 | artifact: libepoxy-shared-$(pout) 64 | draft: false 65 | prerelease: false 66 | on: 67 | appveyor_repo_tag: true # deploy on tag push only 68 | -------------------------------------------------------------------------------- /test/egl_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include "egl_common.h" 27 | 28 | /** 29 | * Do whatever it takes to get us an EGL display for the system. 30 | * 31 | * This needs to be ported to other window systems. 32 | */ 33 | EGLDisplay * 34 | get_egl_display_or_skip(void) 35 | { 36 | Display *dpy = XOpenDisplay(NULL); 37 | EGLint major, minor; 38 | EGLDisplay *edpy; 39 | bool ok; 40 | 41 | if (!dpy) 42 | errx(77, "couldn't open display\n"); 43 | 44 | edpy = eglGetDisplay(dpy); 45 | if (!edpy) 46 | errx(1, "Couldn't get EGL display for X11 Display.\n"); 47 | 48 | ok = eglInitialize(edpy, &major, &minor); 49 | if (!ok) 50 | errx(1, "eglInitialize() failed\n"); 51 | 52 | return edpy; 53 | } 54 | -------------------------------------------------------------------------------- /test/miscdefines.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | 26 | #ifdef BUILD_EGL 27 | #include 28 | #endif 29 | 30 | #ifdef BUILD_GLX 31 | #include 32 | #endif 33 | 34 | #if GL_VERSION_3_2 != 1 35 | #error bad GL_VERSION_3_2 36 | #endif 37 | 38 | #if GL_ARB_ES2_compatibility != 1 39 | #error bad GL_ARB_ES2_compatibility 40 | #endif 41 | 42 | #ifndef GLAPI 43 | #error missing GLAPI 44 | #endif 45 | 46 | #ifndef GLAPIENTRY 47 | #error missing GLAPIENTRY 48 | #endif 49 | 50 | #ifndef GLAPIENTRYP 51 | #error missing GLAPIENTRYP 52 | #endif 53 | 54 | #ifndef APIENTRY 55 | #error missing APIENTRY 56 | #endif 57 | 58 | #ifndef APIENTRYP 59 | #error missing APIENTRYP 60 | #endif 61 | 62 | /* Do we want to export GL_GLEXT_VERSION? */ 63 | 64 | int main(int argc, char **argv) 65 | { 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /include/epoxy/egl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** @file egl.h 25 | * 26 | * Provides an implementation of an EGL dispatch layer using global 27 | * function pointers 28 | * 29 | * You should include `` instead of ``. 30 | */ 31 | 32 | #ifndef EPOXY_EGL_H 33 | #define EPOXY_EGL_H 34 | 35 | #include "epoxy/common.h" 36 | 37 | #if defined(__egl_h_) || defined(__eglext_h_) 38 | #error epoxy/egl.h must be included before (or in place of) GL/egl.h 39 | #else 40 | #define __egl_h_ 41 | #define __eglext_h_ 42 | #endif 43 | 44 | EPOXY_BEGIN_DECLS 45 | 46 | #include "epoxy/egl_generated.h" 47 | 48 | EPOXY_PUBLIC bool epoxy_has_egl_extension(EGLDisplay dpy, const char *extension); 49 | EPOXY_PUBLIC int epoxy_egl_version(EGLDisplay dpy); 50 | EPOXY_PUBLIC bool epoxy_has_egl(void); 51 | 52 | EPOXY_END_DECLS 53 | 54 | #endif /* EPOXY_EGL_H */ 55 | -------------------------------------------------------------------------------- /include/epoxy/wgl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** @file wgl.h 25 | * 26 | * Provides an implementation of a WGL dispatch layer using a hidden 27 | * vtable. 28 | */ 29 | 30 | #ifndef EPOXY_WGL_H 31 | #define EPOXY_WGL_H 32 | 33 | #include 34 | 35 | #include "epoxy/common.h" 36 | 37 | #undef wglUseFontBitmaps 38 | #undef wglUseFontOutlines 39 | 40 | #if defined(__wglxext_h_) 41 | #error epoxy/wgl.h must be included before (or in place of) wgl.h 42 | #else 43 | #define __wglxext_h_ 44 | #endif 45 | 46 | #ifdef UNICODE 47 | #define wglUseFontBitmaps wglUseFontBitmapsW 48 | #else 49 | #define wglUseFontBitmaps wglUseFontBitmapsA 50 | #endif 51 | 52 | EPOXY_BEGIN_DECLS 53 | 54 | #include "epoxy/wgl_generated.h" 55 | 56 | EPOXY_PUBLIC bool epoxy_has_wgl_extension(HDC hdc, const char *extension); 57 | EPOXY_PUBLIC void epoxy_handle_external_wglMakeCurrent(void); 58 | 59 | EPOXY_END_DECLS 60 | 61 | #endif /* EPOXY_WGL_H */ 62 | -------------------------------------------------------------------------------- /test/glx_glxgetprocaddress_nocontext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file glx_glxgetprocaddress_nocontext.c 26 | * 27 | * Catches a bug in early development where glXGetProcAddress() with 28 | * no context bound would fail out in dispatch. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include "epoxy/gl.h" 35 | #include "epoxy/glx.h" 36 | #include 37 | 38 | #include "glx_common.h" 39 | 40 | static Display *dpy; 41 | 42 | int 43 | main(int argc, char **argv) 44 | { 45 | bool pass = true; 46 | void *func; 47 | 48 | dpy = get_display_or_skip(); 49 | if (epoxy_glx_version(dpy, 0) < 14) 50 | errx(77, "GLX version 1.4 required for glXGetProcAddress().\n"); 51 | 52 | func = glXGetProcAddress((const GLubyte *)"glGetString"); 53 | if (!func) 54 | errx(1, "glXGetProcAddress() returned NULL\n"); 55 | 56 | return pass != true; 57 | } 58 | -------------------------------------------------------------------------------- /test/glx_has_extension_nocontext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file glx_has_extension_nocontext.c 26 | * 27 | * Catches a bug in early development where glXGetProcAddress() with 28 | * no context bound would fail out in dispatch. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include "epoxy/gl.h" 35 | #include "epoxy/glx.h" 36 | #include 37 | 38 | #include "glx_common.h" 39 | 40 | static Display *dpy; 41 | 42 | int 43 | main(int argc, char **argv) 44 | { 45 | bool pass = true; 46 | 47 | dpy = get_display_or_skip(); 48 | 49 | if (!epoxy_has_glx_extension(dpy, 0, "GLX_ARB_get_proc_address")) 50 | errx(1, "Implementation reported absence of GLX_ARB_get_proc_address"); 51 | 52 | if (epoxy_has_glx_extension(dpy, 0, "GLX_ARB_ham_sandwich")) 53 | errx(1, "Implementation reported presence of GLX_ARB_ham_sandwich"); 54 | 55 | return pass != true; 56 | } 57 | -------------------------------------------------------------------------------- /include/epoxy/glx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** @file glx.h 25 | * 26 | * Provides an implementation of a GLX dispatch layer using global 27 | * function pointers. 28 | * 29 | * You should include `` instead of ``. 30 | */ 31 | 32 | #ifndef EPOXY_GLX_H 33 | #define EPOXY_GLX_H 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #if defined(GLX_H) || defined(__glxext_h_) 40 | #error epoxy/glx.h must be included before (or in place of) GL/glx.h 41 | #else 42 | #define GLX_H 43 | #define __glx_h__ 44 | #define __glxext_h_ 45 | #endif 46 | 47 | EPOXY_BEGIN_DECLS 48 | 49 | #include "epoxy/glx_generated.h" 50 | 51 | EPOXY_PUBLIC bool epoxy_has_glx_extension(Display *dpy, int screen, const char *extension); 52 | EPOXY_PUBLIC int epoxy_glx_version(Display *dpy, int screen); 53 | EPOXY_PUBLIC bool epoxy_has_glx(Display *dpy); 54 | 55 | EPOXY_END_DECLS 56 | 57 | #endif /* EPOXY_GLX_H */ 58 | -------------------------------------------------------------------------------- /include/epoxy/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Emmanuele Bassi 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** @file common.h 25 | * 26 | * A common header file, used to define macros and shared symbols. 27 | */ 28 | 29 | #ifndef EPOXY_COMMON_H 30 | #define EPOXY_COMMON_H 31 | 32 | #ifdef __cplusplus 33 | # define EPOXY_BEGIN_DECLS extern "C" { 34 | # define EPOXY_END_DECLS } 35 | #else 36 | # define EPOXY_BEGIN_DECLS 37 | # define EPOXY_END_DECLS 38 | #endif 39 | 40 | #ifndef EPOXY_PUBLIC 41 | # if defined(_MSC_VER) 42 | # define EPOXY_PUBLIC __declspec(dllimport) extern 43 | # else 44 | # define EPOXY_PUBLIC extern 45 | # endif 46 | #endif 47 | 48 | #if defined(_MSC_VER) && !defined(__bool_true_false_are_defined) && (_MSC_VER < 1800) 49 | typedef unsigned char bool; 50 | # define false 0 51 | # define true 1 52 | #else 53 | # include 54 | #endif 55 | 56 | EPOXY_BEGIN_DECLS 57 | 58 | EPOXY_PUBLIC bool epoxy_extension_in_string(const char *extension_list, 59 | const char *ext); 60 | 61 | EPOXY_END_DECLS 62 | 63 | #endif /* EPOXY_COMMON_H */ 64 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | # Copyright © 2013 Intel Corporation 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a 5 | # copy of this software and associated documentation files (the "Software"), 6 | # to deal in the Software without restriction, including without limitation 7 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | # and/or sell copies of the Software, and to permit persons to whom the 9 | # Software is furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice (including the next 12 | # paragraph) shall be included in all copies or substantial portions of the 13 | # Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | # IN THE SOFTWARE. 22 | 23 | ACLOCAL_AMFLAGS = -I m4 24 | 25 | SUBDIRS = include/epoxy src 26 | 27 | SUBDIRS += test 28 | 29 | pkgconfigdir = $(libdir)/pkgconfig 30 | pkgconfig_DATA = epoxy.pc 31 | 32 | registry_files = \ 33 | registry/egl.xml \ 34 | registry/gl.xml \ 35 | registry/glx.xml \ 36 | registry/wgl.xml \ 37 | $() 38 | 39 | meson_build_files = \ 40 | meson_options.txt \ 41 | meson.build \ 42 | include/epoxy/meson.build \ 43 | src/meson.build \ 44 | test/meson.build \ 45 | doc/meson.build \ 46 | doc/Doxyfile.in \ 47 | cross/fedora-mingw64.txt \ 48 | $() 49 | 50 | EXTRA_DIST = \ 51 | .dir-locals.el \ 52 | README.md \ 53 | autogen.sh \ 54 | epoxy.pc.in \ 55 | $(registry_files) \ 56 | $(meson_build_files) \ 57 | $() 58 | 59 | dist-hook: 60 | @if test -d "$(top_srcdir)/.git"; then \ 61 | echo Generating ChangeLog... ; \ 62 | ( $(top_srcdir)/missing --run git log --stat ) > "$(top_srcdir)/ChangeLog.tmp" \ 63 | && mv -f "$(top_srcdir)/ChangeLog.tmp" "$(top_distdir)/ChangeLog" \ 64 | || ( rm -f "$(top_srcdir)/ChangeLog.tmp"; \ 65 | echo Failed to generate ChangeLog >&2 ); \ 66 | else \ 67 | echo A git checkout is required to generate a ChangeLog >&2; \ 68 | fi 69 | -------------------------------------------------------------------------------- /test/glx_static.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file glx_static.c 26 | * 27 | * Simple touch-test of using epoxy when linked statically. On Linux, 28 | * the ifunc support we'd like to use has some significant behavior 29 | * changes depending on whether it's a static build or shared library 30 | * build. 31 | * 32 | * Note that if configured without --enable-static, this test will end 33 | * up dynamically linked anyway, defeating the test. 34 | */ 35 | 36 | #include 37 | #include 38 | #include "epoxy/gl.h" 39 | #include "epoxy/glx.h" 40 | #include 41 | #include 42 | 43 | #include "glx_common.h" 44 | 45 | int 46 | main(int argc, char **argv) 47 | { 48 | bool pass = true; 49 | int val; 50 | 51 | #if NEEDS_TO_BE_STATIC 52 | if (dlsym(NULL, "epoxy_glCompileShader")) { 53 | fprintf(stderr, "glx_static requires epoxy built with --enable-static\n"); 54 | return 77; 55 | } 56 | #endif 57 | 58 | Display *dpy = get_display_or_skip(); 59 | make_glx_context_current_or_skip(dpy); 60 | 61 | glEnable(GL_LIGHTING); 62 | val = 0; 63 | glGetIntegerv(GL_LIGHTING, &val); 64 | if (!val) { 65 | fprintf(stderr, "Enabling GL_LIGHTING didn't stick.\n"); 66 | pass = false; 67 | } 68 | 69 | return pass != true; 70 | } 71 | -------------------------------------------------------------------------------- /test/khronos_typedefs_nonepoxy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2014 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | #include "config.h" 28 | #include "khronos_typedefs.h" 29 | 30 | #ifdef HAVE_KHRPLATFORM_H 31 | 32 | #include 33 | 34 | #define GET_SIZE(type) sizes[type ## _slot] = sizeof(type) 35 | 36 | void 37 | get_system_typedef_sizes(uint32_t *sizes) 38 | { 39 | GET_SIZE(khronos_int8_t); 40 | GET_SIZE(khronos_uint8_t); 41 | GET_SIZE(khronos_int16_t); 42 | GET_SIZE(khronos_uint16_t); 43 | GET_SIZE(khronos_int32_t); 44 | GET_SIZE(khronos_uint32_t); 45 | GET_SIZE(khronos_int64_t); 46 | GET_SIZE(khronos_uint64_t); 47 | GET_SIZE(khronos_intptr_t); 48 | GET_SIZE(khronos_uintptr_t); 49 | GET_SIZE(khronos_ssize_t); 50 | GET_SIZE(khronos_usize_t); 51 | GET_SIZE(khronos_float_t); 52 | GET_SIZE(khronos_utime_nanoseconds_t); 53 | GET_SIZE(khronos_stime_nanoseconds_t); 54 | GET_SIZE(khronos_boolean_enum_t); 55 | } 56 | 57 | #else /* !HAVE_KHRPLATFORM_H */ 58 | 59 | /* Don't care -- this is a conditional case in test code. */ 60 | #pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" 61 | 62 | void 63 | get_system_typedef_sizes(uint32_t *sizes) 64 | { 65 | fprintf(stderr, "./configure failed to find khrplatform.h\n"); 66 | exit(77); 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /test/wgl_usefontbitmaps.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | 26 | #include "wgl_common.h" 27 | #include 28 | 29 | static int 30 | test_function(HDC hdc) 31 | { 32 | bool pass = true; 33 | HGLRC ctx; 34 | GLuint dlist[2] = {100, 101}; 35 | const char *string = "some string"; 36 | 37 | ctx = wglCreateContext(hdc); 38 | if (!ctx) { 39 | fprintf(stderr, "Failed to create wgl context\n"); 40 | return 1; 41 | } 42 | if (!wglMakeCurrent(hdc, ctx)) { 43 | fprintf(stderr, "Failed to make context current\n"); 44 | return 1; 45 | } 46 | 47 | /* First, use the #ifdeffed variant of the function */ 48 | wglUseFontBitmaps(hdc, 0, 255, dlist[0]); 49 | glListBase(dlist[1]); 50 | glCallLists(strlen(string), GL_UNSIGNED_BYTE, string); 51 | 52 | /* Now, use the specific version, manually. */ 53 | #ifdef UNICODE 54 | wglUseFontBitmapsW(hdc, 0, 255, dlist[0]); 55 | #else 56 | wglUseFontBitmapsA(hdc, 0, 255, dlist[0]); 57 | #endif 58 | glListBase(dlist[1]); 59 | glCallLists(strlen(string), GL_UNSIGNED_BYTE, string); 60 | 61 | wglMakeCurrent(NULL, NULL); 62 | wglDeleteContext(ctx); 63 | 64 | return !pass; 65 | } 66 | 67 | int 68 | main(int argc, char **argv) 69 | { 70 | make_window_and_test(test_function); 71 | 72 | /* UNREACHED */ 73 | return 1; 74 | } 75 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | The libepoxy project code is covered by the MIT license: 2 | 3 | /* 4 | * Copyright © 2013-2014 Intel Corporation 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a 7 | * copy of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice (including the next 14 | * paragraph) shall be included in all copies or substantial portions of the 15 | * Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | * IN THE SOFTWARE. 24 | */ 25 | 26 | The generated code is derived from Khronos's xml files, which appear 27 | under the following license: 28 | 29 | /* 30 | * Copyright (c) 2013 The Khronos Group Inc. 31 | * 32 | * Permission is hereby granted, free of charge, to any person obtaining a 33 | * copy of this software and/or associated documentation files (the 34 | * "Materials"), to deal in the Materials without restriction, including 35 | * without limitation the rights to use, copy, modify, merge, publish, 36 | * distribute, sublicense, and/or sell copies of the Materials, and to 37 | * permit persons to whom the Materials are furnished to do so, subject to 38 | * the following conditions: 39 | * 40 | * The above copyright notice and this permission notice shall be included 41 | * in all copies or substantial portions of the Materials. 42 | * 43 | * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 44 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 45 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 46 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 47 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 48 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 49 | * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 50 | */ 51 | -------------------------------------------------------------------------------- /test/glx_alias_prefer_same_name.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file glx_gles2.c 26 | * 27 | * Catches a bug where a GLES2 context using 28 | * GLX_EXT_create_context_es2_profile would try to find the symbols in 29 | * libGLESv2.so.2 instead of libGL.so.1. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include "epoxy/gl.h" 36 | #include "epoxy/glx.h" 37 | #include 38 | 39 | #include "glx_common.h" 40 | 41 | static Display *dpy; 42 | 43 | static int last_call; 44 | 45 | #define CORE_FUNC_VAL 100 46 | #define EXT_FUNC_VAL 101 47 | 48 | void 49 | override_GL_glBindTexture(GLenum target); 50 | void 51 | override_GL_glBindTextureEXT(GLenum target); 52 | 53 | void 54 | override_GL_glBindTexture(GLenum target) 55 | { 56 | last_call = CORE_FUNC_VAL; 57 | } 58 | 59 | void 60 | override_GL_glBindTextureEXT(GLenum target) 61 | { 62 | last_call = EXT_FUNC_VAL; 63 | } 64 | 65 | int 66 | main(int argc, char **argv) 67 | { 68 | bool pass = true; 69 | 70 | dpy = get_display_or_skip(); 71 | make_glx_context_current_or_skip(dpy); 72 | 73 | if (!epoxy_has_gl_extension("GL_EXT_texture_object")) 74 | errx(77, "Test requires GL_EXT_texture_object"); 75 | 76 | glBindTexture(GL_TEXTURE_2D, 1); 77 | pass = pass && last_call == CORE_FUNC_VAL; 78 | glBindTextureEXT(GL_TEXTURE_2D, 1); 79 | pass = pass && last_call == EXT_FUNC_VAL; 80 | 81 | return pass != true; 82 | } 83 | -------------------------------------------------------------------------------- /test/egl_has_extension_nocontext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file egl_has_extension_nocontext.c 26 | * 27 | * Catches a bug in early development where eglGetProcAddress() with 28 | * no context bound would fail out in dispatch. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include "epoxy/gl.h" 37 | #include "epoxy/egl.h" 38 | 39 | #include "egl_common.h" 40 | 41 | int 42 | main(int argc, char **argv) 43 | { 44 | bool pass = true; 45 | 46 | EGLDisplay *dpy = get_egl_display_or_skip(); 47 | const char *extensions = eglQueryString(dpy, EGL_EXTENSIONS); 48 | char *first_space; 49 | char *an_extension; 50 | 51 | /* We don't have any extensions guaranteed by the ABI, so for the 52 | * touch test we just check if the first one is reported to be there. 53 | */ 54 | first_space = strstr(extensions, " "); 55 | if (first_space) { 56 | an_extension = strndup(extensions, first_space - extensions); 57 | } else { 58 | an_extension = strdup(extensions); 59 | } 60 | 61 | if (!epoxy_has_egl_extension(dpy, an_extension)) 62 | errx(1, "Implementation reported absence of %s", an_extension); 63 | 64 | free(an_extension); 65 | 66 | if (epoxy_has_egl_extension(dpy, "GLX_ARB_ham_sandwich")) 67 | errx(1, "Implementation reported presence of GLX_ARB_ham_sandwich"); 68 | 69 | return pass != true; 70 | } 71 | -------------------------------------------------------------------------------- /test/wgl_core_and_exts.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | 26 | #include "wgl_common.h" 27 | #include 28 | 29 | static int 30 | test_function(HDC hdc) 31 | { 32 | bool pass = true; 33 | int val; 34 | HGLRC ctx; 35 | 36 | ctx = wglCreateContext(hdc); 37 | if (!ctx) { 38 | fprintf(stderr, "Failed to create wgl context\n"); 39 | return 1; 40 | } 41 | if (!wglMakeCurrent(hdc, ctx)) { 42 | fprintf(stderr, "Failed to make context current\n"); 43 | return 1; 44 | } 45 | 46 | /* GL 1.0 APIs are available as symbols in opengl32.dll. */ 47 | glEnable(GL_LIGHTING); 48 | val = 0; 49 | glGetIntegerv(GL_LIGHTING, &val); 50 | if (!val) { 51 | fprintf(stderr, "Enabling GL_LIGHTING didn't stick.\n"); 52 | pass = false; 53 | } 54 | 55 | if (epoxy_gl_version() >= 15 || 56 | epoxy_has_gl_extension("GL_ARB_vertex_buffer_object")) { 57 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 1234); 58 | 59 | val = 0; 60 | glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &val); 61 | if (val != 1234) { 62 | printf("GL_ELEMENT_ARRAY_BUFFER_BINDING didn't stick: %d\n", val); 63 | pass = false; 64 | } 65 | } 66 | 67 | wglMakeCurrent(NULL, NULL); 68 | wglDeleteContext(ctx); 69 | 70 | return !pass; 71 | } 72 | 73 | int 74 | main(int argc, char **argv) 75 | { 76 | make_window_and_test(test_function); 77 | 78 | /* UNREACHED */ 79 | return 1; 80 | } 81 | -------------------------------------------------------------------------------- /test/khronos_typedefs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2014 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include "khronos_typedefs.h" 26 | #include "epoxy/gl.h" 27 | 28 | #define COMPARE_SIZE(type) \ 29 | do { \ 30 | if (sizeof(type) != system_sizes[type ## _slot]) { \ 31 | fprintf(stderr, "system %s is size %d, epoxy is %d\n", \ 32 | #type, \ 33 | (int)system_sizes[type ## _slot], \ 34 | (int)sizeof(type)); \ 35 | error = true; \ 36 | } \ 37 | } while (0) 38 | 39 | int 40 | main(int argc, char **argv) 41 | { 42 | uint32_t system_sizes[khronos_typedef_count]; 43 | bool error = false; 44 | 45 | get_system_typedef_sizes(system_sizes); 46 | 47 | COMPARE_SIZE(khronos_int8_t); 48 | COMPARE_SIZE(khronos_uint8_t); 49 | COMPARE_SIZE(khronos_int16_t); 50 | COMPARE_SIZE(khronos_uint16_t); 51 | COMPARE_SIZE(khronos_int32_t); 52 | COMPARE_SIZE(khronos_uint32_t); 53 | COMPARE_SIZE(khronos_int64_t); 54 | COMPARE_SIZE(khronos_uint64_t); 55 | COMPARE_SIZE(khronos_intptr_t); 56 | COMPARE_SIZE(khronos_uintptr_t); 57 | COMPARE_SIZE(khronos_ssize_t); 58 | COMPARE_SIZE(khronos_usize_t); 59 | COMPARE_SIZE(khronos_float_t); 60 | COMPARE_SIZE(khronos_utime_nanoseconds_t); 61 | COMPARE_SIZE(khronos_stime_nanoseconds_t); 62 | COMPARE_SIZE(khronos_boolean_enum_t); 63 | 64 | return error; 65 | } 66 | -------------------------------------------------------------------------------- /test/dlwrap.h: -------------------------------------------------------------------------------- 1 | /* Copyright © 2013, Intel Corporation 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | * THE SOFTWARE. 20 | */ 21 | 22 | #ifndef DLWRAP_H 23 | #define DLWRAP_H 24 | 25 | #define _GNU_SOURCE 26 | #include 27 | 28 | /* Call the *real* dlopen. We have our own wrapper for dlopen that, of 29 | * necessity must use claim the symbol 'dlopen'. So whenever anything 30 | * internal needs to call the real, underlying dlopen function, the 31 | * thing to call is dlwrap_real_dlopen. 32 | */ 33 | void * 34 | dlwrap_real_dlopen(const char *filename, int flag); 35 | 36 | /* Perform a dlopen on the libfips library itself. 37 | * 38 | * Many places in fips need to lookup symbols within the libfips 39 | * library itself, (and not in any other library). This function 40 | * provides a reliable way to get a handle for performing such 41 | * lookups. 42 | * 43 | * The returned handle can be passed to dlwrap_real_dlsym for the 44 | * lookups. */ 45 | void * 46 | dlwrap_dlopen_libfips(void); 47 | 48 | /* Call the *real* dlsym. We have our own wrapper for dlsym that, of 49 | * necessity must use claim the symbol 'dlsym'. So whenever anything 50 | * internal needs to call the real, underlying dlysm function, the 51 | * thing to call is dlwrap_real_dlsym. 52 | */ 53 | void * 54 | dlwrap_real_dlsym(void *handle, const char *symbol); 55 | 56 | #define DEFER_TO_GL(library, func, name, args) \ 57 | ({ \ 58 | void *lib = dlwrap_real_dlopen(library, RTLD_LAZY | RTLD_LOCAL); \ 59 | typeof(&func) real_func = dlwrap_real_dlsym(lib, name); \ 60 | /* gcc extension -- func's return value is the return value of \ 61 | * the statement. \ 62 | */ \ 63 | real_func args; \ 64 | }) 65 | 66 | #endif 67 | 68 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | # Configuration file 2 | configure_file(output: 'config.h', configuration: conf) 3 | 4 | # List of generated sources: 5 | # - name of the generated file 6 | # - registry source file 7 | # - additional sources 8 | generated_sources = [ 9 | [ 'gl_generated_dispatch.c', gl_registry, [ 'dispatch_common.c', 'dispatch_common.h' ] ] 10 | ] 11 | 12 | if build_egl 13 | generated_sources += [ [ 'egl_generated_dispatch.c', egl_registry, 'dispatch_egl.c' ] ] 14 | endif 15 | 16 | if build_glx 17 | generated_sources += [ [ 'glx_generated_dispatch.c', glx_registry, 'dispatch_glx.c' ] ] 18 | endif 19 | 20 | if build_wgl 21 | generated_sources += [ [ 'wgl_generated_dispatch.c', wgl_registry, 'dispatch_wgl.c' ] ] 22 | endif 23 | 24 | gen_sources = [ ] 25 | sources = [ ] 26 | 27 | foreach g: generated_sources 28 | gen_source = g[0] 29 | registry = g[1] 30 | source = g[2] 31 | 32 | generated = custom_target(gen_source, 33 | input: registry, 34 | output: [ gen_source ], 35 | command: [ 36 | python, 37 | gen_dispatch_py, 38 | '--source', 39 | '--no-header', 40 | '--outputdir=@OUTDIR@', 41 | '@INPUT@', 42 | ]) 43 | 44 | gen_sources += [ generated ] 45 | sources += [ source ] 46 | endforeach 47 | 48 | epoxy_sources = sources + gen_sources 49 | 50 | common_ldflags = [] 51 | 52 | if host_system == 'linux' 53 | foreach f: [ '-Wl,-Bsymbolic', '-Wl,-z,relro', '-Wl,-z,now', ] 54 | if cc.has_argument(f) 55 | common_ldflags += f 56 | endif 57 | endforeach 58 | endif 59 | 60 | # Maintain compatibility with autotools; see: https://github.com/anholt/libepoxy/issues/108 61 | if host_system == 'darwin' 62 | common_ldflags += [ '-compatibility_version 1', '-current_version 1.0', ] 63 | endif 64 | 65 | epoxy_deps = [ dl_dep, ] 66 | if host_system == 'windows' 67 | epoxy_deps += [ opengl32_dep, gdi32_dep ] 68 | endif 69 | 70 | # Allow building a static version of epoxy 71 | if libtype != 'shared' 72 | libepoxy_static = static_library('epoxy', 73 | sources: epoxy_sources + epoxy_headers, 74 | install: true, 75 | dependencies: epoxy_deps, 76 | include_directories: libepoxy_inc, 77 | c_args: common_cflags + visibility_cflags, 78 | link_args: common_ldflags) 79 | libepoxy = libepoxy_static 80 | endif 81 | 82 | if libtype != 'static' 83 | libepoxy_shared = shared_library('epoxy', 84 | sources: epoxy_sources + epoxy_headers, 85 | version: '0.0.0', 86 | install: true, 87 | dependencies: epoxy_deps, 88 | include_directories: libepoxy_inc, 89 | c_args: common_cflags + visibility_cflags, 90 | link_args: common_ldflags) 91 | libepoxy = libepoxy_shared 92 | endif 93 | 94 | libepoxy_dep = declare_dependency(link_with: libepoxy, 95 | include_directories: libepoxy_inc, 96 | dependencies: epoxy_deps, 97 | sources: epoxy_headers) 98 | -------------------------------------------------------------------------------- /include/epoxy/gl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** @file gl.h 25 | * 26 | * Provides an implementation of a GL dispatch layer using either 27 | * global function pointers or a hidden vtable. 28 | * 29 | * You should include `` instead of `` and ``. 30 | */ 31 | 32 | #ifndef EPOXY_GL_H 33 | #define EPOXY_GL_H 34 | 35 | #include "epoxy/common.h" 36 | 37 | #if defined(__gl_h_) || defined(__glext_h_) 38 | #error epoxy/gl.h must be included before (or in place of) GL/gl.h 39 | #else 40 | #define __gl_h_ 41 | #define __glext_h_ 42 | #endif 43 | 44 | #define KHRONOS_SUPPORT_INT64 1 45 | #define KHRONOS_SUPPORT_FLOAT 1 46 | #define KHRONOS_APIATTRIBUTES 47 | 48 | #ifndef _WIN32 49 | /* APIENTRY and GLAPIENTRY are not used on Linux or Mac. */ 50 | #define APIENTRY 51 | #define GLAPIENTRY 52 | #define EPOXY_CALLSPEC 53 | #define GLAPI 54 | #define KHRONOS_APIENTRY 55 | #define KHRONOS_APICALL 56 | 57 | #else 58 | #ifndef APIENTRY 59 | #define APIENTRY __stdcall 60 | #endif 61 | 62 | #ifndef GLAPIENTRY 63 | #define GLAPIENTRY APIENTRY 64 | #endif 65 | 66 | #ifndef EPOXY_CALLSPEC 67 | #define EPOXY_CALLSPEC __stdcall 68 | #endif 69 | 70 | #ifndef GLAPI 71 | #define GLAPI extern 72 | #endif 73 | 74 | #define KHRONOS_APIENTRY __stdcall 75 | #define KHRONOS_APICALL __declspec(dllimport) __stdcall 76 | 77 | #endif /* _WIN32 */ 78 | 79 | #ifndef APIENTRYP 80 | #define APIENTRYP APIENTRY * 81 | #endif 82 | 83 | #ifndef GLAPIENTRYP 84 | #define GLAPIENTRYP GLAPIENTRY * 85 | #endif 86 | 87 | EPOXY_BEGIN_DECLS 88 | 89 | #include "epoxy/gl_generated.h" 90 | 91 | EPOXY_PUBLIC bool epoxy_has_gl_extension(const char *extension); 92 | EPOXY_PUBLIC bool epoxy_is_desktop_gl(void); 93 | EPOXY_PUBLIC int epoxy_gl_version(void); 94 | 95 | /* 96 | * the type of the stub function that the failure handler must return; 97 | * this function will be called on subsequent calls to the same bogus 98 | * function name 99 | */ 100 | typedef void (*epoxy_resolver_stub_t)(void); 101 | 102 | /* the type of the failure handler itself */ 103 | typedef epoxy_resolver_stub_t 104 | (*epoxy_resolver_failure_handler_t)(const char *name); 105 | 106 | EPOXY_PUBLIC epoxy_resolver_failure_handler_t 107 | epoxy_set_resolver_failure_handler(epoxy_resolver_failure_handler_t handler); 108 | 109 | EPOXY_END_DECLS 110 | 111 | #endif /* EPOXY_GL_H */ 112 | -------------------------------------------------------------------------------- /test/glx_beginend.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include "epoxy/gl.h" 27 | #include "epoxy/glx.h" 28 | #include 29 | 30 | #include "glx_common.h" 31 | 32 | static Display *dpy; 33 | static bool has_argb2101010; 34 | 35 | static bool 36 | test_with_epoxy(void) 37 | { 38 | glBegin(GL_TRIANGLES); 39 | { 40 | /* Hit a base entrypoint that won't call gl_version() */ 41 | glVertex2f(0, 0); 42 | 43 | /* Hit an entrypoint that will call probably call gl_version() */ 44 | glMultiTexCoord4f(GL_TEXTURE0, 0.0, 0.0, 0.0, 0.0); 45 | 46 | /* Hit an entrypoint that will probably call 47 | * epoxy_conservative_has_extension(); 48 | */ 49 | if (has_argb2101010) { 50 | glTexCoordP4ui(GL_UNSIGNED_INT_2_10_10_10_REV, 0); 51 | } 52 | } 53 | glEnd(); 54 | 55 | /* No error should have been generated in the process. */ 56 | return glGetError() == 0; 57 | } 58 | 59 | 60 | 61 | #undef glBegin 62 | #undef glEnd 63 | extern void glBegin(GLenum primtype); 64 | extern void glEnd(void); 65 | 66 | static bool 67 | test_without_epoxy(void) 68 | { 69 | glBegin(GL_TRIANGLES); 70 | { 71 | /* Hit a base entrypoint that won't call gl_version() */ 72 | glVertex4f(0, 0, 0, 0); 73 | 74 | /* Hit an entrypoint that will call probably call gl_version() */ 75 | glMultiTexCoord3f(GL_TEXTURE0, 0.0, 0.0, 0.0); 76 | 77 | /* Hit an entrypoint that will probably call 78 | * epoxy_conservative_has_extension(); 79 | */ 80 | if (has_argb2101010) { 81 | glTexCoordP3ui(GL_UNSIGNED_INT_2_10_10_10_REV, 0); 82 | } 83 | } 84 | glEnd(); 85 | 86 | /* We can't make any assertions about error presence this time 87 | * around. This test is just trying to catch segfaults. 88 | */ 89 | return true; 90 | } 91 | 92 | int 93 | main(int argc, char **argv) 94 | { 95 | bool pass = true; 96 | 97 | dpy = get_display_or_skip(); 98 | make_glx_context_current_or_skip(dpy); 99 | 100 | has_argb2101010 = 101 | epoxy_has_gl_extension("GL_ARB_vertex_type_2_10_10_10_rev"); 102 | 103 | pass = pass && test_with_epoxy(); 104 | pass = pass && test_without_epoxy(); 105 | 106 | return pass != true; 107 | } 108 | -------------------------------------------------------------------------------- /src/dispatch_egl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "dispatch_common.h" 29 | 30 | int 31 | epoxy_conservative_egl_version(void) 32 | { 33 | EGLDisplay dpy = eglGetCurrentDisplay(); 34 | 35 | if (!dpy) 36 | return 14; 37 | 38 | return epoxy_egl_version(dpy); 39 | } 40 | 41 | /** 42 | * @brief Returns the version of OpenGL we are using 43 | * 44 | * The version is encoded as: 45 | * 46 | * ``` 47 | * 48 | * version = major * 10 + minor 49 | * 50 | * ``` 51 | * 52 | * So it can be easily used for version comparisons. 53 | * 54 | * @param The EGL display 55 | * 56 | * @return The encoded version of EGL we are using 57 | * 58 | * @see epoxy_gl_version() 59 | */ 60 | int 61 | epoxy_egl_version(EGLDisplay dpy) 62 | { 63 | int major, minor; 64 | const char *version_string; 65 | int ret; 66 | 67 | version_string = eglQueryString(dpy, EGL_VERSION); 68 | if (!version_string) 69 | return 0; 70 | 71 | ret = sscanf(version_string, "%d.%d", &major, &minor); 72 | assert(ret == 2); 73 | return major * 10 + minor; 74 | } 75 | 76 | bool 77 | epoxy_conservative_has_egl_extension(const char *ext) 78 | { 79 | return epoxy_has_egl_extension(eglGetCurrentDisplay(), ext); 80 | } 81 | 82 | /** 83 | * @brief Returns true if the given EGL extension is supported in the current context. 84 | * 85 | * @param dpy The EGL display 86 | * @param extension The name of the EGL extension 87 | * 88 | * @return `true` if the extension is available 89 | * 90 | * @see epoxy_has_gl_extension() 91 | * @see epoxy_has_glx_extension() 92 | */ 93 | bool 94 | epoxy_has_egl_extension(EGLDisplay dpy, const char *ext) 95 | { 96 | return epoxy_extension_in_string(eglQueryString(dpy, EGL_EXTENSIONS), ext) || epoxy_extension_in_string(eglQueryString(NULL, EGL_EXTENSIONS), ext); 97 | } 98 | 99 | /** 100 | * @brief Checks whether EGL is available. 101 | * 102 | * @return `true` if EGL is available 103 | * 104 | * @newin{1,4} 105 | */ 106 | bool 107 | epoxy_has_egl(void) 108 | { 109 | #if !PLATFORM_HAS_EGL 110 | return false; 111 | #else 112 | EGLDisplay* (* pf_eglGetCurrentDisplay) (void); 113 | 114 | pf_eglGetCurrentDisplay = epoxy_conservative_egl_dlsym("eglGetCurrentDisplay", false); 115 | if (pf_eglGetCurrentDisplay) 116 | return true; 117 | 118 | return false; 119 | #endif /* PLATFORM_HAS_EGL */ 120 | } 121 | -------------------------------------------------------------------------------- /test/glx_gles2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file glx_gles2.c 26 | * 27 | * Catches a bug where a GLES2 context using 28 | * GLX_EXT_create_context_es2_profile would try to find the symbols in 29 | * libGLESv2.so.2 instead of libGL.so.1. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include "epoxy/gl.h" 36 | #include "epoxy/glx.h" 37 | #include 38 | 39 | #include "glx_common.h" 40 | 41 | static Display *dpy; 42 | 43 | GLuint 44 | override_GLES2_glCreateShader(GLenum target); 45 | 46 | GLuint 47 | override_GLES2_glCreateShader(GLenum target) 48 | { 49 | return 0; 50 | } 51 | 52 | void 53 | override_GLES2_glGenQueries(GLsizei n, GLuint *ids); 54 | 55 | void 56 | override_GLES2_glGenQueries(GLsizei n, GLuint *ids) 57 | { 58 | int i; 59 | for (i = 0; i < n; i++) 60 | ids[i] = 0; 61 | } 62 | 63 | int 64 | main(int argc, char **argv) 65 | { 66 | bool pass = true; 67 | XVisualInfo *vis; 68 | Window win; 69 | GLXContext ctx; 70 | GLXFBConfig config; 71 | int context_attribs[] = { 72 | GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 73 | GLX_CONTEXT_MAJOR_VERSION_ARB, 2, 74 | GLX_CONTEXT_MINOR_VERSION_ARB, 0, 75 | 0 76 | }; 77 | GLuint shader; 78 | 79 | dpy = get_display_or_skip(); 80 | 81 | if (!epoxy_has_glx_extension(dpy, 0, "GLX_EXT_create_context_es2_profile")) 82 | errx(77, "Test requires GLX_EXT_create_context_es2_profile"); 83 | 84 | vis = get_glx_visual(dpy); 85 | config = get_fbconfig_for_visinfo(dpy, vis); 86 | win = get_glx_window(dpy, vis, false); 87 | 88 | ctx = glXCreateContextAttribsARB(dpy, config, NULL, true, 89 | context_attribs); 90 | 91 | glXMakeCurrent(dpy, win, ctx); 92 | 93 | if (epoxy_is_desktop_gl()) { 94 | errx(1, "GLES2 context creation made a desktop context\n"); 95 | } 96 | 97 | if (epoxy_gl_version() < 20) { 98 | errx(1, "GLES2 context creation made a version %f context\n", 99 | epoxy_gl_version() / 10.0f); 100 | } 101 | 102 | /* Test using an entrypoint that's in GLES2, but not the desktop GL ABI. */ 103 | shader = glCreateShader(GL_FRAGMENT_SHADER); 104 | if (shader == 0) 105 | errx(1, "glCreateShader() failed\n"); 106 | glDeleteShader(shader); 107 | 108 | if (epoxy_gl_version() >= 30) { 109 | GLuint q = 0; 110 | 111 | glGenQueries(1, &q); 112 | if (!q) 113 | errx(1, "glGenQueries() failed\n"); 114 | glDeleteQueries(1, &q); 115 | } 116 | 117 | return pass != true; 118 | } 119 | -------------------------------------------------------------------------------- /test/glx_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009, 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "glx_common.h" 28 | 29 | Display * 30 | get_display_or_skip(void) 31 | { 32 | Display *dpy = XOpenDisplay(NULL); 33 | 34 | if (!dpy) { 35 | fprintf(stderr, "couldn't open display\n"); 36 | exit(77); 37 | } 38 | 39 | return dpy; 40 | } 41 | 42 | XVisualInfo * 43 | get_glx_visual(Display *dpy) 44 | { 45 | XVisualInfo *visinfo; 46 | int attrib[] = { 47 | GLX_RGBA, 48 | GLX_RED_SIZE, 1, 49 | GLX_GREEN_SIZE, 1, 50 | GLX_BLUE_SIZE, 1, 51 | GLX_DOUBLEBUFFER, 52 | None 53 | }; 54 | int screen = DefaultScreen(dpy); 55 | 56 | visinfo = glXChooseVisual(dpy, screen, attrib); 57 | if (visinfo == NULL) { 58 | fprintf(stderr, 59 | "Couldn't get an RGBA, double-buffered visual\n"); 60 | exit(1); 61 | } 62 | 63 | return visinfo; 64 | } 65 | 66 | Window 67 | get_glx_window(Display *dpy, XVisualInfo *visinfo, bool map) 68 | { 69 | XSetWindowAttributes window_attr; 70 | unsigned long mask; 71 | int screen = DefaultScreen(dpy); 72 | Window root_win = RootWindow(dpy, screen); 73 | Window win; 74 | 75 | window_attr.background_pixel = 0; 76 | window_attr.border_pixel = 0; 77 | window_attr.colormap = XCreateColormap(dpy, root_win, 78 | visinfo->visual, AllocNone); 79 | window_attr.event_mask = StructureNotifyMask | ExposureMask | 80 | KeyPressMask; 81 | mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; 82 | win = XCreateWindow(dpy, root_win, 0, 0, 83 | 10, 10, /* width, height */ 84 | 0, visinfo->depth, InputOutput, 85 | visinfo->visual, mask, &window_attr); 86 | 87 | return win; 88 | } 89 | 90 | void 91 | make_glx_context_current_or_skip(Display *dpy) 92 | { 93 | GLXContext ctx; 94 | XVisualInfo *visinfo = get_glx_visual(dpy); 95 | Window win = get_glx_window(dpy, visinfo, false); 96 | 97 | ctx = glXCreateContext(dpy, visinfo, False, True); 98 | if (ctx == None) { 99 | fprintf(stderr, "glXCreateContext failed\n"); 100 | exit(1); 101 | } 102 | 103 | glXMakeCurrent(dpy, win, ctx); 104 | } 105 | 106 | GLXFBConfig 107 | get_fbconfig_for_visinfo(Display *dpy, XVisualInfo *visinfo) 108 | { 109 | int i, nconfigs; 110 | GLXFBConfig ret = None, *configs; 111 | 112 | configs = glXGetFBConfigs(dpy, visinfo->screen, &nconfigs); 113 | if (!configs) 114 | return None; 115 | 116 | for (i = 0; i < nconfigs; i++) { 117 | int v; 118 | 119 | if (glXGetFBConfigAttrib(dpy, configs[i], GLX_VISUAL_ID, &v)) 120 | continue; 121 | 122 | if (v == visinfo->visualid) { 123 | ret = configs[i]; 124 | break; 125 | } 126 | } 127 | 128 | XFree(configs); 129 | return ret; 130 | } 131 | -------------------------------------------------------------------------------- /test/glx_public_api.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include "epoxy/gl.h" 27 | #include "epoxy/glx.h" 28 | #include 29 | 30 | #include "glx_common.h" 31 | 32 | static Display *dpy; 33 | 34 | static bool 35 | test_gl_version(void) 36 | { 37 | int version = epoxy_gl_version(); 38 | if (version < 12) { 39 | fprintf(stderr, 40 | "Reported GL version %d, should be at least 12\n", 41 | version); 42 | return false; 43 | } 44 | 45 | return true; 46 | } 47 | 48 | static bool 49 | test_glx_version(void) 50 | { 51 | int version = epoxy_glx_version(dpy, 0); 52 | const char *version_string; 53 | int ret; 54 | int server_major, server_minor; 55 | int client_major, client_minor; 56 | int server, client, expected; 57 | 58 | if (version < 13) { 59 | fprintf(stderr, 60 | "Reported GLX version %d, should be at least 13 " 61 | "according to Linux GL ABI\n", 62 | version); 63 | return false; 64 | } 65 | 66 | version_string = glXQueryServerString(dpy, 0, GLX_VERSION); 67 | ret = sscanf(version_string, "%d.%d", &server_major, &server_minor); 68 | assert(ret == 2); 69 | server = server_major * 10 + server_minor; 70 | 71 | version_string = glXGetClientString(dpy, GLX_VERSION); 72 | ret = sscanf(version_string, "%d.%d", &client_major, &client_minor); 73 | assert(ret == 2); 74 | client = client_major * 10 + client_minor; 75 | 76 | if (client < server) 77 | expected = client; 78 | else 79 | expected = server; 80 | 81 | if (version != expected) { 82 | fprintf(stderr, 83 | "Reported GLX version %d, should be %d (%s)\n", 84 | version, expected, version_string); 85 | return false; 86 | } 87 | 88 | return true; 89 | } 90 | 91 | static bool 92 | test_glx_extension_supported(void) 93 | { 94 | if (!epoxy_has_glx_extension(dpy, 0, "GLX_ARB_get_proc_address")) { 95 | fprintf(stderr, 96 | "Incorrectly reported no support for GLX_ARB_get_proc_address " 97 | "(should always be present in Linux ABI)\n"); 98 | return false; 99 | } 100 | 101 | if (epoxy_has_glx_extension(dpy, 0, "GLX_EXT_ham_sandwich")) { 102 | fprintf(stderr, 103 | "Incorrectly reported support for GLX_EXT_ham_sandwich\n"); 104 | return false; 105 | } 106 | 107 | return true; 108 | } 109 | 110 | int 111 | main(int argc, char **argv) 112 | { 113 | bool pass = true; 114 | 115 | dpy = get_display_or_skip(); 116 | make_glx_context_current_or_skip(dpy); 117 | 118 | pass = test_gl_version() && pass; 119 | pass = test_glx_version() && pass; 120 | pass = test_glx_extension_supported() && pass; 121 | 122 | return pass != true; 123 | } 124 | -------------------------------------------------------------------------------- /test/egl_gl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2014 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file egl_gl.c 26 | * 27 | * Tests that epoxy works with EGL using desktop OpenGL. 28 | */ 29 | 30 | #define _GNU_SOURCE 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "epoxy/gl.h" 39 | #include "epoxy/egl.h" 40 | #include "epoxy/glx.h" 41 | 42 | #include "egl_common.h" 43 | #include "glx_common.h" 44 | #include "dlwrap.h" 45 | 46 | static bool 47 | make_egl_current_and_test(EGLDisplay *dpy, EGLContext ctx) 48 | { 49 | const char *string; 50 | GLuint shader; 51 | bool pass = true; 52 | 53 | eglMakeCurrent(dpy, NULL, NULL, ctx); 54 | 55 | if (!epoxy_is_desktop_gl()) { 56 | fprintf(stderr, "Claimed to be desktop\n"); 57 | pass = false; 58 | } 59 | 60 | if (epoxy_gl_version() < 20) { 61 | fprintf(stderr, "Claimed to be GL version %d\n", 62 | epoxy_gl_version()); 63 | pass = false; 64 | } 65 | 66 | string = (const char *)glGetString(GL_VERSION); 67 | printf("GL version: %s\n", string); 68 | 69 | shader = glCreateShader(GL_FRAGMENT_SHADER); 70 | pass = glIsShader(shader); 71 | 72 | return pass; 73 | } 74 | 75 | static void 76 | init_egl(EGLDisplay **out_dpy, EGLContext *out_ctx) 77 | { 78 | EGLDisplay *dpy = get_egl_display_or_skip(); 79 | static const EGLint config_attribs[] = { 80 | EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 81 | EGL_RED_SIZE, 1, 82 | EGL_GREEN_SIZE, 1, 83 | EGL_BLUE_SIZE, 1, 84 | EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, 85 | EGL_NONE 86 | }; 87 | static const EGLint context_attribs[] = { 88 | EGL_CONTEXT_CLIENT_VERSION, 2, 89 | EGL_NONE 90 | }; 91 | EGLContext ctx; 92 | EGLConfig cfg; 93 | EGLint count; 94 | 95 | if (!epoxy_has_egl_extension(dpy, "EGL_KHR_surfaceless_context")) 96 | errx(77, "Test requires EGL_KHR_surfaceless_context"); 97 | 98 | if (!eglBindAPI(EGL_OPENGL_API)) 99 | errx(77, "Couldn't initialize EGL with desktop GL\n"); 100 | 101 | if (!eglChooseConfig(dpy, config_attribs, &cfg, 1, &count)) 102 | errx(77, "Couldn't get an EGLConfig\n"); 103 | 104 | ctx = eglCreateContext(dpy, cfg, NULL, context_attribs); 105 | if (!ctx) 106 | errx(77, "Couldn't create a GL context\n"); 107 | 108 | *out_dpy = dpy; 109 | *out_ctx = ctx; 110 | } 111 | 112 | int 113 | main(int argc, char **argv) 114 | { 115 | bool pass = true; 116 | EGLDisplay *egl_dpy; 117 | EGLContext egl_ctx; 118 | 119 | /* Force epoxy to have loaded both EGL and GLX libs already -- we 120 | * can't assume anything about symbol resolution based on having 121 | * EGL or GLX loaded. 122 | */ 123 | (void)glXGetCurrentContext(); 124 | (void)eglGetCurrentContext(); 125 | 126 | init_egl(&egl_dpy, &egl_ctx); 127 | pass = make_egl_current_and_test(egl_dpy, egl_ctx) && pass; 128 | 129 | return pass != true; 130 | } 131 | -------------------------------------------------------------------------------- /test/wgl_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include "wgl_common.h" 27 | 28 | static int (*test_callback)(HDC hdc); 29 | 30 | static void 31 | setup_pixel_format(HDC hdc) 32 | { 33 | PIXELFORMATDESCRIPTOR pfd = { 34 | sizeof(PIXELFORMATDESCRIPTOR), 35 | 1, 36 | PFD_SUPPORT_OPENGL | 37 | PFD_DRAW_TO_WINDOW | 38 | PFD_DOUBLEBUFFER, 39 | PFD_TYPE_RGBA, 40 | 32, 41 | 0, 0, 0, 0, 0, 0, 42 | 0, 43 | 0, 44 | 0, 45 | 0, 0, 0, 0, 46 | 16, 47 | 0, 48 | 0, 49 | PFD_MAIN_PLANE, 50 | 0, 51 | 0, 0, 0, 52 | }; 53 | int pixel_format; 54 | 55 | pixel_format = ChoosePixelFormat(hdc, &pfd); 56 | if (!pixel_format) { 57 | fprintf(stderr, "ChoosePixelFormat failed.\n"); 58 | exit(1); 59 | } 60 | 61 | if (SetPixelFormat(hdc, pixel_format, &pfd) != TRUE) { 62 | fprintf(stderr, "SetPixelFormat() failed.\n"); 63 | exit(1); 64 | } 65 | } 66 | 67 | static LRESULT CALLBACK 68 | window_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) 69 | { 70 | HDC hdc = GetDC(hwnd); 71 | int ret; 72 | 73 | switch (message) { 74 | case WM_CREATE: 75 | setup_pixel_format(hdc); 76 | ret = test_callback(hdc); 77 | ReleaseDC(hwnd, hdc); 78 | exit(ret); 79 | return 0; 80 | default: 81 | return DefWindowProc(hwnd, message, wparam, lparam); 82 | } 83 | } 84 | 85 | void 86 | make_window_and_test(int (*callback)(HDC hdc)) 87 | { 88 | const char *class_name = "epoxy"; 89 | const char *window_name = "epoxy"; 90 | int width = 150; 91 | int height = 150; 92 | HWND hwnd; 93 | HINSTANCE hcurrentinst = NULL; 94 | WNDCLASS window_class; 95 | MSG msg; 96 | 97 | test_callback = callback; 98 | 99 | memset(&window_class, 0, sizeof(window_class)); 100 | window_class.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; 101 | window_class.lpfnWndProc = window_proc; 102 | window_class.cbClsExtra = 0; 103 | window_class.cbWndExtra = 0; 104 | window_class.hInstance = hcurrentinst; 105 | window_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); 106 | window_class.hCursor = LoadCursor(NULL, IDC_ARROW); 107 | window_class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 108 | window_class.lpszMenuName = NULL; 109 | window_class.lpszClassName = class_name; 110 | if (!RegisterClass(&window_class)) { 111 | fprintf(stderr, "Failed to register window class\n"); 112 | exit(1); 113 | } 114 | 115 | /* create window */ 116 | hwnd = CreateWindow(class_name, window_name, 117 | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 118 | 0, 0, width, height, 119 | NULL, NULL, hcurrentinst, NULL); 120 | 121 | ShowWindow(hwnd, SW_SHOWDEFAULT); 122 | UpdateWindow(hwnd); 123 | 124 | while (GetMessage(&msg, NULL, 0, 0)) { 125 | TranslateMessage(&msg); 126 | DispatchMessage(&msg); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/anholt/libepoxy.svg?branch=master)](https://travis-ci.org/anholt/libepoxy) 2 | [![Build status](https://ci.appveyor.com/api/projects/status/xv6y5jurt5v5ngjx/branch/master?svg=true)](https://ci.appveyor.com/project/ebassi/libepoxy/branch/master) 3 | 4 | Epoxy is a library for handling OpenGL function pointer management for 5 | you. 6 | 7 | It hides the complexity of `dlopen()`, `dlsym()`, `glXGetProcAddress()`, 8 | `eglGetProcAddress()`, etc. from the app developer, with very little 9 | knowledge needed on their part. They get to read GL specs and write 10 | code using undecorated function names like `glCompileShader()`. 11 | 12 | Don't forget to check for your extensions or versions being present 13 | before you use them, just like before! We'll tell you what you forgot 14 | to check for instead of just segfaulting, though. 15 | 16 | Features 17 | -------- 18 | 19 | * Automatically initializes as new GL functions are used. 20 | * GL 4.5 core and compatibility context support. 21 | * GLES 1/2/3 context support. 22 | * Knows about function aliases so (e.g.) `glBufferData()` can be 23 | used with `GL_ARB_vertex_buffer_object` implementations, along 24 | with GL 1.5+ implementations. 25 | * EGL, GLX, and WGL support. 26 | * Can be mixed with non-epoxy GL usage. 27 | 28 | Building 29 | -------- 30 | 31 | ```sh 32 | mkdir _build && cd _build 33 | meson 34 | ninja 35 | sudo ninja install 36 | ``` 37 | 38 | Dependencies for Debian: 39 | 40 | * meson 41 | * libegl1-mesa-dev 42 | 43 | Dependencies for macOS (using MacPorts): 44 | 45 | * pkgconfig 46 | * meson 47 | 48 | The test suite has additional dependencies depending on the platform. 49 | (X11, EGL, a running X Server). 50 | 51 | Switching your code to using epoxy 52 | ---------------------------------- 53 | 54 | It should be as easy as replacing: 55 | 56 | ```cpp 57 | #include 58 | #include 59 | #include 60 | ``` 61 | 62 | with: 63 | 64 | ```cpp 65 | #include 66 | #include 67 | ``` 68 | 69 | As long as epoxy's headers appear first, you should be ready to go. 70 | Additionally, some new helpers become available, so you don't have to 71 | write them: 72 | 73 | `int epoxy_gl_version()` returns the GL version: 74 | 75 | * 12 for GL 1.2 76 | * 20 for GL 2.0 77 | * 44 for GL 4.4 78 | 79 | `bool epoxy_has_gl_extension()` returns whether a GL extension is 80 | available (`GL_ARB_texture_buffer_object`, for example). 81 | 82 | Note that this is not terribly fast, so keep it out of your hot paths, 83 | ok? 84 | 85 | Why not use libGLEW? 86 | -------------------- 87 | 88 | GLEW has several issues: 89 | 90 | * Doesn't know about aliases of functions (There are 5 providers of 91 | `glPointParameterfv()`, for example, and you don't want to have to 92 | choose which one to call when they're all the same). 93 | * Doesn't support OpenGL ES. 94 | * Has a hard-to-maintain parser of extension specification text 95 | instead of using the old .spec file or the new .xml. 96 | * Has significant startup time overhead when `glewInit()` 97 | autodetects the world. 98 | * User-visible multithreading support choice for win32. 99 | 100 | The motivation for this project came out of previous use of libGLEW in 101 | [piglit](http://piglit.freedesktop.org/). Other GL dispatch code 102 | generation projects had similar failures. Ideally, piglit wants to be 103 | able to build a single binary for a test that can run on whatever 104 | context or window system it chooses, not based on link time choices. 105 | 106 | We had to solve some of GLEW's problems for piglit and solving them 107 | meant replacing every single piece of GLEW, so we built 108 | piglit-dispatch from scratch. And since we wanted to reuse it in 109 | other GL-related projects, this is the result. 110 | 111 | Known issues when running on Windows 112 | ------------------------------------ 113 | 114 | The automatic per-context symbol resolution for win32 requires that 115 | epoxy knows when `wglMakeCurrent()` is called, because `wglGetProcAddress()` 116 | returns values depend on the context's device and pixel format. If 117 | `wglMakeCurrent()` is called from outside of epoxy (in a way that might 118 | change the device or pixel format), then epoxy needs to be notified of 119 | the change using the `epoxy_handle_external_wglMakeCurrent()` function. 120 | 121 | The win32 `wglMakeCurrent()` variants are slower than they should be, 122 | because they should be caching the resolved dispatch tables instead of 123 | resetting an entire thread-local dispatch table every time. 124 | -------------------------------------------------------------------------------- /test/egl_without_glx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2014 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file egl_without_glx.c 26 | * 27 | * Tries to test operation of the library on a GL stack with EGL and 28 | * GLES but no GLX or desktop GL (such as Arm's Mali GLES3 drivers). 29 | * This test is varied by the GLES_VERSION defined at compile time to 30 | * test either a GLES1-only or a GLES2-only system. 31 | */ 32 | 33 | #define _GNU_SOURCE 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "epoxy/gl.h" 42 | #include "epoxy/egl.h" 43 | 44 | #include "egl_common.h" 45 | 46 | /** 47 | * Wraps the system dlopen(), which libepoxy will end up calling when 48 | * it tries to dlopen() the API libraries, and errors out the 49 | * libraries we're trying to simulate not being installed on the 50 | * system. 51 | */ 52 | void * 53 | dlopen(const char *filename, int flag) 54 | { 55 | void * (*dlopen_unwrapped)(const char *filename, int flag); 56 | 57 | if (!strcmp(filename, "libGL.so.1")) 58 | return NULL; 59 | #if GLES_VERSION == 2 60 | if (!strcmp(filename, "libGLESv1_CM.so.1")) 61 | return NULL; 62 | #else 63 | if (!strcmp(filename, "libGLESv2.so.2")) 64 | return NULL; 65 | #endif 66 | 67 | dlopen_unwrapped = dlsym(RTLD_NEXT, "dlopen"); 68 | assert(dlopen_unwrapped); 69 | 70 | return dlopen_unwrapped(filename, flag); 71 | } 72 | 73 | 74 | static EGLenum last_api; 75 | static EGLenum extra_error = EGL_SUCCESS; 76 | 77 | /** 78 | * Override of the real libEGL's eglBindAPI to simulate the target 79 | * system's eglBindAPI. 80 | */ 81 | static EGLBoolean 82 | override_eglBindAPI(EGLenum api) 83 | { 84 | void *egl = dlopen("libEGL.so.1", RTLD_LAZY | RTLD_LOCAL); 85 | EGLBoolean (*real_eglBindAPI)(EGLenum api) = dlsym(egl, "eglBindAPI"); 86 | 87 | last_api = api; 88 | 89 | if (api == EGL_OPENGL_API) { 90 | extra_error = EGL_BAD_PARAMETER; 91 | return EGL_FALSE; 92 | } 93 | 94 | assert(real_eglBindAPI); 95 | return real_eglBindAPI(api); 96 | } 97 | 98 | /** 99 | * Override of the real libEGL's eglGetError() to feed back the error 100 | * that might have been generated by override_eglBindAPI(). 101 | */ 102 | static EGLint 103 | override_eglGetError(void) 104 | { 105 | void *egl = dlopen("libEGL.so.1", RTLD_LAZY | RTLD_LOCAL); 106 | EGLint (*real_eglGetError)(void) = dlsym(egl, "eglGetError"); 107 | 108 | if (extra_error != EGL_SUCCESS) { 109 | EGLenum error = extra_error; 110 | extra_error = EGL_SUCCESS; 111 | return error; 112 | } 113 | 114 | assert(real_eglGetError); 115 | return real_eglGetError(); 116 | } 117 | 118 | int 119 | main(int argc, char **argv) 120 | { 121 | bool pass = true; 122 | EGLDisplay *dpy = get_egl_display_or_skip(); 123 | EGLint context_attribs[] = { 124 | EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION, 125 | EGL_NONE 126 | }; 127 | EGLConfig cfg; 128 | EGLint config_attribs[] = { 129 | EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 130 | EGL_RED_SIZE, 1, 131 | EGL_GREEN_SIZE, 1, 132 | EGL_BLUE_SIZE, 1, 133 | EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, 134 | EGL_NONE 135 | }; 136 | EGLint count; 137 | EGLContext ctx; 138 | const unsigned char *string; 139 | 140 | epoxy_eglBindAPI = override_eglBindAPI; 141 | epoxy_eglGetError = override_eglGetError; 142 | 143 | if (!epoxy_has_egl_extension(dpy, "EGL_KHR_surfaceless_context")) 144 | errx(77, "Test requires EGL_KHR_surfaceless_context"); 145 | 146 | eglBindAPI(EGL_OPENGL_ES_API); 147 | 148 | if (!eglChooseConfig(dpy, config_attribs, &cfg, 1, &count)) 149 | errx(77, "Couldn't get an EGLConfig\n"); 150 | 151 | ctx = eglCreateContext(dpy, cfg, NULL, context_attribs); 152 | if (!ctx) 153 | errx(77, "Couldn't create a GLES%d context\n", GLES_VERSION); 154 | 155 | eglMakeCurrent(dpy, NULL, NULL, ctx); 156 | 157 | string = glGetString(GL_VERSION); 158 | printf("GL_VERSION: %s\n", string); 159 | 160 | assert(eglGetError() == EGL_SUCCESS); 161 | 162 | return pass != true; 163 | } 164 | -------------------------------------------------------------------------------- /src/dispatch_glx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "dispatch_common.h" 29 | 30 | /** 31 | * If we can determine the GLX version from the current context, then 32 | * return that, otherwise return a version that will just send us on 33 | * to dlsym() or get_proc_address(). 34 | */ 35 | int 36 | epoxy_conservative_glx_version(void) 37 | { 38 | Display *dpy = glXGetCurrentDisplay(); 39 | GLXContext ctx = glXGetCurrentContext(); 40 | int screen; 41 | 42 | if (!dpy || !ctx) 43 | return 14; 44 | 45 | glXQueryContext(dpy, ctx, GLX_SCREEN, &screen); 46 | 47 | return epoxy_glx_version(dpy, screen); 48 | } 49 | 50 | 51 | /** 52 | * @brief Returns the version of GLX we are using 53 | * 54 | * The version is encoded as: 55 | * 56 | * ``` 57 | * 58 | * version = major * 10 + minor 59 | * 60 | * ``` 61 | * 62 | * So it can be easily used for version comparisons. 63 | * 64 | * @param dpy The X11 display 65 | * @param screen The X11 screen 66 | * 67 | * @return The encoded version of GLX we are using 68 | * 69 | * @see epoxy_gl_version() 70 | */ 71 | int 72 | epoxy_glx_version(Display *dpy, int screen) 73 | { 74 | int server_major, server_minor; 75 | int client_major, client_minor; 76 | int server, client; 77 | const char *version_string; 78 | int ret; 79 | 80 | version_string = glXQueryServerString(dpy, screen, GLX_VERSION); 81 | if (!version_string) 82 | return 0; 83 | 84 | ret = sscanf(version_string, "%d.%d", &server_major, &server_minor); 85 | assert(ret == 2); 86 | server = server_major * 10 + server_minor; 87 | 88 | version_string = glXGetClientString(dpy, GLX_VERSION); 89 | if (!version_string) 90 | return 0; 91 | 92 | ret = sscanf(version_string, "%d.%d", &client_major, &client_minor); 93 | assert(ret == 2); 94 | client = client_major * 10 + client_minor; 95 | 96 | if (client < server) 97 | return client; 98 | else 99 | return server; 100 | } 101 | 102 | /** 103 | * If we can determine the GLX extension support from the current 104 | * context, then return that, otherwise give the answer that will just 105 | * send us on to get_proc_address(). 106 | */ 107 | bool 108 | epoxy_conservative_has_glx_extension(const char *ext) 109 | { 110 | Display *dpy = glXGetCurrentDisplay(); 111 | GLXContext ctx = glXGetCurrentContext(); 112 | int screen; 113 | 114 | if (!dpy || !ctx) 115 | return true; 116 | 117 | glXQueryContext(dpy, ctx, GLX_SCREEN, &screen); 118 | 119 | return epoxy_has_glx_extension(dpy, screen, ext); 120 | } 121 | 122 | /** 123 | * @brief Returns true if the given GLX extension is supported in the current context. 124 | * 125 | * @param dpy The X11 display 126 | * @param screen The X11 screen 127 | * @param extension The name of the GLX extension 128 | * 129 | * @return `true` if the extension is available 130 | * 131 | * @see epoxy_has_gl_extension() 132 | * @see epoxy_has_egl_extension() 133 | */ 134 | bool 135 | epoxy_has_glx_extension(Display *dpy, int screen, const char *ext) 136 | { 137 | /* No, you can't just use glXGetClientString or 138 | * glXGetServerString() here. Those each tell you about one half 139 | * of what's needed for an extension to be supported, and 140 | * glXQueryExtensionsString() is what gives you the intersection 141 | * of the two. 142 | */ 143 | return epoxy_extension_in_string(glXQueryExtensionsString(dpy, screen), ext); 144 | } 145 | 146 | /** 147 | * @brief Checks whether GLX is available. 148 | * 149 | * @param dpy The X11 display 150 | * 151 | * @return `true` if GLX is available 152 | * 153 | * @newin{1,4} 154 | */ 155 | bool 156 | epoxy_has_glx(Display *dpy) 157 | { 158 | #if !PLATFORM_HAS_GLX 159 | return false; 160 | #else 161 | Bool (* pf_glXQueryExtension) (Display *, int *, int *); 162 | int error_base, event_base; 163 | 164 | pf_glXQueryExtension = epoxy_conservative_glx_dlsym("glXQueryExtension", false); 165 | if (pf_glXQueryExtension && pf_glXQueryExtension(dpy, &error_base, &event_base)) 166 | return true; 167 | 168 | return false; 169 | #endif /* !PLATFORM_HAS_GLX */ 170 | } 171 | -------------------------------------------------------------------------------- /test/wgl_per_context_funcptrs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file wgl_per_context_funcptrs.c 26 | * 27 | * Tests that epoxy works correctly when wglGetProcAddress() returns 28 | * different function pointers for different contexts. 29 | * 30 | * wgl allows that to be the case when the device or pixel format are 31 | * different. We don't know if the underlying implementation actually 32 | * *will* return different function pointers, so force the issue by 33 | * overriding wglGetProcAddress() to return our function pointers with 34 | * magic behavior. This way we can test epoxy's implementation 35 | * regardless. 36 | */ 37 | 38 | #include 39 | #include 40 | 41 | #include "wgl_common.h" 42 | #include 43 | 44 | #define CREATESHADER_CTX1_VAL 1001 45 | #define CREATESHADER_CTX2_VAL 1002 46 | 47 | static HGLRC ctx1, ctx2, current_context; 48 | static bool pass = true; 49 | 50 | #define OVERRIDE_API(type) __declspec(dllexport) type __stdcall 51 | 52 | OVERRIDE_API (GLuint) override_glCreateShader_ctx1(GLenum target); 53 | OVERRIDE_API (GLuint) override_glCreateShader_ctx2(GLenum target); 54 | OVERRIDE_API (PROC) override_wglGetProcAddress(LPCSTR name); 55 | 56 | OVERRIDE_API (GLuint) 57 | override_glCreateShader_ctx1(GLenum target) 58 | { 59 | if (current_context != ctx1) { 60 | fprintf(stderr, "ctx1 called while other context current\n"); 61 | pass = false; 62 | } 63 | return CREATESHADER_CTX1_VAL; 64 | } 65 | 66 | OVERRIDE_API (GLuint) 67 | override_glCreateShader_ctx2(GLenum target) 68 | { 69 | if (current_context != ctx2) { 70 | fprintf(stderr, "ctx2 called while other context current\n"); 71 | pass = false; 72 | } 73 | return CREATESHADER_CTX2_VAL; 74 | } 75 | 76 | OVERRIDE_API (PROC) 77 | override_wglGetProcAddress(LPCSTR name) 78 | { 79 | assert(strcmp(name, "glCreateShader") == 0); 80 | 81 | if (current_context == ctx1) { 82 | return (PROC)override_glCreateShader_ctx1; 83 | } else { 84 | assert(current_context == ctx2); 85 | return (PROC)override_glCreateShader_ctx2; 86 | } 87 | } 88 | 89 | static void 90 | test_createshader(HDC hdc, HGLRC ctx) 91 | { 92 | GLuint shader, expected; 93 | int ctxnum; 94 | 95 | wglMakeCurrent(hdc, ctx); 96 | current_context = ctx; 97 | 98 | /* Install our GPA override so we can force per-context function 99 | * pointers. 100 | */ 101 | wglGetProcAddress = override_wglGetProcAddress; 102 | 103 | if (ctx == ctx1) { 104 | expected = CREATESHADER_CTX1_VAL; 105 | ctxnum = 1; 106 | } else { 107 | assert(ctx == ctx2); 108 | expected = CREATESHADER_CTX2_VAL; 109 | ctxnum = 2; 110 | } 111 | 112 | shader = glCreateShader(GL_FRAGMENT_SHADER); 113 | printf("ctx%d: Returned %d\n", ctxnum, shader); 114 | if (shader != expected) { 115 | fprintf(stderr, " expected %d\n", expected); 116 | pass = false; 117 | } 118 | } 119 | 120 | static int 121 | test_function(HDC hdc) 122 | { 123 | ctx1 = wglCreateContext(hdc); 124 | ctx2 = wglCreateContext(hdc); 125 | if (!ctx1 || !ctx2) { 126 | fprintf(stderr, "Failed to create wgl contexts\n"); 127 | return 1; 128 | } 129 | 130 | if (!wglMakeCurrent(hdc, ctx1)) { 131 | fprintf(stderr, "Failed to make context current\n"); 132 | return 1; 133 | } 134 | 135 | if (epoxy_gl_version() < 20) { 136 | /* We could possibly do a 1.3 entrypoint or something instead. */ 137 | fprintf(stderr, "Test relies on overriding a GL 2.0 entrypoint\n"); 138 | return 77; 139 | } 140 | 141 | /* Force resolving epoxy_wglGetProcAddress. */ 142 | wglGetProcAddress("glCreateShader"); 143 | 144 | test_createshader(hdc, ctx1); 145 | test_createshader(hdc, ctx1); 146 | test_createshader(hdc, ctx2); 147 | test_createshader(hdc, ctx2); 148 | test_createshader(hdc, ctx1); 149 | test_createshader(hdc, ctx2); 150 | 151 | wglMakeCurrent(NULL, NULL); 152 | wglDeleteContext(ctx1); 153 | wglDeleteContext(ctx2); 154 | 155 | return !pass; 156 | } 157 | 158 | int 159 | main(int argc, char **argv) 160 | { 161 | make_window_and_test(test_function); 162 | 163 | /* UNREACHED */ 164 | return 1; 165 | } 166 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright © 2013 Intel Corporation 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a 4 | # copy of this software and associated documentation files (the "Software"), 5 | # to deal in the Software without restriction, including without limitation 6 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | # and/or sell copies of the Software, and to permit persons to whom the 8 | # Software is furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice (including the next 11 | # paragraph) shall be included in all copies or substantial portions of the 12 | # Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | # IN THE SOFTWARE. 21 | 22 | AM_CPPFLAGS = \ 23 | -I$(top_srcdir)/include \ 24 | -I$(top_builddir)/include \ 25 | $() 26 | 27 | AM_CFLAGS = \ 28 | $(CWARNFLAGS) \ 29 | $(VISIBILITY_CFLAGS) \ 30 | $(X11_CFLAGS) \ 31 | $(EGL_CFLAGS) \ 32 | $() 33 | 34 | epoxyincludedir = $(includedir)/epoxy 35 | lib_LTLIBRARIES = libepoxy.la 36 | 37 | epoxyinclude_DATA = \ 38 | $(GENERATED_GL_INCLUDES) \ 39 | $(INSTALL_GLX_INCLUDES) \ 40 | $(INSTALL_EGL_INCLUDES) \ 41 | $(INSTALL_WGL_INCLUDES) \ 42 | $() 43 | 44 | if BUILD_EGL 45 | INSTALL_EGL_INCLUDES = $(GENERATED_EGL_INCLUDES) 46 | endif 47 | 48 | if BUILD_GLX 49 | INSTALL_GLX_INCLUDES = $(GENERATED_GLX_INCLUDES) 50 | endif 51 | 52 | if BUILD_WGL 53 | INSTALL_WGL_INCLUDES = $(GENERATED_WGL_INCLUDES) 54 | endif 55 | 56 | GENERATED_GL_INCLUDES = \ 57 | $(builddir)/../include/epoxy/gl_generated.h \ 58 | $() 59 | 60 | GENERATED_GLX_INCLUDES = \ 61 | $(builddir)/../include/epoxy/glx_generated.h \ 62 | $() 63 | 64 | GENERATED_EGL_INCLUDES = \ 65 | $(builddir)/../include/epoxy/egl_generated.h \ 66 | $() 67 | 68 | GENERATED_WGL_INCLUDES = \ 69 | $(builddir)/../include/epoxy/wgl_generated.h \ 70 | $() 71 | 72 | GENERATED_GL_SOURCE = gl_generated_dispatch.c 73 | 74 | GENERATED_GL = \ 75 | $(GENERATED_GL_SOURCE) \ 76 | $(GENERATED_GL_INCLUDES) \ 77 | $() 78 | 79 | GENERATED_GLX_SOURCE = glx_generated_dispatch.c 80 | 81 | GENERATED_GLX = \ 82 | $(GENERATED_GLX_SOURCE) \ 83 | $(GENERATED_GLX_INCLUDES) \ 84 | $() 85 | 86 | GENERATED_EGL_SOURCE = egl_generated_dispatch.c 87 | 88 | GENERATED_EGL = \ 89 | $(GENERATED_EGL_SOURCE) \ 90 | $(GENERATED_EGL_INCLUDES) \ 91 | $() 92 | 93 | GENERATED_WGL_SOURCE = wgl_generated_dispatch.c 94 | 95 | GENERATED_WGL = \ 96 | $(GENERATED_WGL_SOURCE) \ 97 | $(GENERATED_WGL_INCLUDES) \ 98 | $() 99 | 100 | BUILT_SOURCES = \ 101 | $(GENERATED_GL) \ 102 | $(GENERATED_GLX) \ 103 | $(GENERATED_EGL) \ 104 | $(GENERATED_WGL) \ 105 | $() 106 | CLEANFILES = $(BUILT_SOURCES) 107 | 108 | libepoxy_la_SOURCES = \ 109 | dispatch_common.c \ 110 | dispatch_common.h \ 111 | $(GENERATED_GL) \ 112 | $(BUILD_EGL_CODE) \ 113 | $(BUILD_GLX_CODE) \ 114 | $(BUILD_WGL_CODE) \ 115 | $() 116 | 117 | libepoxy_la_LDFLAGS = \ 118 | -no-undefined \ 119 | -Bsymbolic \ 120 | $() 121 | 122 | libepoxy_la_LIBADD = \ 123 | $(EPOXY_LINK_LIBS) \ 124 | $(DLOPEN_LIBS) \ 125 | $() 126 | 127 | if BUILD_EGL 128 | BUILD_EGL_CODE = \ 129 | $(GENERATED_EGL) \ 130 | dispatch_egl.c \ 131 | $() 132 | endif 133 | 134 | if BUILD_GLX 135 | BUILD_GLX_CODE = \ 136 | $(GENERATED_GLX) \ 137 | dispatch_glx.c \ 138 | $() 139 | endif 140 | 141 | if BUILD_WGL 142 | BUILD_WGL_CODE = \ 143 | $(GENERATED_WGL) \ 144 | dispatch_wgl.c \ 145 | $() 146 | endif 147 | 148 | # These are generated alongside the .c file. 149 | $(GENERATED_GL_INCLUDES): $(GENERATED_GL_SOURCE) 150 | $(GENERATED_GLX_INCLUDES): $(GENERATED_GLX_SOURCE) 151 | $(GENERATED_EGL_INCLUDES): $(GENERATED_EGL_SOURCE) 152 | $(GENERATED_WGL_INCLUDES): $(GENERATED_WGL_SOURCE) 153 | 154 | $(GENERATED_GL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/gl.xml 155 | @$(MKDIR_P) $(top_builddir)/include/epoxy 156 | $(AM_V_GEN)$(PYTHON) $(srcdir)/gen_dispatch.py \ 157 | --srcdir $(top_builddir)/src \ 158 | --includedir $(top_builddir)/include/epoxy \ 159 | $(top_srcdir)/registry/gl.xml 160 | 161 | $(GENERATED_GLX_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/glx.xml 162 | @$(MKDIR_P) $(top_builddir)/include/epoxy 163 | $(AM_V_GEN)$(PYTHON) $(srcdir)/gen_dispatch.py \ 164 | --srcdir $(top_builddir)/src \ 165 | --includedir $(top_builddir)/include/epoxy \ 166 | $(top_srcdir)/registry/glx.xml 167 | 168 | $(GENERATED_EGL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/egl.xml 169 | @$(MKDIR_P) $(top_builddir)/include/epoxy 170 | $(AM_V_GEN)$(PYTHON) $(srcdir)/gen_dispatch.py \ 171 | --srcdir $(top_builddir)/src \ 172 | --includedir $(top_builddir)/include/epoxy \ 173 | $(top_srcdir)/registry/egl.xml 174 | 175 | $(GENERATED_WGL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/wgl.xml 176 | @$(MKDIR_P) $(top_builddir)/include/epoxy 177 | $(AM_V_GEN)$(PYTHON) $(srcdir)/gen_dispatch.py \ 178 | --srcdir $(top_builddir)/src \ 179 | --includedir $(top_builddir)/include/epoxy \ 180 | $(top_srcdir)/registry/wgl.xml 181 | 182 | EXTRA_DIST = \ 183 | gen_dispatch.py \ 184 | $() 185 | -------------------------------------------------------------------------------- /test/glx_public_api_core.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "epoxy/gl.h" 29 | #include "epoxy/glx.h" 30 | #include 31 | 32 | #include "glx_common.h" 33 | 34 | static Display *dpy; 35 | 36 | static bool 37 | test_has_extensions(void) 38 | { 39 | int num_extensions; 40 | 41 | glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions); 42 | 43 | for (int i = 0; i < num_extensions; i++) { 44 | char *ext = (char *)glGetStringi(GL_EXTENSIONS, i); 45 | 46 | if (!epoxy_has_gl_extension(ext)) { 47 | fprintf(stderr, "GL implementation reported support for %s, " 48 | "but epoxy didn't\n", ext); 49 | return false; 50 | } 51 | } 52 | 53 | if (epoxy_has_gl_extension("GL_ARB_ham_sandwich")) { 54 | fprintf(stderr, "epoxy implementation reported support for " 55 | "GL_ARB_ham_sandwich, but it shouldn't\n"); 56 | return false; 57 | } 58 | 59 | return true; 60 | } 61 | 62 | static bool 63 | test_gl_version(void) 64 | { 65 | int gl_version, epoxy_version; 66 | int major, minor; 67 | 68 | glGetIntegerv(GL_MAJOR_VERSION, &major); 69 | glGetIntegerv(GL_MINOR_VERSION, &minor); 70 | gl_version = major * 10 + minor; 71 | 72 | if (gl_version < 32) { 73 | fprintf(stderr, 74 | "Implementation reported GL version %d, should be at least 32\n", 75 | gl_version); 76 | return false; 77 | } 78 | 79 | epoxy_version = epoxy_gl_version(); 80 | if (epoxy_version != gl_version) { 81 | fprintf(stderr, 82 | "Epoxy reported GL version %d, should be %d\n", 83 | epoxy_version, gl_version); 84 | return false; 85 | } 86 | 87 | return true; 88 | } 89 | 90 | static bool 91 | test_glx_version(void) 92 | { 93 | int version = epoxy_glx_version(dpy, 0); 94 | const char *version_string; 95 | int ret; 96 | int server_major, server_minor; 97 | int client_major, client_minor; 98 | int server, client, expected; 99 | 100 | if (version < 13) { 101 | fprintf(stderr, 102 | "Reported GLX version %d, should be at least 13 " 103 | "according to Linux GL ABI\n", 104 | version); 105 | return false; 106 | } 107 | 108 | version_string = glXQueryServerString(dpy, 0, GLX_VERSION); 109 | ret = sscanf(version_string, "%d.%d", &server_major, &server_minor); 110 | assert(ret == 2); 111 | server = server_major * 10 + server_minor; 112 | 113 | version_string = glXGetClientString(dpy, GLX_VERSION); 114 | ret = sscanf(version_string, "%d.%d", &client_major, &client_minor); 115 | assert(ret == 2); 116 | client = client_major * 10 + client_minor; 117 | 118 | if (client < server) 119 | expected = client; 120 | else 121 | expected = server; 122 | 123 | if (version != expected) { 124 | fprintf(stderr, 125 | "Reported GLX version %d, should be %d (%s)\n", 126 | version, expected, version_string); 127 | return false; 128 | } 129 | 130 | return true; 131 | } 132 | 133 | int 134 | main(int argc, char **argv) 135 | { 136 | bool pass = true; 137 | XVisualInfo *visinfo; 138 | Window win; 139 | GLXFBConfig config; 140 | static const int attribs[] = { 141 | GLX_CONTEXT_PROFILE_MASK_ARB, 142 | GLX_CONTEXT_CORE_PROFILE_BIT_ARB, 143 | GLX_CONTEXT_MAJOR_VERSION_ARB, 144 | 3, 145 | GLX_CONTEXT_MINOR_VERSION_ARB, 146 | 2, 147 | None 148 | }; 149 | GLXContext ctx; 150 | 151 | dpy = get_display_or_skip(); 152 | 153 | if (!epoxy_has_glx_extension(dpy, 0, "GLX_ARB_create_context_profile")) 154 | errx(77, "Test requires GLX_ARB_create_context_profile"); 155 | 156 | visinfo = get_glx_visual(dpy); 157 | win = get_glx_window(dpy, visinfo, false); 158 | config = get_fbconfig_for_visinfo(dpy, visinfo); 159 | ctx = glXCreateContextAttribsARB(dpy, config, NULL, True, attribs); 160 | if (ctx == None) 161 | errx(77, "glXCreateContext failed"); 162 | 163 | glXMakeCurrent(dpy, win, ctx); 164 | 165 | pass = test_gl_version() && pass; 166 | pass = test_glx_version() && pass; 167 | pass = test_has_extensions() && pass; 168 | 169 | return pass != true; 170 | } 171 | -------------------------------------------------------------------------------- /src/dispatch_wgl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "dispatch_common.h" 29 | 30 | static bool first_context_current = false; 31 | static bool already_switched_to_dispatch_table = false; 32 | 33 | /** 34 | * If we can determine the WGL extension support from the current 35 | * context, then return that, otherwise give the answer that will just 36 | * send us on to get_proc_address(). 37 | */ 38 | bool 39 | epoxy_conservative_has_wgl_extension(const char *ext) 40 | { 41 | HDC hdc = wglGetCurrentDC(); 42 | 43 | if (!hdc) 44 | return true; 45 | 46 | return epoxy_has_wgl_extension(hdc, ext); 47 | } 48 | 49 | bool 50 | epoxy_has_wgl_extension(HDC hdc, const char *ext) 51 | { 52 | PFNWGLGETEXTENSIONSSTRINGARBPROC getext; 53 | 54 | getext = (void *)wglGetProcAddress("wglGetExtensionsStringARB"); 55 | if (!getext) { 56 | fprintf(stderr, 57 | "Implementation unexpectedly missing " 58 | "WGL_ARB_extensions_string. Probably a libepoxy bug.\n"); 59 | return false; 60 | } 61 | 62 | return epoxy_extension_in_string(getext(hdc), ext); 63 | } 64 | 65 | /** 66 | * Does the work necessary to update the win32 per-thread dispatch 67 | * tables when wglMakeCurrent() is called. 68 | * 69 | * Right now, we use global function pointers until the second 70 | * MakeCurrent occurs, at which point we switch to dispatch tables. 71 | * This could be improved in the future to track a resolved dispatch 72 | * table per context and reuse it when the context is made current 73 | * again. 74 | */ 75 | void 76 | epoxy_handle_external_wglMakeCurrent(void) 77 | { 78 | if (!first_context_current) { 79 | first_context_current = true; 80 | } else { 81 | if (!already_switched_to_dispatch_table) { 82 | already_switched_to_dispatch_table = true; 83 | gl_switch_to_dispatch_table(); 84 | wgl_switch_to_dispatch_table(); 85 | } 86 | 87 | gl_init_dispatch_table(); 88 | wgl_init_dispatch_table(); 89 | } 90 | } 91 | 92 | /** 93 | * This global symbol is apparently looked up by Windows when loading 94 | * a DLL, but it doesn't declare the prototype. 95 | */ 96 | BOOL WINAPI 97 | DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved); 98 | 99 | BOOL WINAPI 100 | DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved) 101 | { 102 | void *data; 103 | 104 | switch (reason) { 105 | case DLL_PROCESS_ATTACH: 106 | gl_tls_index = TlsAlloc(); 107 | if (gl_tls_index == TLS_OUT_OF_INDEXES) 108 | return FALSE; 109 | wgl_tls_index = TlsAlloc(); 110 | if (wgl_tls_index == TLS_OUT_OF_INDEXES) 111 | return FALSE; 112 | 113 | first_context_current = false; 114 | 115 | /* FALLTHROUGH */ 116 | 117 | case DLL_THREAD_ATTACH: 118 | data = LocalAlloc(LPTR, gl_tls_size); 119 | TlsSetValue(gl_tls_index, data); 120 | 121 | data = LocalAlloc(LPTR, wgl_tls_size); 122 | TlsSetValue(wgl_tls_index, data); 123 | 124 | break; 125 | 126 | case DLL_THREAD_DETACH: 127 | case DLL_PROCESS_DETACH: 128 | data = TlsGetValue(gl_tls_index); 129 | LocalFree(data); 130 | 131 | data = TlsGetValue(wgl_tls_index); 132 | LocalFree(data); 133 | 134 | if (reason == DLL_PROCESS_DETACH) { 135 | TlsFree(gl_tls_index); 136 | TlsFree(wgl_tls_index); 137 | } 138 | break; 139 | } 140 | 141 | return TRUE; 142 | } 143 | 144 | WRAPPER_VISIBILITY (BOOL) 145 | WRAPPER(epoxy_wglMakeCurrent)(HDC hdc, HGLRC hglrc) 146 | { 147 | BOOL ret = epoxy_wglMakeCurrent_unwrapped(hdc, hglrc); 148 | 149 | epoxy_handle_external_wglMakeCurrent(); 150 | 151 | return ret; 152 | } 153 | 154 | 155 | WRAPPER_VISIBILITY (BOOL) 156 | WRAPPER(epoxy_wglMakeContextCurrentARB)(HDC hDrawDC, 157 | HDC hReadDC, 158 | HGLRC hglrc) 159 | { 160 | BOOL ret = epoxy_wglMakeContextCurrentARB_unwrapped(hDrawDC, hReadDC, 161 | hglrc); 162 | 163 | epoxy_handle_external_wglMakeCurrent(); 164 | 165 | return ret; 166 | } 167 | 168 | 169 | WRAPPER_VISIBILITY (BOOL) 170 | WRAPPER(epoxy_wglMakeContextCurrentEXT)(HDC hDrawDC, 171 | HDC hReadDC, 172 | HGLRC hglrc) 173 | { 174 | BOOL ret = epoxy_wglMakeContextCurrentEXT_unwrapped(hDrawDC, hReadDC, 175 | hglrc); 176 | 177 | epoxy_handle_external_wglMakeCurrent(); 178 | 179 | return ret; 180 | } 181 | 182 | 183 | WRAPPER_VISIBILITY (BOOL) 184 | WRAPPER(epoxy_wglMakeAssociatedContextCurrentAMD)(HGLRC hglrc) 185 | { 186 | BOOL ret = epoxy_wglMakeAssociatedContextCurrentAMD_unwrapped(hglrc); 187 | 188 | epoxy_handle_external_wglMakeCurrent(); 189 | 190 | return ret; 191 | } 192 | 193 | PFNWGLMAKECURRENTPROC epoxy_wglMakeCurrent = epoxy_wglMakeCurrent_wrapped; 194 | PFNWGLMAKECONTEXTCURRENTEXTPROC epoxy_wglMakeContextCurrentEXT = epoxy_wglMakeContextCurrentEXT_wrapped; 195 | PFNWGLMAKECONTEXTCURRENTARBPROC epoxy_wglMakeContextCurrentARB = epoxy_wglMakeContextCurrentARB_wrapped; 196 | PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC epoxy_wglMakeAssociatedContextCurrentEXT = epoxy_wglMakeAssociatedContextCurrentAMD_wrapped; 197 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright © 2013 Intel Corporation 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a 4 | # copy of this software and associated documentation files (the "Software"), 5 | # to deal in the Software without restriction, including without limitation 6 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | # and/or sell copies of the Software, and to permit persons to whom the 8 | # Software is furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice (including the next 11 | # paragraph) shall be included in all copies or substantial portions of the 12 | # Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | # IN THE SOFTWARE. 21 | 22 | EPOXY = $(builddir)/../src/libepoxy.la 23 | 24 | check_LTLIBRARIES = \ 25 | $(EGL_UTIL_LIB) \ 26 | $(GLX_UTIL_LIB) \ 27 | $(WGL_UTIL_LIB) \ 28 | $() 29 | 30 | libegl_common_la_SOURCES = \ 31 | egl_common.c \ 32 | egl_common.h 33 | $() 34 | 35 | libglx_common_la_SOURCES = \ 36 | glx_common.c \ 37 | glx_common.h 38 | $() 39 | 40 | libwgl_common_la_SOURCES = \ 41 | wgl_common.c \ 42 | wgl_common.h 43 | $() 44 | libwgl_common_la_LIBADD = $(EPOXY) 45 | 46 | AM_CPPFLAGS = \ 47 | -I$(top_srcdir)/include \ 48 | -I$(top_builddir)/include \ 49 | $(X11_CFLAGS) \ 50 | $(EGL_CFLAGS) \ 51 | $() 52 | 53 | AM_CFLAGS = $(CWARNFLAGS) 54 | 55 | TESTS = \ 56 | $(EGL_TESTS) \ 57 | $(GLX_TESTS) \ 58 | $(EGL_AND_GLX_TESTS) \ 59 | $(WGL_TESTS) \ 60 | headerguards$(EXEEXT) \ 61 | miscdefines$(EXEEXT) \ 62 | khronos_typedefs$(EXEEXT) \ 63 | $() 64 | 65 | check_BINARIES = $(EGL_AND_GLX_BIN) 66 | 67 | XFAIL_TESTS = \ 68 | egl_and_glx_different_pointers_egl_glx \ 69 | $() 70 | 71 | check_PROGRAMS = $(TESTS) 72 | 73 | if BUILD_EGL 74 | EGL_TESTS = \ 75 | $() 76 | 77 | if HAVE_X11 78 | EGL_TESTS += \ 79 | egl_has_extension_nocontext \ 80 | egl_gles2_without_glx \ 81 | $() 82 | 83 | if HAS_GLES1 84 | EGL_TESTS += egl_gles1_without_glx 85 | endif 86 | 87 | EGL_UTIL_LIB = libegl_common.la 88 | endif 89 | endif 90 | 91 | if BUILD_GLX 92 | if HAS_ZNOW 93 | GLX_SHARED_ZNOW = glx_shared_znow 94 | endif 95 | 96 | if BUILD_EGL 97 | if BUILD_GLX 98 | if !BUILD_APPLE 99 | EGL_AND_GLX_TESTS = \ 100 | egl_gl \ 101 | egl_and_glx_different_pointers_egl_glx \ 102 | egl_and_glx_different_pointers_egl \ 103 | egl_and_glx_different_pointers_glx \ 104 | $() 105 | endif 106 | endif 107 | endif 108 | 109 | if !BUILD_APPLE 110 | GLX_NON_APPLE_TESTS = \ 111 | glx_alias_prefer_same_name \ 112 | glx_gles2 \ 113 | $() 114 | endif 115 | 116 | GLX_TESTS = \ 117 | glx_beginend \ 118 | glx_public_api \ 119 | glx_public_api_core \ 120 | glx_glxgetprocaddress_nocontext \ 121 | glx_has_extension_nocontext \ 122 | glx_static \ 123 | $(GLX_SHARED_ZNOW) \ 124 | $(GLX_NON_APPLE_TESTS) \ 125 | $() 126 | 127 | GLX_UTIL_LIB = libglx_common.la 128 | endif 129 | 130 | if BUILD_WGL 131 | WGL_TESTS = \ 132 | wgl_core_and_exts$(EXEEXT) \ 133 | wgl_per_context_funcptrs$(EXEEXT) \ 134 | wgl_usefontbitmaps$(EXEEXT) \ 135 | wgl_usefontbitmaps_unicode$(EXEEXT) \ 136 | $() 137 | 138 | WGL_UTIL_LIB = libwgl_common.la 139 | endif 140 | 141 | egl_has_extension_nocontext_LDADD = $(EPOXY) libegl_common.la $(X11_LIBS) 142 | 143 | egl_gl_LDADD = $(EPOXY) $(DLOPEN_LIBS) libegl_common.la $(X11_LIBS) 144 | 145 | egl_gles1_without_glx_CPPFLAGS = $(AM_CPPFLAGS) -DGLES_VERSION=1 146 | egl_gles1_without_glx_SOURCES = egl_without_glx.c 147 | egl_gles1_without_glx_LDADD = $(EPOXY) $(DLOPEN_LIBS) libegl_common.la $(X11_LIBS) 148 | 149 | egl_gles2_without_glx_CPPFLAGS = $(AM_CPPFLAGS) -DGLES_VERSION=2 150 | egl_gles2_without_glx_SOURCES = egl_without_glx.c 151 | egl_gles2_without_glx_LDADD = $(EPOXY) $(DLOPEN_LIBS) libegl_common.la $(X11_LIBS) 152 | 153 | egl_and_glx_different_pointers_egl_SOURCES = egl_and_glx_different_pointers.c dlwrap.c dlwrap.h 154 | egl_and_glx_different_pointers_egl_LDADD = libegl_common.la libglx_common.la $(DLOPEN_LIBS) $(EPOXY) $(X11_LIBS) 155 | egl_and_glx_different_pointers_egl_LDFLAGS = -rdynamic 156 | egl_and_glx_different_pointers_egl_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_EGL 157 | 158 | egl_and_glx_different_pointers_glx_SOURCES = egl_and_glx_different_pointers.c dlwrap.c dlwrap.h 159 | egl_and_glx_different_pointers_glx_LDADD = libegl_common.la libglx_common.la $(DLOPEN_LIBS) $(EPOXY) $(X11_LIBS) 160 | egl_and_glx_different_pointers_glx_LDFLAGS = -rdynamic 161 | egl_and_glx_different_pointers_glx_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_GLX 162 | 163 | egl_and_glx_different_pointers_egl_glx_SOURCES = egl_and_glx_different_pointers.c dlwrap.c dlwrap.h 164 | egl_and_glx_different_pointers_egl_glx_LDADD = libegl_common.la libglx_common.la $(DLOPEN_LIBS) $(EPOXY) $(X11_LIBS) 165 | egl_and_glx_different_pointers_egl_glx_LDFLAGS = -rdynamic 166 | egl_and_glx_different_pointers_egl_glx_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_EGL -DUSE_GLX 167 | 168 | glx_alias_prefer_same_name_SOURCES = glx_alias_prefer_same_name.c dlwrap.c dlwrap.h 169 | glx_alias_prefer_same_name_LDFLAGS = -rdynamic 170 | glx_alias_prefer_same_name_LDADD = $(EPOXY) libglx_common.la $(X11_LIBS) -ldl 171 | 172 | glx_beginend_LDADD = $(EPOXY) libglx_common.la $(GL_LIBS) $(X11_LIBS) 173 | 174 | glx_gles2_SOURCES = glx_gles2.c dlwrap.c dlwrap.h 175 | glx_gles2_LDFLAGS = -rdynamic 176 | glx_gles2_LDADD = $(EPOXY) libglx_common.la $(X11_LIBS) -ldl 177 | 178 | glx_public_api_LDADD = $(EPOXY) libglx_common.la $(X11_LIBS) 179 | 180 | glx_public_api_core_LDADD = $(EPOXY) libglx_common.la $(X11_LIBS) 181 | 182 | glx_glxgetprocaddress_nocontext_LDADD = $(EPOXY) libglx_common.la $(X11_LIBS) 183 | 184 | glx_has_extension_nocontext_LDADD = $(EPOXY) libglx_common.la $(X11_LIBS) 185 | 186 | glx_static_CFLAGS = -DNEEDS_TO_BE_STATIC 187 | glx_static_LDADD = $(DLOPEN_LIBS) $(EPOXY) libglx_common.la $(X11_LIBS) 188 | glx_static_LDFLAGS = -static 189 | 190 | glx_shared_znow_SOURCES = glx_static.c 191 | glx_shared_znow_LDADD = $(DLOPEN_LIBS) $(EPOXY) libglx_common.la $(X11_LIBS) 192 | glx_shared_znow_LDFLAGS = -Wl,-z,now 193 | 194 | khronos_typedefs_SOURCES = \ 195 | khronos_typedefs.c \ 196 | khronos_typedefs.h \ 197 | khronos_typedefs_nonepoxy.c \ 198 | $() 199 | 200 | wgl_core_and_exts_LDADD = $(EPOXY) libwgl_common.la -lgdi32 201 | 202 | wgl_per_context_funcptrs_LDADD = $(EPOXY) libwgl_common.la -lgdi32 203 | 204 | wgl_usefontbitmaps_LDADD = $(EPOXY) libwgl_common.la -lgdi32 205 | wgl_usefontbitmaps_unicode_SOURCES = wgl_usefontbitmaps.c 206 | wgl_usefontbitmaps_unicode_LDADD = $(EPOXY) libwgl_common.la -lgdi32 207 | wgl_usefontbitmaps_unicode_CPPFLAGS = $(AM_CPPFLAGS) -DUNICODE 208 | -------------------------------------------------------------------------------- /test/meson.build: -------------------------------------------------------------------------------- 1 | has_gles1 = gles1_dep.found() 2 | has_gles2 = gles2_dep.found() 3 | build_x11_tests = build_glx and x11_dep.found() 4 | 5 | test_cflags = common_cflags + [ 6 | '-D_XOPEN_SOURCE', 7 | '-D_POSIX_C_SOURCE=200809L', 8 | ] 9 | 10 | # Unconditionally built tests 11 | test('header_guards', 12 | executable('header guards', 'headerguards.c', 13 | c_args: common_cflags, 14 | dependencies: libepoxy_dep, 15 | include_directories: libepoxy_inc)) 16 | test('misc_defines', 17 | executable('misc defines', 'miscdefines.c', 18 | c_args: common_cflags, 19 | dependencies: libepoxy_dep, 20 | include_directories: libepoxy_inc)) 21 | test('khronos_typedefs', 22 | executable('khronos typedefs', [ 23 | 'khronos_typedefs.c', 24 | 'khronos_typedefs.h', 25 | 'khronos_typedefs_nonepoxy.c', 26 | ], 27 | c_args: common_cflags, 28 | dependencies: libepoxy_dep, 29 | include_directories: libepoxy_inc)) 30 | 31 | if build_egl and build_x11_tests 32 | egl_common_sources = [ 'egl_common.h', 'egl_common.c', ] 33 | egl_common_lib = static_library('egl_common', 34 | sources: egl_common_sources, 35 | dependencies: libepoxy_dep, 36 | include_directories: libepoxy_inc, 37 | c_args: common_cflags, 38 | install: false) 39 | 40 | egl_tests = [ 41 | [ 'egl_has_extension_nocontext', [], [ 'egl_has_extension_nocontext.c' ], true, ], 42 | [ 'egl_gl', [], [ 'egl_gl.c' ], true, ], 43 | [ 'egl_gles1_without_glx', [ '-DGLES_VERSION=1', ], [ 'egl_without_glx.c' ], has_gles1, ], 44 | [ 'egl_gles2_without_glx', [ '-DGLES_VERSION=2', ], [ 'egl_without_glx.c' ], has_gles2, ], 45 | ] 46 | 47 | foreach test: egl_tests 48 | test_name = test[0] 49 | test_source = test[2] 50 | test_args = test[1] 51 | test_run = test[3] 52 | 53 | if test_run 54 | test_bin = executable(test_name, test_source, 55 | c_args: test_cflags + test_args, 56 | include_directories: libepoxy_inc, 57 | dependencies: [ libepoxy_dep, x11_dep, egl_dep, dl_dep ], 58 | link_with: egl_common_lib, 59 | link_args: '-rdynamic') 60 | test(test_name, test_bin) 61 | endif 62 | endforeach 63 | endif 64 | 65 | if build_glx 66 | glx_common_sources = [ 'glx_common.h', 'glx_common.c', ] 67 | glx_common_lib = static_library('glx_common', 68 | sources: glx_common_sources, 69 | dependencies: libepoxy_dep, 70 | include_directories: libepoxy_inc, 71 | c_args: common_cflags, 72 | install: false) 73 | 74 | # glx_beginend links directly with the GL library, so we need to check it 75 | # separately 76 | test('glx_beginend', executable('glx_beginend', 'glx_beginend.c', 77 | c_args: test_cflags, 78 | include_directories: libepoxy_inc, 79 | dependencies: [ libepoxy_dep, x11_dep, gl_dep, dl_dep ], 80 | link_with: glx_common_lib)) 81 | 82 | glx_tests = [ 83 | [ 'glx_public_api', [ 'glx_public_api.c' ], [], [], true ], 84 | [ 'glx_public_api_core', [ 'glx_public_api_core.c' ], [], [], true ], 85 | [ 'glx_glxgetprocaddress_nocontext', [ 'glx_glxgetprocaddress_nocontext.c' ], [], [], true ], 86 | [ 'glx_has_extension_nocontext', [ 'glx_has_extension_nocontext.c' ], [], [], true ], 87 | [ 'glx_static', [ 'glx_static.c' ], [ '-DNEEDS_TO_BE_STATIC'], [ '-static' ], libtype == 'static' ], 88 | [ 'glx_shared_znow', [ 'glx_static.c', ], [], [ '-Wl,-z,now' ], has_znow ], 89 | [ 'glx_alias_prefer_same_name', [ 'glx_alias_prefer_same_name.c', 'dlwrap.c', 'dlwrap.h' ], [], [ '-rdynamic' ], not build_apple ], 90 | [ 'glx_gles2', [ 'glx_gles2.c', 'dlwrap.c', 'dlwrap.h' ], [], [ '-rdynamic' ], not build_apple ], 91 | ] 92 | 93 | foreach test: glx_tests 94 | test_name = test[0] 95 | test_source = test[1] 96 | test_c_args = test[2] 97 | test_link_args = test[3] 98 | test_run = test[4] 99 | 100 | if test_run 101 | test_bin = executable(test_name, test_source, 102 | c_args: test_cflags + test_c_args, 103 | include_directories: libepoxy_inc, 104 | dependencies: [ libepoxy_dep, x11_dep, dl_dep ], 105 | link_with: glx_common_lib, 106 | link_args: test_link_args) 107 | test(test_name, test_bin) 108 | endif 109 | endforeach 110 | 111 | if not build_apple 112 | # GLX/EGL tests 113 | if build_egl 114 | glx_egl_sources = [ 115 | 'egl_and_glx_different_pointers.c', 116 | 'dlwrap.c', 117 | 'dlwrap.h', 118 | ] 119 | 120 | glx_egl_deps = [ libepoxy_dep, x11_dep, dl_dep ] 121 | glx_egl_link_flags = [ '-rdynamic' ] 122 | glx_egl_link_with = [ glx_common_lib, egl_common_lib ] 123 | 124 | glx_egl_tests = [ 125 | [ 'egl_and_glx_different_pointers_glx', [ '-DUSE_GLX' ], false ], 126 | [ 'egl_and_glx_different_pointers_egl', [ '-DUSE_EGL' ], false ], 127 | [ 'egl_and_glx_different_pointers_egl_glx', [ '-DUSE_EGL', '-DUSE_GLX' ], true ], 128 | ] 129 | 130 | foreach test: glx_egl_tests 131 | test_name = test[0] 132 | test_c_args = test[1] 133 | test_should_fail = test[2] 134 | 135 | test_bin = executable(test_name, glx_egl_sources, 136 | c_args: common_cflags + test_c_args, 137 | include_directories: libepoxy_inc, 138 | dependencies: glx_egl_deps, 139 | link_with: glx_egl_link_with, 140 | link_args: glx_egl_link_flags) 141 | test(test_name, test_bin, should_fail: test_should_fail) 142 | endforeach 143 | endif 144 | endif 145 | endif 146 | 147 | # WGL 148 | if build_wgl 149 | wgl_common_sources = [ 'wgl_common.h', 'wgl_common.c', ] 150 | wgl_common_lib = static_library('wgl_common', 151 | sources: wgl_common_sources, 152 | dependencies: libepoxy_dep, 153 | include_directories: libepoxy_inc, 154 | c_args: common_cflags, 155 | install: false) 156 | 157 | wgl_tests = [ 158 | [ 'wgl_core_and_exts', [ 'wgl_core_and_exts.c' ], [], ], 159 | [ 'wgl_per_context_funcptrs', [ 'wgl_per_context_funcptrs.c' ], [], ], 160 | [ 'wgl_usefontbitmaps', [ 'wgl_usefontbitmaps.c'], [], ], 161 | [ 'wgl_usefontbitmaps_unicode', [ 'wgl_usefontbitmaps.c' ], [ '-DUNICODE' ], ], 162 | ] 163 | 164 | foreach test: wgl_tests 165 | test_name = test[0] 166 | test_source = test[1] 167 | test_c_args = test[2] 168 | 169 | test_bin = executable(test_name, test_source, 170 | c_args: test_cflags + test_c_args, 171 | include_directories: libepoxy_inc, 172 | dependencies: [ libepoxy_dep ], 173 | link_with: wgl_common_lib) 174 | 175 | test(test_name, test_bin) 176 | endforeach 177 | endif 178 | -------------------------------------------------------------------------------- /test/egl_and_glx_different_pointers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2014 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | /** 25 | * @file egl_and_glx_different_pointers.c 26 | * 27 | * Tests that epoxy correctly handles an EGL and GLX implementation 28 | * that return different function pointers between the two. 29 | * 30 | * This is the case for EGL and GLX on nvidia binary drivers 31 | * currently, but is also the case if someone has nvidia binary GLX 32 | * installed but still has Mesa (software) EGL installed. This seems 33 | * common enough that we should make sure things work. 34 | */ 35 | 36 | #define _GNU_SOURCE 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include "epoxy/gl.h" 45 | #include "epoxy/egl.h" 46 | #include "epoxy/glx.h" 47 | 48 | #include "egl_common.h" 49 | #include "glx_common.h" 50 | #include "dlwrap.h" 51 | 52 | #define GLX_FAKED_VENDOR_STRING "libepoxy override GLX" 53 | #define EGL_FAKED_VENDOR_STRING "libepoxy override EGL" 54 | 55 | #define GL_CREATESHADER_VALUE 1234 56 | #define GLES2_CREATESHADER_VALUE 5678 57 | 58 | const char *override_GLES2_glGetString(GLenum e); 59 | const char *override_GL_glGetString(GLenum e); 60 | GLuint override_GLES2_glCreateShader(GLenum e); 61 | GLuint override_GL_glCreateShader(GLenum e); 62 | 63 | const char * 64 | override_GL_glGetString(GLenum e) 65 | { 66 | if (e == GL_VENDOR) 67 | return GLX_FAKED_VENDOR_STRING; 68 | 69 | return DEFER_TO_GL("libGL.so.1", override_GL_glGetString, 70 | "glGetString", (e)); 71 | } 72 | 73 | const char * 74 | override_GLES2_glGetString(GLenum e) 75 | { 76 | if (e == GL_VENDOR) 77 | return EGL_FAKED_VENDOR_STRING; 78 | 79 | return DEFER_TO_GL("libGLESv2.so.2", override_GLES2_glGetString, 80 | "glGetString", (e)); 81 | } 82 | 83 | GLuint 84 | override_GL_glCreateShader(GLenum type) 85 | { 86 | return GL_CREATESHADER_VALUE; 87 | } 88 | 89 | GLuint 90 | override_GLES2_glCreateShader(GLenum type) 91 | { 92 | return GLES2_CREATESHADER_VALUE; 93 | } 94 | 95 | #ifdef USE_GLX 96 | static bool 97 | make_glx_current_and_test(Display *dpy, GLXContext ctx, Drawable draw) 98 | { 99 | const char *string; 100 | GLuint shader; 101 | bool pass = true; 102 | 103 | glXMakeCurrent(dpy, draw, ctx); 104 | 105 | if (!epoxy_is_desktop_gl()) { 106 | fprintf(stderr, "Claimed to be ES\n"); 107 | pass = false; 108 | } 109 | 110 | string = (const char *)glGetString(GL_VENDOR); 111 | printf("GLX vendor: %s\n", string); 112 | 113 | shader = glCreateShader(GL_FRAGMENT_SHADER); 114 | if (shader != GL_CREATESHADER_VALUE) { 115 | fprintf(stderr, "glCreateShader() returned %d instead of %d\n", 116 | shader, GL_CREATESHADER_VALUE); 117 | pass = false; 118 | } 119 | 120 | pass = pass && !strcmp(string, GLX_FAKED_VENDOR_STRING); 121 | 122 | return pass; 123 | } 124 | 125 | static void 126 | init_glx(Display **out_dpy, GLXContext *out_ctx, Drawable *out_draw) 127 | { 128 | Display *dpy = get_display_or_skip(); 129 | make_glx_context_current_or_skip(dpy); 130 | 131 | *out_dpy = dpy; 132 | *out_ctx = glXGetCurrentContext(); 133 | *out_draw= glXGetCurrentDrawable(); 134 | } 135 | #endif /* USE_GLX */ 136 | 137 | #ifdef USE_EGL 138 | static bool 139 | make_egl_current_and_test(EGLDisplay *dpy, EGLContext ctx) 140 | { 141 | const char *string; 142 | GLuint shader; 143 | bool pass = true; 144 | 145 | eglMakeCurrent(dpy, NULL, NULL, ctx); 146 | 147 | if (epoxy_is_desktop_gl()) { 148 | fprintf(stderr, "Claimed to be desktop\n"); 149 | pass = false; 150 | } 151 | 152 | if (epoxy_gl_version() < 20) { 153 | fprintf(stderr, "Claimed to be GL version %d\n", 154 | epoxy_gl_version()); 155 | pass = false; 156 | } 157 | 158 | shader = glCreateShader(GL_FRAGMENT_SHADER); 159 | if (shader != GLES2_CREATESHADER_VALUE) { 160 | fprintf(stderr, "glCreateShader() returned %d instead of %d\n", 161 | shader, GLES2_CREATESHADER_VALUE); 162 | pass = false; 163 | } 164 | 165 | string = (const char *)glGetString(GL_VENDOR); 166 | printf("EGL vendor: %s\n", string); 167 | 168 | pass = pass && !strcmp(string, EGL_FAKED_VENDOR_STRING); 169 | 170 | return pass; 171 | } 172 | 173 | static void 174 | init_egl(EGLDisplay **out_dpy, EGLContext *out_ctx) 175 | { 176 | EGLDisplay *dpy = get_egl_display_or_skip(); 177 | static const EGLint config_attribs[] = { 178 | EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 179 | EGL_RED_SIZE, 1, 180 | EGL_GREEN_SIZE, 1, 181 | EGL_BLUE_SIZE, 1, 182 | EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, 183 | EGL_NONE 184 | }; 185 | static const EGLint context_attribs[] = { 186 | EGL_CONTEXT_CLIENT_VERSION, 2, 187 | EGL_NONE 188 | }; 189 | EGLContext ctx; 190 | EGLConfig cfg; 191 | EGLint count; 192 | 193 | if (!epoxy_has_egl_extension(dpy, "EGL_KHR_surfaceless_context")) 194 | errx(77, "Test requires EGL_KHR_surfaceless_context"); 195 | 196 | eglBindAPI(EGL_OPENGL_ES_API); 197 | 198 | if (!eglChooseConfig(dpy, config_attribs, &cfg, 1, &count)) 199 | errx(77, "Couldn't get an EGLConfig\n"); 200 | 201 | ctx = eglCreateContext(dpy, cfg, NULL, context_attribs); 202 | if (!ctx) 203 | errx(77, "Couldn't create a GLES2 context\n"); 204 | 205 | *out_dpy = dpy; 206 | *out_ctx = ctx; 207 | } 208 | #endif /* USE_EGL */ 209 | 210 | int 211 | main(int argc, char **argv) 212 | { 213 | bool pass = true; 214 | #ifdef USE_EGL 215 | EGLDisplay *egl_dpy; 216 | EGLContext egl_ctx; 217 | #endif 218 | #ifdef USE_GLX 219 | Display *glx_dpy; 220 | GLXContext glx_ctx; 221 | Drawable glx_draw; 222 | #endif 223 | 224 | /* Force epoxy to have loaded both EGL and GLX libs already -- we 225 | * can't assume anything about symbol resolution based on having 226 | * EGL or GLX loaded. 227 | */ 228 | (void)glXGetCurrentContext(); 229 | (void)eglGetCurrentContext(); 230 | 231 | #ifdef USE_GLX 232 | init_glx(&glx_dpy, &glx_ctx, &glx_draw); 233 | pass = make_glx_current_and_test(glx_dpy, glx_ctx, glx_draw) && pass; 234 | #endif 235 | #ifdef USE_EGL 236 | init_egl(&egl_dpy, &egl_ctx); 237 | pass = make_egl_current_and_test(egl_dpy, egl_ctx) && pass; 238 | #endif 239 | 240 | #if defined(USE_GLX) && defined(USE_EGL) 241 | pass = make_glx_current_and_test(glx_dpy, glx_ctx, glx_draw) && pass; 242 | pass = make_egl_current_and_test(egl_dpy, egl_ctx) && pass; 243 | #endif 244 | 245 | return pass != true; 246 | } 247 | -------------------------------------------------------------------------------- /doc/Doxyfile.in: -------------------------------------------------------------------------------- 1 | DOXYFILE_ENCODING = UTF-8 2 | PROJECT_NAME = @PACKAGE_NAME@ 3 | PROJECT_NUMBER = @PACKAGE_VERSION@ 4 | PROJECT_BRIEF = 5 | PROJECT_LOGO = 6 | OUTPUT_DIRECTORY = doc 7 | CREATE_SUBDIRS = NO 8 | ALLOW_UNICODE_NAMES = YES 9 | OUTPUT_LANGUAGE = English 10 | BRIEF_MEMBER_DESC = YES 11 | REPEAT_BRIEF = YES 12 | ABBREVIATE_BRIEF = 13 | ALWAYS_DETAILED_SEC = NO 14 | INLINE_INHERITED_MEMB = NO 15 | FULL_PATH_NAMES = YES 16 | STRIP_FROM_PATH = "@top_srcdir@/include" "@top_builddir@/include" 17 | 18 | SHORT_NAMES = NO 19 | JAVADOC_AUTOBRIEF = YES 20 | QT_AUTOBRIEF = NO 21 | MULTILINE_CPP_IS_BRIEF = NO 22 | INHERIT_DOCS = YES 23 | SEPARATE_MEMBER_PAGES = NO 24 | TAB_SIZE = 8 25 | ALIASES = "newin{2}=\xrefitem since_\1_\2 \"Since @PACKAGE_NAME@ \1.\2\" \"New API in @PACKAGE_NAME@ \1.\2\"" 26 | TCL_SUBST = 27 | OPTIMIZE_OUTPUT_FOR_C = YES 28 | OPTIMIZE_OUTPUT_JAVA = NO 29 | OPTIMIZE_FOR_FORTRAN = NO 30 | OPTIMIZE_OUTPUT_VHDL = NO 31 | EXTENSION_MAPPING = 32 | MARKDOWN_SUPPORT = YES 33 | AUTOLINK_SUPPORT = YES 34 | BUILTIN_STL_SUPPORT = NO 35 | CPP_CLI_SUPPORT = NO 36 | SIP_SUPPORT = NO 37 | IDL_PROPERTY_SUPPORT = NO 38 | DISTRIBUTE_GROUP_DOC = NO 39 | GROUP_NESTED_COMPOUNDS = NO 40 | SUBGROUPING = YES 41 | INLINE_GROUPED_CLASSES = NO 42 | INLINE_SIMPLE_STRUCTS = NO 43 | TYPEDEF_HIDES_STRUCT = NO 44 | LOOKUP_CACHE_SIZE = 0 45 | 46 | EXTRACT_ALL = YES 47 | EXTRACT_PRIVATE = NO 48 | EXTRACT_PACKAGE = NO 49 | EXTRACT_STATIC = NO 50 | EXTRACT_LOCAL_CLASSES = NO 51 | EXTRACT_LOCAL_METHODS = NO 52 | EXTRACT_ANON_NSPACES = NO 53 | HIDE_UNDOC_MEMBERS = YES 54 | HIDE_UNDOC_CLASSES = YES 55 | HIDE_FRIEND_COMPOUNDS = YES 56 | HIDE_IN_BODY_DOCS = YES 57 | INTERNAL_DOCS = NO 58 | CASE_SENSE_NAMES = YES 59 | HIDE_SCOPE_NAMES = NO 60 | HIDE_COMPOUND_REFERENCE= NO 61 | SHOW_INCLUDE_FILES = YES 62 | SHOW_GROUPED_MEMB_INC = NO 63 | FORCE_LOCAL_INCLUDES = NO 64 | INLINE_INFO = YES 65 | SORT_MEMBER_DOCS = YES 66 | SORT_BRIEF_DOCS = NO 67 | SORT_MEMBERS_CTORS_1ST = YES 68 | SORT_GROUP_NAMES = YES 69 | SORT_BY_SCOPE_NAME = YES 70 | STRICT_PROTO_MATCHING = NO 71 | GENERATE_TODOLIST = YES 72 | GENERATE_TESTLIST = NO 73 | GENERATE_BUGLIST = YES 74 | GENERATE_DEPRECATEDLIST= YES 75 | ENABLED_SECTIONS = 76 | MAX_INITIALIZER_LINES = 2 77 | SHOW_USED_FILES = YES 78 | SHOW_FILES = YES 79 | SHOW_NAMESPACES = NO 80 | FILE_VERSION_FILTER = 81 | LAYOUT_FILE = 82 | CITE_BIB_FILES = 83 | 84 | QUIET = YES 85 | WARNINGS = YES 86 | WARN_IF_UNDOCUMENTED = YES 87 | WARN_IF_DOC_ERROR = YES 88 | WARN_NO_PARAMDOC = YES 89 | WARN_AS_ERROR = NO 90 | WARN_FORMAT = "$file:$line: $text" 91 | WARN_LOGFILE = doc/doxygen.log 92 | 93 | INPUT = "@top_srcdir@/include/epoxy" "@top_srcdir@/src" 94 | INPUT_ENCODING = UTF-8 95 | FILE_PATTERNS = "*.h" "*.c" 96 | RECURSIVE = NO 97 | EXCLUDE = "@top_srcdir@/src/gen_dispatch.py" 98 | EXCLUDE_SYMLINKS = YES 99 | EXCLUDE_PATTERNS = 100 | EXCLUDE_SYMBOLS = _* GLAPI* KHRONOS_* APIENTRY* GLX* wgl* EPOXY_CALLSPEC EPOXY_BEGIN_DECLS EPOXY_END_DECLS 101 | EXAMPLE_PATH = 102 | EXAMPLE_PATTERNS = 103 | EXAMPLE_RECURSIVE = NO 104 | IMAGE_PATH = 105 | INPUT_FILTER = 106 | FILTER_PATTERNS = 107 | FILTER_SOURCE_FILES = NO 108 | FILTER_SOURCE_PATTERNS = 109 | USE_MDFILE_AS_MAINPAGE = 110 | 111 | SOURCE_BROWSER = NO 112 | INLINE_SOURCES = NO 113 | STRIP_CODE_COMMENTS = YES 114 | REFERENCED_BY_RELATION = NO 115 | REFERENCES_RELATION = NO 116 | REFERENCES_LINK_SOURCE = YES 117 | SOURCE_TOOLTIPS = YES 118 | USE_HTAGS = NO 119 | VERBATIM_HEADERS = NO 120 | 121 | ALPHABETICAL_INDEX = YES 122 | COLS_IN_ALPHA_INDEX = 3 123 | IGNORE_PREFIX = "epoxy" 124 | 125 | GENERATE_HTML = YES 126 | HTML_OUTPUT = html 127 | HTML_FILE_EXTENSION = .html 128 | HTML_HEADER = 129 | HTML_FOOTER = 130 | HTML_STYLESHEET = 131 | HTML_EXTRA_STYLESHEET = 132 | HTML_EXTRA_FILES = 133 | HTML_COLORSTYLE_HUE = 220 134 | HTML_COLORSTYLE_SAT = 100 135 | HTML_COLORSTYLE_GAMMA = 80 136 | HTML_TIMESTAMP = YES 137 | HTML_DYNAMIC_SECTIONS = NO 138 | HTML_INDEX_NUM_ENTRIES = 100 139 | GENERATE_DOCSET = NO 140 | DOCSET_FEEDNAME = "Doxygen generated docs" 141 | DOCSET_BUNDLE_ID = org.doxygen.Project 142 | DOCSET_PUBLISHER_ID = org.doxygen.Publisher 143 | DOCSET_PUBLISHER_NAME = Publisher 144 | GENERATE_HTMLHELP = NO 145 | CHM_FILE = 146 | HHC_LOCATION = 147 | GENERATE_CHI = NO 148 | CHM_INDEX_ENCODING = 149 | BINARY_TOC = NO 150 | TOC_EXPAND = NO 151 | GENERATE_QHP = NO 152 | QCH_FILE = 153 | QHP_NAMESPACE = 154 | QHP_VIRTUAL_FOLDER = doc 155 | QHP_CUST_FILTER_NAME = 156 | QHP_CUST_FILTER_ATTRS = 157 | QHP_SECT_FILTER_ATTRS = 158 | QHG_LOCATION = 159 | GENERATE_ECLIPSEHELP = NO 160 | ECLIPSE_DOC_ID = org.doxygen.Project 161 | DISABLE_INDEX = NO 162 | GENERATE_TREEVIEW = NO 163 | ENUM_VALUES_PER_LINE = 1 164 | TREEVIEW_WIDTH = 250 165 | EXT_LINKS_IN_WINDOW = NO 166 | FORMULA_FONTSIZE = 10 167 | FORMULA_TRANSPARENT = YES 168 | USE_MATHJAX = NO 169 | MATHJAX_FORMAT = HTML-CSS 170 | MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest 171 | MATHJAX_EXTENSIONS = 172 | MATHJAX_CODEFILE = 173 | SEARCHENGINE = NO 174 | SERVER_BASED_SEARCH = NO 175 | EXTERNAL_SEARCH = NO 176 | SEARCHENGINE_URL = 177 | SEARCHDATA_FILE = 178 | EXTERNAL_SEARCH_ID = 179 | EXTRA_SEARCH_MAPPINGS = 180 | 181 | GENERATE_LATEX = NO 182 | GENERATE_RTF = NO 183 | GENERATE_MAN = NO 184 | GENERATE_XML = NO 185 | GENERATE_DOCBOOK = NO 186 | GENERATE_AUTOGEN_DEF = NO 187 | GENERATE_PERLMOD = NO 188 | 189 | ENABLE_PREPROCESSING = YES 190 | MACRO_EXPANSION = YES 191 | EXPAND_ONLY_PREDEF = YES 192 | SEARCH_INCLUDES = YES 193 | INCLUDE_PATH = "@top_srcdir@/include" \ 194 | "@top_builddir@/include" 195 | INCLUDE_FILE_PATTERNS = *.h 196 | PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \ 197 | "EPOXY_BEGIN_DECLS=" \ 198 | "EPOXY_END_DECLS=" \ 199 | "EPOXY_PUBLIC=" 200 | EXPAND_AS_DEFINED = 201 | SKIP_FUNCTION_MACROS = YES 202 | 203 | ALLEXTERNALS = NO 204 | EXTERNAL_GROUPS = NO 205 | EXTERNAL_PAGES = NO 206 | 207 | HAVE_DOT = @HAVE_DOT@ 208 | CLASS_DIAGRAMS = NO 209 | MSCGEN_PATH = 210 | DIA_PATH = 211 | HIDE_UNDOC_RELATIONS = NO 212 | DOT_NUM_THREADS = 0 213 | DOT_FONTNAME = Sans 214 | DOT_FONTSIZE = 10 215 | DOT_FONTPATH = 216 | CLASS_GRAPH = NO 217 | COLLABORATION_GRAPH = YES 218 | GROUP_GRAPHS = YES 219 | UML_LOOK = NO 220 | UML_LIMIT_NUM_FIELDS = 10 221 | TEMPLATE_RELATIONS = NO 222 | INCLUDE_GRAPH = NO 223 | INCLUDED_BY_GRAPH = NO 224 | CALL_GRAPH = NO 225 | CALLER_GRAPH = NO 226 | GRAPHICAL_HIERARCHY = YES 227 | DIRECTORY_GRAPH = YES 228 | DOT_IMAGE_FORMAT = png 229 | INTERACTIVE_SVG = NO 230 | DOT_PATH = 231 | DOTFILE_DIRS = 232 | MSCFILE_DIRS = 233 | DIAFILE_DIRS = 234 | PLANTUML_JAR_PATH = 235 | PLANTUML_INCLUDE_PATH = 236 | DOT_GRAPH_MAX_NODES = 50 237 | MAX_DOT_GRAPH_DEPTH = 0 238 | DOT_TRANSPARENT = NO 239 | DOT_MULTI_TARGETS = YES 240 | GENERATE_LEGEND = YES 241 | DOT_CLEANUP = YES 242 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Copyright © 2013 Intel Corporation 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a 4 | # copy of this software and associated documentation files (the "Software"), 5 | # to deal in the Software without restriction, including without limitation 6 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | # and/or sell copies of the Software, and to permit persons to whom the 8 | # Software is furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice (including the next 11 | # paragraph) shall be included in all copies or substantial portions of the 12 | # Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | # IN THE SOFTWARE. 21 | 22 | # Initialize Autoconf 23 | AC_PREREQ([2.60]) 24 | AC_INIT([libepoxy], 25 | [1.5.0], 26 | [https://github.com/anholt/libepoxy], 27 | [libepoxy]) 28 | AC_CONFIG_SRCDIR([Makefile.am]) 29 | AC_CONFIG_HEADERS([config.h]) 30 | AC_CONFIG_MACRO_DIR([m4]) 31 | 32 | # Initialize Automake 33 | AM_INIT_AUTOMAKE([foreign -Wno-portability dist-xz no-dist-gzip tar-ustar subdir-objects]) 34 | 35 | # Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS 36 | m4_ifndef([XORG_MACROS_VERSION], 37 | [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen. 38 | Hint: either install from source, git://anongit.freedesktop.org/xorg/util/macros or, 39 | depending on you distribution, try package 'xutils-dev' or 'xorg-x11-util-macros'])]) 40 | 41 | XORG_MACROS_VERSION(1.8) 42 | XORG_DEFAULT_OPTIONS 43 | 44 | AC_CHECK_PROGS([PYTHON], [python3 python2 python]) 45 | 46 | # Initialize libtool 47 | AC_DISABLE_STATIC 48 | AC_LIBTOOL_WIN32_DLL 49 | AC_PROG_LIBTOOL 50 | AC_SYS_LARGEFILE 51 | 52 | AC_CHECK_HEADER([KHR/khrplatform.h], 53 | [AC_DEFINE([HAVE_KHRPLATFORM_H], [1], 54 | [Define to 1 if you have (used for tests)] 55 | )] 56 | ) 57 | 58 | # OS X defaults to having -Wint-conversion ("warn when passing 59 | # uintptr_t to a void *") by default. Kill that. 60 | XORG_TESTSET_CFLAG(CWARNFLAGS, [-Wno-int-conversion]) 61 | 62 | AC_ARG_ENABLE([glx], 63 | [AC_HELP_STRING([--enable-glx=@<:@auto,yes,no@:>@], [Enable GLX support @<:@default=auto@:>@])], 64 | [enable_glx=$enableval], 65 | [enable_glx=auto]) 66 | 67 | # GLX can be used on different platforms, so we expose a 68 | # configure time switch to enable or disable it; in case 69 | # the "auto" default value is set, we only enable GLX 70 | # support on Linux and Unix 71 | AS_CASE([$enable_glx], 72 | [auto], [ 73 | AS_CASE([$host_os], 74 | [mingw*], [build_glx=no], 75 | [darwin*], [build_glx=no], 76 | [android*], [build_glx=no], 77 | [build_glx=yes]) 78 | ], 79 | 80 | [yes], [ 81 | build_glx=yes 82 | ], 83 | 84 | [no], [ 85 | build_glx=no 86 | ], 87 | 88 | [AC_MSG_ERROR([Invalid value "$enable_glx" for option "--enable-glx"])] 89 | ]) 90 | 91 | AC_ARG_ENABLE([egl], 92 | [AC_HELP_STRING([--enable-egl=@<:@auto,yes,no@:>@], [Enable EGL support @<:@default=auto@:>@])], 93 | [enable_egl=$enableval], 94 | [enable_egl=auto]) 95 | 96 | AS_CASE([$enable_egl], 97 | [auto], [ 98 | AS_CASE([$host_os], 99 | [mingw*], [build_egl=no], 100 | [darwin*], [build_egl=no], 101 | [build_egl=yes]) 102 | ], 103 | 104 | [yes], [ 105 | build_egl=yes 106 | ], 107 | 108 | [no], [ 109 | build_egl=no 110 | ], 111 | 112 | [AC_MSG_ERROR([Invalid value "$enable_egl" for option "--enable-egl"])] 113 | ]) 114 | 115 | # The remaining platform specific API are enabled depending on the 116 | # platform we're building for 117 | AS_CASE([$host_os], 118 | [mingw*], [ 119 | build_wgl=yes 120 | has_znow=yes 121 | # On windows, the DLL has to have all of its functions 122 | # resolved at link time, so we have to link directly aginst 123 | # opengl32.dll. But that's the only GL provider, anyway. 124 | EPOXY_LINK_LIBS="-lopengl32" 125 | 126 | # Testing our built windows binaries requires that they be run 127 | # under wine. Yeah, we should be nice and autodetect, but 128 | # there's lots of missing autodetection for the testsuite 129 | # (like checking for EGL and GLX libs in non-windows.). 130 | AC_SUBST([LOG_COMPILER], [wine]) 131 | ], 132 | 133 | [darwin*], [ 134 | build_wgl=no 135 | build_apple=yes 136 | has_znow=no 137 | EPOXY_LINK_LIBS="" 138 | ], 139 | 140 | [ 141 | build_wgl=no 142 | has_znow=yes 143 | # On platforms with dlopen, we load everything dynamically and 144 | # don't link against a specific window system or GL implementation. 145 | EPOXY_LINK_LIBS="" 146 | ] 147 | ) 148 | 149 | AC_SUBST(EPOXY_LINK_LIBS) 150 | 151 | AM_CONDITIONAL(BUILD_EGL, test x$build_egl = xyes) 152 | if test x$build_egl = xyes; then 153 | PKG_CHECK_MODULES(EGL, [egl]) 154 | AC_DEFINE([BUILD_EGL], [1], [build EGL tests]) 155 | AC_DEFINE(ENABLE_EGL, [1], [Whether EGL support is enabled]) 156 | fi 157 | 158 | AM_CONDITIONAL(BUILD_GLX, test x$build_glx = xyes) 159 | if test x$build_glx = xyes; then 160 | AC_DEFINE([BUILD_GLX], [1], [build GLX tests]) 161 | fi 162 | 163 | AM_CONDITIONAL(BUILD_WGL, test x$build_wgl = xyes) 164 | if test x$build_wgl = xyes; then 165 | AC_DEFINE([BUILD_WGL], [1], [build WGL tests]) 166 | fi 167 | 168 | AM_CONDITIONAL(BUILD_APPLE, test x$build_apple = xyes) 169 | if test x$build_apple = xyes; then 170 | AC_DEFINE([BUILD_APPLE], [1], [build APPLE is apple (for testing)]) 171 | fi 172 | 173 | AM_CONDITIONAL(HAS_ZNOW, test x$has_znow = xyes) 174 | 175 | AC_CHECK_LIB([GLESv1_CM], [glFlush], [has_gles1=yes], [has_gles1=no]) 176 | AM_CONDITIONAL(HAS_GLES1, test x$has_gles1 = xyes) 177 | 178 | AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"]) 179 | AC_SUBST([DLOPEN_LIBS]) 180 | 181 | VISIBILITY_CFLAGS="" 182 | AS_CASE(["$host"], 183 | 184 | [*-*-mingw*], [ 185 | dnl on mingw32 we do -fvisibility=hidden and __declspec(dllexport) 186 | AC_DEFINE([EPOXY_PUBLIC], 187 | [__attribute__((visibility("default"))) __declspec(dllexport) extern], 188 | [defines how to decorate public symbols while building]) 189 | VISIBILITY_CFLAGS="-fvisibility=hidden" 190 | ], 191 | 192 | [ 193 | dnl on other compilers, check if we can do -fvisibility=hidden 194 | SAVED_CFLAGS="${CFLAGS}" 195 | CFLAGS="-fvisibility=hidden" 196 | AC_MSG_CHECKING([for -fvisibility=hidden compiler flag]) 197 | AC_TRY_COMPILE([], [int main (void) { return 0; }], [ 198 | AC_MSG_RESULT(yes) 199 | enable_fvisibility_hidden=yes 200 | ], [ 201 | AC_MSG_RESULT(no) 202 | enable_fvisibility_hidden=no 203 | ]) 204 | CFLAGS="${SAVED_CFLAGS}" 205 | 206 | AS_IF([test "${enable_fvisibility_hidden}" = "yes"], [ 207 | AC_DEFINE([EPOXY_PUBLIC], 208 | [__attribute__((visibility("default"))) extern], 209 | [defines how to decorate public symbols while building]) 210 | VISIBILITY_CFLAGS="-fvisibility=hidden" 211 | ]) 212 | ] 213 | ) 214 | 215 | AC_SUBST([VISIBILITY_CFLAGS]) 216 | 217 | if test x$build_glx = xyes; then 218 | PKG_CHECK_MODULES(X11, [x11], [x11=yes], [x11=no]) 219 | if test x$x11 = xno -a x$build_glx = xyes; then 220 | AC_MSG_ERROR([libX11 headers (libx11-dev) required to build with GLX support]) 221 | fi 222 | AC_DEFINE(ENABLE_GLX, [1], [Whether GLX support is enabled]) 223 | else 224 | x11=no 225 | fi 226 | 227 | AM_CONDITIONAL(HAVE_X11, test x$x11 = xyes) 228 | 229 | PKG_CHECK_MODULES(GL, [gl], [gl=yes], [gl=no]) 230 | 231 | # Variables for the pkg-config file; AC_SUBST does not do `test` substitutions, 232 | # so we need to specify the boolean values here 233 | AS_IF([test x$build_glx = xyes], [epoxy_has_glx=1], [epoxy_has_glx=0]) 234 | AS_IF([test x$build_egl = xyes], [epoxy_has_egl=1], [epoxy_has_egl=0]) 235 | AS_IF([test x$build_wgl = xyes], [epoxy_has_wgl=1], [epoxy_has_wgl=0]) 236 | AC_SUBST(epoxy_has_glx) 237 | AC_SUBST(epoxy_has_egl) 238 | AC_SUBST(epoxy_has_wgl) 239 | 240 | AC_CONFIG_FILES([ 241 | epoxy.pc 242 | Makefile 243 | include/epoxy/Makefile 244 | src/Makefile 245 | test/Makefile 246 | ]) 247 | AC_OUTPUT 248 | 249 | echo " EGL: $build_egl" 250 | echo " GLX: $build_glx" 251 | echo " WGL: $build_wgl" 252 | echo " PYTHON: $PYTHON" 253 | -------------------------------------------------------------------------------- /src/dispatch_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2013 Intel Corporation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | */ 23 | 24 | #include "config.h" 25 | 26 | #ifdef _WIN32 27 | #define PLATFORM_HAS_EGL ENABLE_EGL 28 | #define PLATFORM_HAS_GLX ENABLE_GLX 29 | #define PLATFORM_HAS_WGL 1 30 | #elif defined(__APPLE__) 31 | #define PLATFORM_HAS_EGL ENABLE_EGL 32 | #define PLATFORM_HAS_GLX ENABLE_GLX 33 | #define PLATFORM_HAS_WGL 0 34 | #elif defined(ANDROID) 35 | #define PLATFORM_HAS_EGL ENABLE_EGL 36 | #define PLATFORM_HAS_GLX 0 37 | #define PLATFORM_HAS_WGL 0 38 | #else 39 | #define PLATFORM_HAS_EGL ENABLE_EGL 40 | #define PLATFORM_HAS_GLX ENABLE_GLX 41 | #define PLATFORM_HAS_WGL 0 42 | #endif 43 | 44 | #include "epoxy/gl.h" 45 | #if PLATFORM_HAS_GLX 46 | #include "epoxy/glx.h" 47 | #endif 48 | #if PLATFORM_HAS_EGL 49 | #include "epoxy/egl.h" 50 | #endif 51 | #if PLATFORM_HAS_WGL 52 | #include "epoxy/wgl.h" 53 | #endif 54 | 55 | #if defined(__GNUC__) 56 | #define PACKED __attribute__((__packed__)) 57 | #define ENDPACKED 58 | #elif defined (_MSC_VER) 59 | #define PACKED __pragma(pack(push,1)) 60 | #define ENDPACKED __pragma(pack(pop)) 61 | #else 62 | #define PACKED 63 | #define ENDPACKED 64 | #endif 65 | 66 | /* On win32, we're going to need to keep a per-thread dispatch table, 67 | * since the function pointers depend on the device and pixel format 68 | * of the current context. 69 | */ 70 | #if defined(_WIN32) 71 | #define USING_DISPATCH_TABLE 1 72 | #else 73 | #define USING_DISPATCH_TABLE 0 74 | #endif 75 | 76 | #define UNWRAPPED_PROTO(x) (GLAPIENTRY *x) 77 | #define WRAPPER_VISIBILITY(type) static type GLAPIENTRY 78 | #define WRAPPER(x) x ## _wrapped 79 | 80 | #define GEN_GLOBAL_REWRITE_PTR(name, args, passthrough) \ 81 | static void EPOXY_CALLSPEC \ 82 | name##_global_rewrite_ptr args \ 83 | { \ 84 | name = (void *)name##_resolver(); \ 85 | name passthrough; \ 86 | } 87 | 88 | #define GEN_GLOBAL_REWRITE_PTR_RET(ret, name, args, passthrough) \ 89 | static ret EPOXY_CALLSPEC \ 90 | name##_global_rewrite_ptr args \ 91 | { \ 92 | name = (void *)name##_resolver(); \ 93 | return name passthrough; \ 94 | } 95 | 96 | #if USING_DISPATCH_TABLE 97 | #define GEN_DISPATCH_TABLE_REWRITE_PTR(name, args, passthrough) \ 98 | static void EPOXY_CALLSPEC \ 99 | name##_dispatch_table_rewrite_ptr args \ 100 | { \ 101 | struct dispatch_table *dispatch_table = get_dispatch_table(); \ 102 | \ 103 | dispatch_table->name = (void *)name##_resolver(); \ 104 | dispatch_table->name passthrough; \ 105 | } 106 | 107 | #define GEN_DISPATCH_TABLE_REWRITE_PTR_RET(ret, name, args, passthrough) \ 108 | static ret EPOXY_CALLSPEC \ 109 | name##_dispatch_table_rewrite_ptr args \ 110 | { \ 111 | struct dispatch_table *dispatch_table = get_dispatch_table(); \ 112 | \ 113 | dispatch_table->name = (void *)name##_resolver(); \ 114 | return dispatch_table->name passthrough; \ 115 | } 116 | 117 | #define GEN_DISPATCH_TABLE_THUNK(name, args, passthrough) \ 118 | static void EPOXY_CALLSPEC \ 119 | name##_dispatch_table_thunk args \ 120 | { \ 121 | get_dispatch_table()->name passthrough; \ 122 | } 123 | 124 | #define GEN_DISPATCH_TABLE_THUNK_RET(ret, name, args, passthrough) \ 125 | static ret EPOXY_CALLSPEC \ 126 | name##_dispatch_table_thunk args \ 127 | { \ 128 | return get_dispatch_table()->name passthrough; \ 129 | } 130 | 131 | #else 132 | #define GEN_DISPATCH_TABLE_REWRITE_PTR(name, args, passthrough) 133 | #define GEN_DISPATCH_TABLE_REWRITE_PTR_RET(ret, name, args, passthrough) 134 | #define GEN_DISPATCH_TABLE_THUNK(name, args, passthrough) 135 | #define GEN_DISPATCH_TABLE_THUNK_RET(ret, name, args, passthrough) 136 | #endif 137 | 138 | #define GEN_THUNKS(name, args, passthrough) \ 139 | GEN_GLOBAL_REWRITE_PTR(name, args, passthrough) \ 140 | GEN_DISPATCH_TABLE_REWRITE_PTR(name, args, passthrough) \ 141 | GEN_DISPATCH_TABLE_THUNK(name, args, passthrough) 142 | 143 | #define GEN_THUNKS_RET(ret, name, args, passthrough) \ 144 | GEN_GLOBAL_REWRITE_PTR_RET(ret, name, args, passthrough) \ 145 | GEN_DISPATCH_TABLE_REWRITE_PTR_RET(ret, name, args, passthrough) \ 146 | GEN_DISPATCH_TABLE_THUNK_RET(ret, name, args, passthrough) 147 | 148 | void *epoxy_egl_dlsym(const char *name); 149 | void *epoxy_glx_dlsym(const char *name); 150 | void *epoxy_gl_dlsym(const char *name); 151 | void *epoxy_gles1_dlsym(const char *name); 152 | void *epoxy_gles2_dlsym(const char *name); 153 | void *epoxy_gles3_dlsym(const char *name); 154 | void *epoxy_get_proc_address(const char *name); 155 | void *epoxy_get_core_proc_address(const char *name, int core_version); 156 | void *epoxy_get_bootstrap_proc_address(const char *name); 157 | 158 | int epoxy_conservative_gl_version(void); 159 | bool epoxy_conservative_has_gl_extension(const char *name); 160 | int epoxy_conservative_glx_version(void); 161 | bool epoxy_conservative_has_glx_extension(const char *name); 162 | int epoxy_conservative_egl_version(void); 163 | bool epoxy_conservative_has_egl_extension(const char *name); 164 | bool epoxy_conservative_has_wgl_extension(const char *name); 165 | void *epoxy_conservative_egl_dlsym(const char *name, bool exit_if_fails); 166 | void *epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails); 167 | 168 | #define glBegin_unwrapped epoxy_glBegin_unwrapped 169 | #define glEnd_unwrapped epoxy_glEnd_unwrapped 170 | extern void UNWRAPPED_PROTO(glBegin_unwrapped)(GLenum primtype); 171 | extern void UNWRAPPED_PROTO(glEnd_unwrapped)(void); 172 | 173 | extern epoxy_resolver_failure_handler_t epoxy_resolver_failure_handler; 174 | 175 | #if USING_DISPATCH_TABLE 176 | void gl_init_dispatch_table(void); 177 | void gl_switch_to_dispatch_table(void); 178 | void wgl_init_dispatch_table(void); 179 | void wgl_switch_to_dispatch_table(void); 180 | extern uint32_t gl_tls_index, gl_tls_size; 181 | extern uint32_t wgl_tls_index, wgl_tls_size; 182 | 183 | #define wglMakeCurrent_unwrapped epoxy_wglMakeCurrent_unwrapped 184 | #define wglMakeContextCurrentARB_unwrapped epoxy_wglMakeContextCurrentARB_unwrapped 185 | #define wglMakeContextCurrentEXT_unwrapped epoxy_wglMakeContextCurrentEXT_unwrapped 186 | #define wglMakeAssociatedContextCurrentAMD_unwrapped epoxy_wglMakeAssociatedContextCurrentAMD_unwrapped 187 | extern BOOL UNWRAPPED_PROTO(wglMakeCurrent_unwrapped)(HDC hdc, HGLRC hglrc); 188 | extern BOOL UNWRAPPED_PROTO(wglMakeContextCurrentARB_unwrapped)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); 189 | extern BOOL UNWRAPPED_PROTO(wglMakeContextCurrentEXT_unwrapped)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); 190 | extern BOOL UNWRAPPED_PROTO(wglMakeAssociatedContextCurrentAMD_unwrapped)(HGLRC hglrc); 191 | #endif /* _WIN32_ */ 192 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('libepoxy', 'c', version: '1.5.0', 2 | default_options: [ 3 | 'buildtype=debugoptimized', 4 | 'c_std=gnu99', 5 | 'warning_level=1', 6 | ], 7 | license: 'MIT', 8 | meson_version: '>= 0.39.1') 9 | 10 | epoxy_version = meson.project_version().split('.') 11 | epoxy_major_version = epoxy_version[0].to_int() 12 | epoxy_minor_version = epoxy_version[1].to_int() 13 | epoxy_micro_version = epoxy_version[2].to_int() 14 | 15 | epoxy_prefix = get_option('prefix') 16 | epoxy_libdir = join_paths(epoxy_prefix, get_option('libdir')) 17 | epoxy_datadir = join_paths(epoxy_prefix, get_option('datadir')) 18 | epoxy_includedir = join_paths(epoxy_prefix, get_option('includedir')) 19 | 20 | cc = meson.get_compiler('c') 21 | host_system = host_machine.system() 22 | 23 | conf = configuration_data() 24 | conf.set_quoted('PACKAGE_NAME', meson.project_name()) 25 | conf.set_quoted('PACKAGE_VERSION', meson.project_version()) 26 | conf.set_quoted('PACKAGE_STRING', '@0@-@1@'.format(meson.project_name(), meson.project_version())) 27 | conf.set_quoted('PACKAGE_DATADIR', join_paths(get_option('prefix'), get_option('datadir'))) 28 | conf.set_quoted('PACKAGE_LIBDIR', join_paths(get_option('prefix'), get_option('libdir'))) 29 | conf.set_quoted('PACKAGE_LOCALEDIR', join_paths(get_option('prefix'), get_option('datadir'), 'locale')) 30 | conf.set_quoted('PACKAGE_LIBEXECDIR', join_paths(get_option('prefix'), get_option('libexecdir'))) 31 | conf.set('HAVE_KHRPLATFORM_H', cc.has_header('KHR/khrplatform.h', required: false)) 32 | 33 | # GLX can be used on different platforms, so we expose a 34 | # configure time switch to enable or disable it; in case 35 | # the "auto" default value is set, we only enable GLX 36 | # support on Linux and Unix 37 | enable_glx = get_option('enable-glx') 38 | if enable_glx == 'auto' 39 | if host_system == 'windows' 40 | build_glx = false 41 | elif host_system == 'darwin' 42 | build_glx = false 43 | elif host_system == 'android' 44 | build_glx = false 45 | elif host_system == 'haiku' 46 | build_glx = false 47 | else 48 | build_glx = true 49 | endif 50 | elif enable_glx == 'yes' 51 | build_glx = true 52 | elif enable_glx == 'no' 53 | build_glx = false 54 | endif 55 | 56 | enable_egl = get_option('enable-egl') 57 | if enable_egl == 'auto' 58 | if host_system == 'windows' 59 | build_egl = false 60 | elif host_system == 'darwin' 61 | build_egl = false 62 | elif host_system == 'android' 63 | build_egl = true 64 | else 65 | build_egl = true 66 | endif 67 | elif enable_egl == 'yes' 68 | build_egl = true 69 | elif enable_egl == 'no' 70 | build_egl = false 71 | endif 72 | 73 | # The remaining platform specific API for GL/GLES are enabled 74 | # depending on the platform we're building for 75 | if host_system == 'windows' 76 | build_apple = false 77 | build_wgl = true 78 | has_znow = true 79 | elif host_system == 'darwin' 80 | build_apple = true 81 | build_wgl = false 82 | has_znow = false 83 | else 84 | build_apple = false 85 | build_wgl = false 86 | has_znow = true 87 | endif 88 | 89 | conf.set10('ENABLE_GLX', build_glx) 90 | conf.set10('ENABLE_EGL', build_egl) 91 | 92 | # Compiler flags, taken from the Xorg macros 93 | if cc.get_id() == 'msvc' 94 | # Compiler options taken from msvc_recommended_pragmas.h 95 | # in GLib, based on _Win32_Programming_ by Rector and Newcomer 96 | test_cflags = [ 97 | '-we4002', # too many actual parameters for macro 98 | '-we4003', # not enough actual parameters for macro 99 | '-w14010', # single-line comment contains line-continuation character 100 | '-we4013', # 'function' undefined; assuming extern returning int 101 | '-w14016', # no function return type; using int as default 102 | '-we4020', # too many actual parameters 103 | '-we4021', # too few actual parameters 104 | '-we4027', # function declared without formal parameter list 105 | '-we4029', # declared formal parameter list different from definition 106 | '-we4033', # 'function' must return a value 107 | '-we4035', # 'function' : no return value 108 | '-we4045', # array bounds overflow 109 | '-we4047', # different levels of indirection 110 | '-we4049', # terminating line number emission 111 | '-we4053', # an expression of type void was used as an operand 112 | '-we4071', # no function prototype given 113 | '-we4819', # the file contains a character that cannot be represented in the current code page 114 | ] 115 | elif cc.get_id() == 'gcc' or cc.get_id() == 'clang' 116 | test_cflags = [ 117 | '-Wpointer-arith', 118 | '-Wmissing-declarations', 119 | '-Wformat=2', 120 | '-Wstrict-prototypes', 121 | '-Wmissing-prototypes', 122 | '-Wnested-externs', 123 | '-Wbad-function-cast', 124 | '-Wold-style-definition', 125 | '-Wdeclaration-after-statement', 126 | '-Wunused', 127 | '-Wuninitialized', 128 | '-Wshadow', 129 | '-Wmissing-noreturn', 130 | '-Wmissing-format-attribute', 131 | '-Wredundant-decls', 132 | '-Wlogical-op', 133 | '-Werror=implicit', 134 | '-Werror=nonnull', 135 | '-Werror=init-self', 136 | '-Werror=main', 137 | '-Werror=missing-braces', 138 | '-Werror=sequence-point', 139 | '-Werror=return-type', 140 | '-Werror=trigraphs', 141 | '-Werror=array-bounds', 142 | '-Werror=write-strings', 143 | '-Werror=address', 144 | '-Werror=int-to-pointer-cast', 145 | '-Werror=pointer-to-int-cast', 146 | '-fno-strict-aliasing', 147 | '-Wno-int-conversion', 148 | ] 149 | else 150 | test_cflags = [] 151 | endif 152 | 153 | common_cflags = [] 154 | foreach cflag: test_cflags 155 | if cc.has_argument(cflag) 156 | common_cflags += cflag 157 | endif 158 | endforeach 159 | 160 | libtype = get_option('default_library') 161 | 162 | # Visibility compiler flags; we only use this for shared libraries 163 | visibility_cflags = [] 164 | if libtype == 'shared' 165 | if host_system == 'windows' 166 | conf.set('DLL_EXPORT', true) 167 | conf.set('EPOXY_PUBLIC', '__declspec(dllexport) extern') 168 | if cc.get_id() != 'msvc' 169 | visibility_cflags += [ '-fvisibility=hidden' ] 170 | endif 171 | else 172 | conf.set('EPOXY_PUBLIC', '__attribute__((visibility("default"))) extern') 173 | visibility_cflags += [ '-fvisibility=hidden' ] 174 | endif 175 | endif 176 | 177 | # The inline keyword is available only for C++ in MSVC. 178 | # So we need to use Microsoft specific __inline. 179 | if host_system == 'windows' 180 | if cc.get_id() == 'msvc' 181 | conf.set('inline', '__inline') 182 | endif 183 | endif 184 | 185 | # Dependencies 186 | dl_dep = cc.find_library('dl', required: false) 187 | gl_dep = dependency('gl', required: false) 188 | egl_dep = dependency('egl', required: false) 189 | 190 | # Optional dependencies for tests 191 | x11_dep = dependency('x11', required: false) 192 | 193 | # GLES v2 and v1 may have pkg-config files, courtesy of downstream 194 | # packagers; let's check those first, and fall back to find_library() 195 | # if we fail 196 | gles2_dep = dependency('glesv2', required: false) 197 | if not gles2_dep.found() 198 | gles2_dep = cc.find_library('libGLESv2', required: false) 199 | endif 200 | 201 | gles1_dep = dependency('glesv1_cm', required: false) 202 | if not gles1_dep.found() 203 | gles1_dep = cc.find_library('libGLESv1_CM', required: false) 204 | endif 205 | 206 | # On windows, the DLL has to have all of its functions 207 | # resolved at link time, so we have to link directly aginst 208 | # opengl32. But that's the only GL provider, anyway. 209 | if host_system == 'windows' 210 | opengl32_dep = cc.find_library('opengl32', required: true) 211 | 212 | # When building against static libraries, we need to control 213 | # the order of the dependencies, and gdi32 provides symbols 214 | # needed when using opengl32, like SetPixelFormat and 215 | # ChoosePixelFormat. This is mostly a workaround for older 216 | # versions of Meson. 217 | gdi32_dep = cc.find_library('gdi32', required: true) 218 | endif 219 | 220 | # PkgConfig file 221 | pkgconf = configuration_data() 222 | pkgconf.set('prefix', epoxy_prefix) 223 | pkgconf.set('exec_prefix', epoxy_prefix) 224 | pkgconf.set('libdir', epoxy_libdir) 225 | pkgconf.set('includedir', epoxy_includedir) 226 | pkgconf.set10('epoxy_has_glx', build_glx) 227 | pkgconf.set10('epoxy_has_egl', build_egl) 228 | pkgconf.set10('epoxy_has_wgl', build_wgl) 229 | pkgconf.set('PACKAGE_VERSION', meson.project_version()) 230 | if dl_dep.found() 231 | pkgconf.set('DLOPEN_LIBS', '-ldl') 232 | endif 233 | 234 | configure_file(input: 'epoxy.pc.in', 235 | output: 'epoxy.pc', 236 | configuration: pkgconf, 237 | install: true, 238 | install_dir: join_paths(epoxy_libdir, 'pkgconfig')) 239 | 240 | # Python 241 | python = import('python3').find_python() 242 | if not python.found() 243 | python = find_program('python', required: true) 244 | endif 245 | 246 | # Generates the dispatch tables 247 | gen_dispatch_py = files('src/gen_dispatch.py') 248 | 249 | gl_registry = files('registry/gl.xml') 250 | egl_registry = files('registry/egl.xml') 251 | glx_registry = files('registry/glx.xml') 252 | wgl_registry = files('registry/wgl.xml') 253 | 254 | libepoxy_inc = [ 255 | include_directories('include'), 256 | include_directories('src'), 257 | ] 258 | 259 | subdir('include/epoxy') 260 | subdir('src') 261 | subdir('test') 262 | 263 | if get_option('enable-docs') 264 | doxygen = find_program('doxygen', required: false) 265 | if doxygen.found() 266 | subdir('doc') 267 | else 268 | message('Documentation disabled without doxygen') 269 | endif 270 | endif 271 | -------------------------------------------------------------------------------- /test/dlwrap.c: -------------------------------------------------------------------------------- 1 | /* Copyright © 2013, Intel Corporation 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | * THE SOFTWARE. 20 | */ 21 | 22 | /** @file dlwrap.c 23 | * 24 | * Implements a wrapper for dlopen() and dlsym() so that epoxy will 25 | * end up finding symbols from the testcases named 26 | * "override_EGL_eglWhatever()" or "override_GLES2_glWhatever()" or 27 | * "override_GL_glWhatever()" when it tries to dlopen() and dlsym() 28 | * the real GL or EGL functions in question. 29 | * 30 | * This lets us simulate some target systems in the test suite, or 31 | * just stub out GL functions so we can be sure of what's being 32 | * called. 33 | */ 34 | 35 | /* dladdr is a glibc extension */ 36 | #define _GNU_SOURCE 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include "dlwrap.h" 46 | 47 | #define STRNCMP_LITERAL(var, literal) \ 48 | strncmp ((var), (literal), sizeof (literal) - 1) 49 | 50 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) 51 | 52 | void *libfips_handle; 53 | 54 | typedef void *(*fips_dlopen_t)(const char *filename, int flag); 55 | typedef void *(*fips_dlsym_t)(void *handle, const char *symbol); 56 | 57 | void *override_EGL_eglGetProcAddress(const char *name); 58 | void *override_GL_glXGetProcAddress(const char *name); 59 | void *override_GL_glXGetProcAddressARB(const char *name); 60 | void __dlclose(void *handle); 61 | 62 | static struct libwrap { 63 | const char *filename; 64 | const char *symbol_prefix; 65 | void *handle; 66 | } wrapped_libs[] = { 67 | { "libGL.so", "GL", NULL }, 68 | { "libEGL.so", "EGL", NULL }, 69 | { "libGLESv2.so", "GLES2", NULL }, 70 | }; 71 | 72 | /* Match 'filename' against an internal list of libraries for which 73 | * libfips has wrappers. 74 | * 75 | * Returns true and sets *index_ret if a match is found. 76 | * Returns false if no match is found. */ 77 | static struct libwrap * 78 | find_wrapped_library(const char *filename) 79 | { 80 | unsigned i; 81 | 82 | if (!filename) 83 | return NULL; 84 | 85 | for (i = 0; i < ARRAY_SIZE(wrapped_libs); i++) { 86 | if (strncmp(wrapped_libs[i].filename, filename, 87 | strlen(wrapped_libs[i].filename)) == 0) { 88 | return &wrapped_libs[i]; 89 | } 90 | } 91 | 92 | return NULL; 93 | } 94 | 95 | /* Many (most?) OpenGL programs dlopen libGL.so.1 rather than linking 96 | * against it directly, which means they would not be seeing our 97 | * wrapped GL symbols via LD_PRELOAD. So we catch the dlopen in a 98 | * wrapper here and redirect it to our library. 99 | */ 100 | void * 101 | dlopen(const char *filename, int flag) 102 | { 103 | void *ret; 104 | struct libwrap *wrap; 105 | 106 | /* Before deciding whether to redirect this dlopen to our own 107 | * library, we call the real dlopen. This assures that any 108 | * expected side-effects from loading the intended library are 109 | * resolved. Below, we may still return a handle pointing to 110 | * our own library, and not what is opened here. */ 111 | ret = dlwrap_real_dlopen(filename, flag); 112 | 113 | /* If filename is not a wrapped library, just return real dlopen */ 114 | wrap = find_wrapped_library(filename); 115 | if (!wrap) 116 | return ret; 117 | 118 | wrap->handle = ret; 119 | 120 | /* We use wrapped_libs as our handles to libraries. */ 121 | return wrap; 122 | } 123 | 124 | /** 125 | * Wraps dlclose to hide our faked handles from it. 126 | */ 127 | void 128 | __dlclose(void *handle) 129 | { 130 | struct libwrap *wrap = handle; 131 | 132 | if (wrap < wrapped_libs || 133 | wrap >= wrapped_libs + ARRAY_SIZE(wrapped_libs)) { 134 | void (*real_dlclose)(void *handle) = dlwrap_real_dlsym(RTLD_NEXT, "__dlclose"); 135 | real_dlclose(handle); 136 | } 137 | } 138 | 139 | void * 140 | dlwrap_real_dlopen(const char *filename, int flag) 141 | { 142 | static fips_dlopen_t real_dlopen = NULL; 143 | 144 | if (!real_dlopen) { 145 | real_dlopen = (fips_dlopen_t) dlwrap_real_dlsym(RTLD_NEXT, "dlopen"); 146 | if (!real_dlopen) { 147 | fprintf(stderr, "Error: Failed to find symbol for dlopen.\n"); 148 | exit(1); 149 | } 150 | } 151 | 152 | return real_dlopen(filename, flag); 153 | } 154 | 155 | /** 156 | * Return the dlsym() on the application's namespace for 157 | * "override__" 158 | */ 159 | static void * 160 | wrapped_dlsym(const char *prefix, const char *name) 161 | { 162 | char *wrap_name; 163 | void *symbol; 164 | 165 | asprintf(&wrap_name, "override_%s_%s", prefix, name); 166 | symbol = dlwrap_real_dlsym(RTLD_DEFAULT, wrap_name); 167 | free(wrap_name); 168 | return symbol; 169 | } 170 | 171 | /* Since we redirect dlopens of libGL.so and libEGL.so to libfips we 172 | * need to ensure that dlysm succeeds for all functions that might be 173 | * defined in the real, underlying libGL library. But we're far too 174 | * lazy to implement wrappers for function that would simply 175 | * pass-through, so instead we also wrap dlysm and arrange for it to 176 | * pass things through with RTLD_next if libfips does not have the 177 | * function desired. */ 178 | void * 179 | dlsym(void *handle, const char *name) 180 | { 181 | struct libwrap *wrap = handle; 182 | 183 | /* Make sure that handle is actually one of our wrapped libs. */ 184 | if (wrap < wrapped_libs || 185 | wrap >= wrapped_libs + ARRAY_SIZE(wrapped_libs)) { 186 | wrap = NULL; 187 | } 188 | 189 | /* Failing that, anything specifically requested from the 190 | * libfips library should be redirected to a real GL 191 | * library. */ 192 | 193 | if (wrap) { 194 | void *symbol = wrapped_dlsym(wrap->symbol_prefix, name); 195 | if (symbol) 196 | return symbol; 197 | else 198 | return dlwrap_real_dlsym(wrap->handle, name); 199 | } 200 | 201 | /* And anything else is some unrelated dlsym. Just pass it 202 | * through. (This also covers the cases of lookups with 203 | * special handles such as RTLD_DEFAULT or RTLD_NEXT.) 204 | */ 205 | return dlwrap_real_dlsym(handle, name); 206 | } 207 | 208 | void * 209 | dlwrap_real_dlsym(void *handle, const char *name) 210 | { 211 | static fips_dlsym_t real_dlsym = NULL; 212 | 213 | if (!real_dlsym) { 214 | /* FIXME: This brute-force, hard-coded searching for a versioned 215 | * symbol is really ugly. The only reason I'm doing this is because 216 | * I need some way to lookup the "dlsym" function in libdl, but 217 | * I can't use 'dlsym' to do it. So dlvsym works, but forces me 218 | * to guess what the right version is. 219 | * 220 | * Potential fixes here: 221 | * 222 | * 1. Use libelf to actually inspect libdl.so and 223 | * find the right version, (finding the right 224 | * libdl.so can be made easier with 225 | * dl_iterate_phdr). 226 | * 227 | * 2. Use libelf to find the offset of the 'dlsym' 228 | * symbol within libdl.so, (and then add this to 229 | * the base address at which libdl.so is loaded 230 | * as reported by dl_iterate_phdr). 231 | * 232 | * In the meantime, I'll just keep augmenting this 233 | * hard-coded version list as people report bugs. */ 234 | const char *version[] = { 235 | "GLIBC_2.17", 236 | "GLIBC_2.4", 237 | "GLIBC_2.3", 238 | "GLIBC_2.2.5", 239 | "GLIBC_2.2", 240 | "GLIBC_2.0" 241 | }; 242 | int num_versions = sizeof(version) / sizeof(version[0]); 243 | int i; 244 | for (i = 0; i < num_versions; i++) { 245 | real_dlsym = (fips_dlsym_t) dlvsym(RTLD_NEXT, "dlsym", version[i]); 246 | if (real_dlsym) 247 | break; 248 | } 249 | if (i == num_versions) { 250 | fprintf(stderr, "Internal error: Failed to find real dlsym\n"); 251 | fprintf(stderr, 252 | "This may be a simple matter of fips not knowing about the version of GLIBC that\n" 253 | "your program is using. Current known versions are:\n\n\t"); 254 | for (i = 0; i < num_versions; i++) 255 | fprintf(stderr, "%s ", version[i]); 256 | fprintf(stderr, 257 | "\n\nYou can inspect your version by first finding libdl.so.2:\n" 258 | "\n" 259 | "\tldd | grep libdl.so\n" 260 | "\n" 261 | "And then inspecting the version attached to the dlsym symbol:\n" 262 | "\n" 263 | "\treadelf -s /path/to/libdl.so.2 | grep dlsym\n" 264 | "\n" 265 | "And finally, adding the version to dlwrap.c:dlwrap_real_dlsym.\n"); 266 | 267 | exit(1); 268 | } 269 | } 270 | 271 | return real_dlsym(handle, name); 272 | } 273 | 274 | void * 275 | override_GL_glXGetProcAddress(const char *name) 276 | { 277 | void *symbol; 278 | 279 | symbol = wrapped_dlsym("GL", name); 280 | if (symbol) 281 | return symbol; 282 | 283 | return DEFER_TO_GL("libGL.so.1", override_GL_glXGetProcAddress, 284 | "glXGetProcAddress", (name)); 285 | } 286 | 287 | void * 288 | override_GL_glXGetProcAddressARB(const char *name) 289 | { 290 | void *symbol; 291 | 292 | symbol = wrapped_dlsym("GL", name); 293 | if (symbol) 294 | return symbol; 295 | 296 | return DEFER_TO_GL("libGL.so.1", override_GL_glXGetProcAddressARB, 297 | "glXGetProcAddressARB", (name)); 298 | } 299 | 300 | void * 301 | override_EGL_eglGetProcAddress(const char *name) 302 | { 303 | void *symbol; 304 | 305 | if (!STRNCMP_LITERAL(name, "gl")) { 306 | symbol = wrapped_dlsym("GLES2", name); 307 | if (symbol) 308 | return symbol; 309 | } 310 | 311 | if (!STRNCMP_LITERAL(name, "egl")) { 312 | symbol = wrapped_dlsym("EGL", name); 313 | if (symbol) 314 | return symbol; 315 | } 316 | 317 | return DEFER_TO_GL("libEGL.so.1", override_EGL_eglGetProcAddress, 318 | "eglGetProcAddress", (name)); 319 | } 320 | --------------------------------------------------------------------------------