Add support for EGL.

This totally replaces the getprocaddress and dlsym code, which was
basically just stubs up until now.  The is_glx/is_egl() is also
dropped -- they weren't doing anything, and the only false answer they
could give is if the dlopen were to fail.
macos/v1.5.9
Eric Anholt 11 years ago
parent 111c54992b
commit 0270c80008
  1. 4
      .gitignore
  2. 63
      include/epoxy/egl.h
  3. 24
      src/Makefile.am
  4. 185
      src/dispatch_common.c
  5. 27
      src/dispatch_common.h
  6. 68
      src/gen_dispatch.py
  7. 14
      test/Makefile.am
  8. 50
      test/egl_common.c
  9. 25
      test/egl_common.h
  10. 70
      test/egl_has_extension_nocontext.c
  11. 3
      test/headerguards.c

4
.gitignore vendored

@ -89,3 +89,7 @@ gl_generated_vtable_defines.h
glx_generated_dispatch.c
glx_generated.h
glx_generated_vtable_defines.h
egl_generated_dispatch.c
egl_generated.h
egl_generated_vtable_defines.h

@ -0,0 +1,63 @@
/*
* Copyright © 2013 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** @file egl.h
*
* Provides an implementation of a EGL dispatch layer using a hidden
* vtable.
*
* This is a lower performance path than ifuncs when they are
* available, but it is required if you might have multiple return
* values for GetProcAddress/dlsym()ed functions (for example, if you
* unload libGL.so.1).
*/
#ifndef __EPOXY_EGL_H
#define __EPOXY_EGL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#if defined(__egl_h_) || defined(__eglext_h_)
#error epoxy/egl.h must be included before (or in place of) GL/egl.h
#else
#define __egl_h_
#define __eglext_h_
#endif
#pragma once
#include "epoxy/egl_generated.h"
#include "epoxy/egl_generated_vtable_defines.h"
bool epoxy_has_egl_extension(EGLDisplay *dpy, const char *extension);
int epoxy_egl_version(EGLDisplay *dpy);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __EPOXY_EGL_H */

