From 1064406814190cfa1f95ba01d08f87596065ac7e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 31 Jan 2014 14:49:00 -0800 Subject: [PATCH] Fix using epoxy on systems with only EGL and GLES1 or GLES2. Fixes #19 --- src/dispatch_common.c | 70 ++++++++++++++++++++++++++++++++++++++++++- src/dispatch_common.h | 1 + src/gen_dispatch.py | 4 +-- test/Makefile.am | 2 -- 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/dispatch_common.c b/src/dispatch_common.c index 289694a..b85e0cc 100644 --- a/src/dispatch_common.c +++ b/src/dispatch_common.c @@ -1,5 +1,5 @@ /* - * Copyright © 2013 Intel Corporation + * Copyright © 2013-2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -381,6 +381,10 @@ epoxy_gles2_dlsym(const char *name) return do_dlsym(&api.gles2_handle, "libGLESv2.so.2", name, true); } +/** + * Performs either the dlsym or glXGetProcAddress()-equivalent for + * core functions in desktop GL. + */ void * epoxy_get_core_proc_address(const char *name, int core_version) { @@ -397,6 +401,70 @@ epoxy_get_core_proc_address(const char *name, int core_version) } } +/** + * Performs the dlsym() for the core GL 1.0 functions that we use for + * determining version and extension support for deciding on dlsym + * versus glXGetProcAddress() for all other functions. + * + * This needs to succeed on implementations without GLX (since + * glGetString() and glGetIntegerv() are both in GLES1/2 as well, and + * at call time we don't know for sure what API they're trying to use + * without inspecting contexts ourselves). + */ +void * +epoxy_get_bootstrap_proc_address(const char *name) +{ + /* If we already have a library that links to libglapi loaded, + * use that. + */ + if (api.glx_handle) + return epoxy_gl_dlsym(name); + if (api.gles2_handle) + return epoxy_gles2_dlsym(name); + if (api.gles1_handle) + return epoxy_gles1_dlsym(name); + + /* If epoxy hasn't loaded any API-specific library yet, try to + * figure out what API the context is using and use that library, + * since future calls will also use that API (this prevents a + * non-X11 ES2 context from loading a bunch of X11 junk). + */ +#if PLATFORM_HAS_EGL + get_dlopen_handle(&api.egl_handle, "libEGL.so.1", false); + if (api.egl_handle) { + EGLenum save_api = eglQueryAPI(); + EGLContext ctx; + + eglBindAPI(EGL_OPENGL_API); + ctx = eglGetCurrentContext(); + if (ctx) { + eglBindAPI(save_api); + return epoxy_gl_dlsym(name); + } + + eglBindAPI(EGL_OPENGL_ES_API); + ctx = eglGetCurrentContext(); + if (ctx) { + eglBindAPI(save_api); + /* We can't resolve the GL version, because + * epoxy_glGetString() is one of the two things calling + * us. Try the GLES2 implementation first, and fall back + * to GLES1 otherwise. + */ + get_dlopen_handle(&api.gles2_handle, "libGLESv2.so.2", false); + if (api.gles2_handle) + return epoxy_gles2_dlsym(name); + else + return epoxy_gles1_dlsym(name); + } + eglBindAPI(save_api); + } +#endif /* PLATFORM_HAS_EGL */ + + /* Fall back to GLX */ + return epoxy_gl_dlsym(name); +} + void * epoxy_get_proc_address(const char *name) { diff --git a/src/dispatch_common.h b/src/dispatch_common.h index 1274b49..a70753a 100644 --- a/src/dispatch_common.h +++ b/src/dispatch_common.h @@ -80,6 +80,7 @@ void *epoxy_gles1_dlsym(const char *name); void *epoxy_gles2_dlsym(const char *name); void *epoxy_get_proc_address(const char *name); void *epoxy_get_core_proc_address(const char *name, int core_version); +void *epoxy_get_bootstrap_proc_address(const char *name); int epoxy_conservative_gl_version(void); bool epoxy_conservative_has_gl_extension(const char *name); diff --git a/src/gen_dispatch.py b/src/gen_dispatch.py index 6172756..abf7e3a 100755 --- a/src/gen_dispatch.py +++ b/src/gen_dispatch.py @@ -847,9 +847,9 @@ for file in args.files: generator.sort_functions() generator.resolve_aliases() generator.fixup_bootstrap_function('glGetString', - 'epoxy_get_core_proc_address({0}, 10)') + 'epoxy_get_bootstrap_proc_address({0})') generator.fixup_bootstrap_function('glGetIntegerv', - 'epoxy_get_core_proc_address({0}, 10)') + 'epoxy_get_bootstrap_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 diff --git a/test/Makefile.am b/test/Makefile.am index 7f43f26..5fa4487 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -57,8 +57,6 @@ TESTS = \ $() XFAIL_TESTS = \ - egl_gles1_without_glx \ - egl_gles2_without_glx \ $() check_PROGRAMS = $(TESTS)