Skip to content

Commit

Permalink
Add support for EGL on Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowNinja authored and Slavomir Kaslev committed Dec 23, 2021
1 parent 3755745 commit ec62d76
Showing 1 changed file with 94 additions and 11 deletions.
105 changes: 94 additions & 11 deletions gl3w_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,31 +253,114 @@ def download(url, dst):
#else
#include <dlfcn.h>
static void *libgl;
static GL3WglProc (*glx_get_proc_address)(const GLubyte *);
static void *libgl; // OpenGL library
static void *libglx; // GLX library
static void *libegl; // EGL library
static GL3WGetProcAddressProc gl_get_proc_address;
static int open_libgl(void)
static void close_libgl(void)
{
if (libgl) {
dlclose(libgl);
libgl = NULL;
}
if (libegl) {
dlclose(libegl);
libegl = NULL;
}
if (libglx) {
dlclose(libglx);
libglx = NULL;
}
}
static int is_library_loaded(const char *name, void **lib)
{
*lib = dlopen(name, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
return *lib != NULL;
}
static int open_libs(void)
{
// On Linux we have two APIs to get process addresses: EGL and GLX.
// EGL is supported under both X11 and Wayland, whereas GLX is X11-specific.
libgl = NULL;
libegl = NULL;
libglx = NULL;
// First check what's already loaded, the windowing library might have
// already loaded either EGL or GLX and we want to use the same one.
if (is_library_loaded("libEGL.so.1", &libegl) ||
is_library_loaded("libGLX.so.0", &libglx)) {
libgl = dlopen("libOpenGL.so.0", RTLD_LAZY | RTLD_LOCAL);
if (libgl)
return GL3W_OK;
else
close_libgl();
}
if (is_library_loaded("libGL.so.1", &libgl))
return GL3W_OK;
// Neither is already loaded, so we have to load one. Try EGL first
// because it is supported under both X11 and Wayland.
// Load OpenGL + EGL
libgl = dlopen("libOpenGL.so.0", RTLD_LAZY | RTLD_LOCAL);
libegl = dlopen("libEGL.so.1", RTLD_LAZY | RTLD_LOCAL);
if (libgl && libegl)
return GL3W_OK;
else
close_libgl();
// Fall back to legacy libGL, which includes GLX
libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
if (!libgl)
return GL3W_ERROR_LIBRARY_OPEN;
if (libgl)
return GL3W_OK;
*(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
return GL3W_OK;
return GL3W_ERROR_LIBRARY_OPEN;
}
static void close_libgl(void)
static int open_libgl(void)
{
dlclose(libgl);
int res = open_libs();
if (res)
return res;
if (libegl)
*(void **)(&gl_get_proc_address) = dlsym(libegl, "eglGetProcAddress");
else if (libglx)
*(void **)(&gl_get_proc_address) = dlsym(libglx, "glXGetProcAddressARB");
else
*(void **)(&gl_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
if (!gl_get_proc_address) {
close_libgl();
return GL3W_ERROR_LIBRARY_OPEN;
}
return GL3W_OK;
}
static GL3WglProc get_proc(const char *proc)
{
GL3WglProc res;
GL3WglProc res = NULL;
// Before EGL version 1.5, eglGetProcAddress doesn't support querying core
// functions and may return a dummy function if we try, so try to load the
// function from the GL library directly first.
if (libegl)
*(void **)(&res) = dlsym(libgl, proc);
res = glx_get_proc_address((const GLubyte *)proc);
if (!res)
res = gl_get_proc_address(proc);
if (!libegl && !res)
*(void **)(&res) = dlsym(libgl, proc);
return res;
}
#endif
Expand Down

0 comments on commit ec62d76

Please sign in to comment.