@ -31,6 +31,7 @@ lib_LTLIBRARIES = libepoxy.la
epoxyinclude_DATA = \
$(GL_INCLUDES) \
$(GLX_INCLUDES) \
$(EGL_INCLUDES) \
$()
GL_INCLUDES = \
@ -43,6 +44,11 @@ GLX_INCLUDES = \
$(GENERATED_GLX_INCLUDES) \
$()
EGL_INCLUDES = \
../include/epoxy/egl.h \
$(GENERATED_EGL_INCLUDES) \
$()
GENERATED_GL_INCLUDES = \
$(builddir)/../include/epoxy/gl_generated.h \
$(builddir)/../include/epoxy/gl_generated_vtable_defines.h \
@ -53,6 +59,11 @@ GENERATED_GLX_INCLUDES = \
$(builddir)/../include/epoxy/glx_generated_vtable_defines.h \
$()
GENERATED_EGL_INCLUDES = \
$(tuilddir)/../include/epoxy/egl_generated.h \
$(builddir)/../include/epoxy/egl_generated_vtable_defines.h \
$()
GENERATED_GL_SOURCE = gl_generated_dispatch.c
GENERATED_GL = \
@ -67,9 +78,17 @@ GENERATED_GLX = \
$(GENERATED_GLX_INCLUDES) \
$()
GENERATED_EGL_SOURCE = egl_generated_dispatch.c
GENERATED_EGL = \
$(GENERATED_EGL_SOURCE) \
$(GENERATED_EGL_INCLUDES) \
$()
BUILT_SOURCES = \
$(GENERATED_GL) \
$(GENERATED_GLX) \
$(GENERATED_EGL) \
$()
CLEANFILES = $(BUILT_SOURCES)
@ -82,6 +101,7 @@ libepoxy_la_SOURCES = \
# These are generated alongside the .c file.
$(GENERATED_GL_INCLUDES): $(GENERATED_GL_SOURCE)
$(GENERATED_GLX_INCLUDES): $(GENERATED_GLX_SOURCE)
$(GENERATED_EGL_INCLUDES): $(GENERATED_EGL_SOURCE)
$(GENERATED_GL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/gl.xml
$(MKDIR_P) $(top_builddir)/include/epoxy
@ -90,3 +110,7 @@ $(GENERATED_GL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/gl.xml
$(GENERATED_GLX_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/glx.xml
$(MKDIR_P) $(top_builddir)/include/epoxy
$(AM_V_GEN)$(PYTHON) $(srcdir)/gen_dispatch.py --dir $(top_builddir) $(top_srcdir)/registry/glx.xml
$(GENERATED_EGL_SOURCE): $(srcdir)/gen_dispatch.py $(top_srcdir)/registry/egl.xml
$(MKDIR_P) $(top_builddir)/include/epoxy
$(AM_V_GEN)$(PYTHON) $(srcdir)/gen_dispatch.py --dir $(top_builddir) $(top_srcdir)/registry/egl.xml

@ -93,14 +93,67 @@
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <pthread.h>
#include <err.h>
#include "epoxy/gl.h"
#include "epoxy/glx.h"
#include "epoxy/egl.h"
#include "dispatch_common.h"
/* XXX: Make this thread local */
struct api local_api;
struct api {
/**
* Locking for making sure we don't double-dlopen().
*/
pthread_mutex_t mutex;
/** dlopen() return value for libGL.so.1. */
void *glx_handle;
/** dlopen() return value for libEGL.so.1 */
void *egl_handle;
/** dlopen() return value for libGLESv1_CM.so.1 */
void *gles1_handle;
/** dlopen() return value for libGLESv2.so.2 */
void *gles2_handle;
};
static struct api api = {
.mutex = PTHREAD_MUTEX_INITIALIZER,
};
static void
get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail)
{
if (*handle)
return;
pthread_mutex_lock(&api.mutex);
if (!*handle) {
*handle = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
if (!*handle && exit_on_fail) {
fprintf(stderr, "Couldn't open %s: %s", lib_name, dlerror());
exit(1);
}
}
pthread_mutex_unlock(&api.mutex);
}
static void *
do_dlsym(void **handle, const char *lib_name, const char *name,
bool exit_on_fail)
{
void *result;
get_dlopen_handle(handle, lib_name, exit_on_fail);
struct api *api = &local_api;
result = dlsym(*handle, name);
if (!result)
errx(1, "%s() not found in %s", name, lib_name);
return result;
}
PUBLIC bool
epoxy_is_desktop_gl(void)
@ -132,12 +185,6 @@ epoxy_gl_version(void)
return 10 * major + minor;
}
PUBLIC bool
epoxy_is_glx(void)
{
return true; /* XXX */
}
/**
* If we can determine the GLX version from the current context, then
* return that, otherwise return a version that will just send us on
@ -183,6 +230,30 @@ epoxy_glx_version(Display *dpy, int screen)
return server;
}
PUBLIC int
epoxy_conservative_egl_version(void)
{
EGLDisplay *dpy = eglGetCurrentDisplay();
if (!dpy)
return 14;
return epoxy_egl_version(dpy);
}
PUBLIC int
epoxy_egl_version(EGLDisplay *dpy)
{
int major, minor;
const char *version_string;
int ret;
version_string = eglQueryString(dpy, EGL_VERSION);
ret = sscanf(version_string, "%d.%d", &major, &minor);
assert(ret == 2);
return major * 10 + minor;
}
static bool
epoxy_extension_in_string(const char *extension_list, const char *ext)
{
@ -204,13 +275,22 @@ epoxy_has_gl_extension(const char *ext)
ext);
}
#if 0
bool
epoxy_conservative_has_egl_extension(const char *ext)
{
EGLDisplay *dpy = eglGetCurrentDisplay();
if (!dpy)
return true;
return epoxy_has_egl_extension(dpy, ext);
}
PUBLIC bool
epoxy_has_egl_extension(const char *ext)
epoxy_has_egl_extension(EGLDisplay *dpy, const char *ext)
{
return epoxy_extension_in_string(eglQueryString(EGL_EXTENSIONS), ext);
return epoxy_extension_in_string(eglQueryString(dpy, EGL_EXTENSIONS), ext);
}
#endif
/**
* If we can determine the GLX extension support from the current
@ -234,7 +314,7 @@ epoxy_conservative_has_glx_extension(const char *ext)
PUBLIC bool
epoxy_has_glx_extension(Display *dpy, int screen, const char *ext)
{
{
/* No, you can't just use glXGetClientString or
* glXGetServerString() here. Those each tell you about one half
* of what's needed for an extension to be supported, and
@ -245,37 +325,78 @@ epoxy_has_glx_extension(Display *dpy, int screen, const char *ext)
}
void *
epoxy_dlsym(const char *name)
epoxy_egl_dlsym(const char *name)
{
assert(api->gl_handle);
return dlsym(api->gl_handle, name);
return do_dlsym(&api.egl_handle, "libEGL.so.1", name, true);
}
void *
epoxy_get_proc_address(const char *name)
epoxy_glx_dlsym(const char *name)
{
return glXGetProcAddress((const GLubyte *)name);
return do_dlsym(&api.glx_handle, "libGL.so.1", name, true);
}
void
epoxy_glx_autoinit(void)
void *
epoxy_gl_dlsym(const char *name)
{
if (api->gl_handle)
return;
/* There's no library for desktop GL support independent of GLX. */
return epoxy_glx_dlsym(name);
}
api->gl_handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
if (!api->gl_handle) {
fprintf(stderr, "Couldn't open libGL.so.1: %s", dlerror());
exit(1);
}
void *
epoxy_gles1_dlsym(const char *name)
{
return do_dlsym(&api.gles1_handle, "libGLESv1_CM.so.1", name, true);
}
api->winsys_handle = api->gl_handle;
void *
epoxy_gles2_dlsym(const char *name)
{
return do_dlsym(&api.gles1_handle, "libGLESv2.so.2", name, true);
}
void
epoxy_platform_autoinit(void)
void *
epoxy_get_proc_address(const char *name)
{
epoxy_glx_autoinit();
if (api.egl_handle) {
return eglGetProcAddress(name);
} else if (api.glx_handle) {
return glXGetProcAddressARB((const GLubyte *)name);
} else {
/* If the application hasn't explicitly called some of our GLX
* or EGL code but has presumably set up a context on its own,
* then we need to figure out how to getprocaddress anyway.
*
* If there's a public GetProcAddress loaded in the
* application's namespace, then use that.
*/
PFNGLXGETPROCADDRESSARBPROC glx_gpa;
PFNEGLGETPROCADDRESSPROC egl_gpa;
egl_gpa = dlsym(NULL, "eglGetProcAddress");
if (egl_gpa)
return egl_gpa(name);
glx_gpa = dlsym(NULL, "glXGetProcAddressARB");
if (glx_gpa)
return glx_gpa((const GLubyte *)name);
/* OK, couldn't find anything in the app's address space.
* Presumably they dlopened with RTLD_LOCAL, which hides it
* from us. Just go dlopen()ing likely libraries and try them.
*/
egl_gpa = do_dlsym(&api.egl_handle, "libEGL.so.1", "eglGetProcAddress",
false);
if (egl_gpa)
return egl_gpa(name);
return do_dlsym(&api.glx_handle, "libGL.so.1", "glXGetProcAddressARB",
false);
if (glx_gpa)
return glx_gpa((const GLubyte *)name);
errx(1, "Couldn't find GLX or EGL libraries.\n");
}
}
void

@ -23,6 +23,7 @@
#include <stdbool.h>
#include "epoxy/gl.h"
#include "epoxy/egl.h"
#include "epoxy/glx.h"
#ifndef PUBLIC
@ -33,27 +34,17 @@
# endif
#endif
struct api {
bool is_glx;
bool is_gl;
bool is_gles1;
bool is_gles2; /**< Also GLES3 */
/** dlopen() return value for libGL.so.1, libGLESv2.so.1, etc. */
void *gl_handle;
/** dlopen() return value for libGL.so.1 or libEGL.so.1 */
void *winsys_handle;
};
bool epoxy_is_glx(void);
void *epoxy_egl_dlsym(const char *name);
void *epoxy_glx_dlsym(const char *name);
void *epoxy_gl_dlsym(const char *name);
void *epoxy_gles1_dlsym(const char *name);
void *epoxy_gles2_dlsym(const char *name);
void *epoxy_get_proc_address(const char *name);
int epoxy_conservative_glx_version(void);
bool epoxy_conservative_has_glx_extension(const char *name);
void *epoxy_dlsym(const char *name);
void epoxy_glx_autoinit(void);
void epoxy_platform_autoinit(void);
int epoxy_conservative_egl_version(void);
bool epoxy_conservative_has_egl_extension(const char *name);
void epoxy_print_failure_reasons(const char *name,
const char **provider_names,
const int *providers);

@ -116,9 +116,6 @@ class Generator(object):
self.typedefs = ''
self.out_file = None
self.dlsym_loader = 'epoxy_dlsym({0})'
self.gpa_loader = 'epoxy_get_proc_address({0})'
# Dictionary mapping human-readable names of providers to a C
# enum token that will be used to reference those names, to
# reduce generated binary size.
@ -266,36 +263,41 @@ class Generator(object):
# else is supposed to not be present, so you have to
# glXGetProcAddress() it.
if version <= 12:
loader = self.dlsym_loader
loader = 'epoxy_gl_dlsym({0})'
else:
loader = self.gpa_loader
loader = 'epoxy_get_proc_address({0})'
condition += ' && epoxy_gl_version() >= {0}'.format(version)
elif api == 'gles2':
human_name = 'OpenGL ES {0}'.format(feature.get('number'))
condition = '!epoxy_is_desktop_gl() && epoxy_gl_version() >= {0}'.format(version)
if version <= 20:
loader = self.dlsym_loader
loader = 'epoxy_gles2_dlsym({0})'
else:
loader = self.gpa_loader
loader = 'epoxy_get_proc_address({0})'
elif api == 'gles1':
human_name = 'OpenGL ES 1.0'
condition = '!epoxy_is_desktop_gl() && epoxy_gl_version() == 10'
if version <= 20:
loader = self.dlsym_loader
else:
loader = self.gpa_loader
loader = 'epoxy_gles1_dlsym({0})'
elif api == 'glx':
human_name = 'GLX {0}'.format(version)
condition = 'epoxy_is_glx()'
# We could just always use GPA, but dlsym() is a more
# We could just always use GPA for loading everything
# but glXGetProcAddress(), but dlsym() is a more
# efficient lookup.
if version > 13:
condition = condition + ' && epoxy_conservative_glx_version() >= {0}'.format(version)
loader = self.gpa_loader
condition = 'epoxy_conservative_glx_version() >= {0}'.format(version)
loader = 'glXGetProcAddress((const GLubyte *){0})'
else:
condition = 'true'
loader = 'epoxy_glx_dlsym({0})'
elif api == 'egl':
human_name = 'EGL {0}'.format(version)
if version > 10:
condition = 'epoxy_conservative_egl_version() >= {0}'.format(version)
loader = 'eglGetProcAddress({0})'
else:
loader = self.dlsym_loader
condition = 'true'
loader = 'epoxy_egl_dlsym({0})'
else:
sys.exit('unknown API: "{0}"'.format(api))
@ -309,15 +311,20 @@ class Generator(object):
if 'glx' in apis:
human_name = 'GLX extension \\"{0}\\"'.format(extname)
condition = 'epoxy_conservative_has_glx_extension("{0}")'.format(extname)
loader = self.gpa_loader
loader = 'glXGetProcAddress((const GLubyte *){0})'
self.process_require_statements(extension, condition, loader, human_name)
if 'egl' in apis:
human_name = 'EGL extension \\"{0}\\"'.format(extname)
condition = 'epoxy_conservative_has_egl_extension("{0}")'.format(extname)
loader = 'eglGetProcAddress({0})'
self.process_require_statements(extension, condition, loader, human_name)
if 'gl' in apis:
human_name = 'GL extension \\"{0}\\"'.format(extname)
condition = 'epoxy_has_gl_extension("{0}")'.format(extname)
loader = self.gpa_loader
loader = 'epoxy_get_proc_address({0})'
self.process_require_statements(extension, condition, loader, human_name)
def fixup_bootstrap_function(self, name):
def fixup_bootstrap_function(self, name, loader):
# We handle glGetString() and glGetIntegerv() specially, because we
# need to use them in the process of deciding on loaders for
# resolving, and the naive code generation would result in their
@ -327,7 +334,7 @@ class Generator(object):
func = self.functions[name]
func.providers = {}
func.add_provider('true', self.dlsym_loader, 'always present')
func.add_provider('true', loader, 'always present')
def parse(self, file):
reg = ET.parse(file)
@ -375,6 +382,8 @@ class Generator(object):
if self.target != "gl":
self.outln('#include "epoxy/gl_generated.h"')
if self.target == "egl":
self.outln('#include "EGL/eglplatform.h"')
else:
# Add some ridiculous inttypes.h redefinitions that are from
# khrplatform.h and not included in the XML.
@ -389,6 +398,8 @@ class Generator(object):
self.outln('typedef float khronos_float_t;')
self.outln('typedef intptr_t khronos_intptr_t;')
self.outln('typedef ptrdiff_t khronos_ssize_t;')
self.outln('typedef uint64_t khronos_utime_nanoseconds_t;')
self.outln('typedef int64_t khronos_stime_nanoseconds_t;')
if self.target == "glx":
self.outln('#include <X11/Xlib.h>')
@ -435,12 +446,6 @@ class Generator(object):
self.outln(' "{0}",'.format(provider.name))
self.outln(' };')
if 'glX' in func.name:
self.outln(' epoxy_glx_autoinit();')
else:
self.outln(' epoxy_platform_autoinit();')
self.outln('')
self.outln(' return {0}_provider_resolver("{1}",'.format(self.target, func.name))
self.outln(' providers, entrypoints);')
@ -583,13 +588,16 @@ for file in args.files:
generator.drop_weird_glx_functions()
generator.sort_functions()
generator.resolve_aliases()
generator.fixup_bootstrap_function('glGetString')
generator.fixup_bootstrap_function('glGetIntegerv')
generator.fixup_bootstrap_function('glGetString',
'epoxy_get_proc_address({0})')
generator.fixup_bootstrap_function('glGetIntegerv',
'epoxy_get_proc_address({0})')
# While this is technically exposed as a GLX extension, it's
# required to be present as a public symbol by the Linux OpenGL
# ABI.
generator.fixup_bootstrap_function('glXGetProcAddress')
generator.fixup_bootstrap_function('glXGetProcAddress',
'epoxy_glx_dlsym({0})')
generator.prepare_provider_enum()

@ -20,7 +20,15 @@
EPOXY = $(builddir)/../src/libepoxy.la
check_LTLIBRARIES = libglx_common.la
check_LTLIBRARIES = \
libegl_common.la \
libglx_common.la \
$()
libegl_common_la_SOURCES = \
egl_common.c \
egl_common.h
$()
libglx_common_la_SOURCES = \
glx_common.c \
@ -32,6 +40,7 @@ AM_CPPFLAGS = \
$(X11_CFLAGS)
TESTS = \
egl_has_extension_nocontext \
glx_public_api \
glx_glxgetprocaddress_nocontext \
glx_has_extension_nocontext \
@ -40,6 +49,9 @@ TESTS = \
check_PROGRAMS = $(TESTS)
egl_has_extension_nocontext_LDFLAGS = $(X11_LIBS) $(EPOXY) libegl_common.la
egl_has_extension_nocontext_DEPENDENCIES = libegl_common.la
glx_public_api_LDFLAGS = $(X11_LIBS) $(EPOXY) libglx_common.la
glx_public_api_DEPENDENCIES = libglx_common.la

@ -0,0 +1,50 @@
/*
* Copyright © 2013 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <err.h>
#include <epoxy/egl.h>
/**
* Do whatever it takes to get us an EGL display for the system.
*
* This needs to be ported to other window systems.
*/
EGLDisplay *
get_egl_display_or_skip(void)
{
Display *dpy = XOpenDisplay(NULL);
EGLint major, minor;
if (!dpy)
errx(77, "couldn't open display\n");
EGLDisplay *edpy = eglGetDisplay(dpy);
if (!edpy)
errx(1, "Couldn't get EGL display for X11 Display.\n");
bool ok = eglInitialize(edpy, &major, &minor);
if (!ok)
errx(1, "eglInitialize() failed\n");
return edpy;
}

@ -0,0 +1,25 @@
/*
* Copyright © 2013 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
EGLDisplay *
get_egl_display_or_skip(void);

@ -0,0 +1,70 @@
/*
* Copyright © 2013 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/**
* @file egl_has_extension_nocontext.c
*
* Catches a bug in early development where eglGetProcAddress() with
* no context bound would fail out in dispatch.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <err.h>
#include "epoxy/gl.h"
#include "epoxy/egl.h"
#include "egl_common.h"
int
main(int argc, char **argv)
{
bool pass = true;
EGLDisplay *dpy = get_egl_display_or_skip();
const char *extensions = eglQueryString(dpy, EGL_EXTENSIONS);
char *first_space;
char *an_extension;
/* We don't have any extensions guaranteed by the ABI, so for the
* touch test we just check if the first one is reported to be there.
*/
first_space = strstr(extensions, " ");
if (first_space) {
an_extension = strndup(extensions, first_space - extensions);
} else {
an_extension = strdup(extensions);
}
if (!epoxy_has_egl_extension(dpy, an_extension))
errx(1, "Implementation reported absence of GLX_ARB_get_proc_address");
free(an_extension);
if (epoxy_has_egl_extension(dpy, "GLX_ARB_ham_sandwich"))
errx(1, "Implementation reported presence of GLX_ARB_ham_sandwich");
return pass != true;
}

@ -22,8 +22,11 @@
*/
#include <epoxy/gl.h>
#include <epoxy/egl.h>
#include <epoxy/glx.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glx.h>

Loading…
Cancel
Save