Skip to content

Commit

Permalink
Add API to allow for platform detection
Browse files Browse the repository at this point in the history
On Linux and other Unix variants we may not have access to GLX and EGL
at run time. Dependent libraries can only discover this by using dlsym()
on various symbols, because as soon as they attempt to call those
symbols through Epoxy, Epoxy will abort. This means that a bunch of code
needs to be copy-pasted between projects, with the high chance of
somebody getting it wrong.

Epoxy already has all the internals needed to detect whether GLX and EGL
are available, so exposing a simple API is a better alternative.

Fixes #73
  • Loading branch information
ebassi committed Feb 6, 2017
2 parents ec93dcd + 075172f commit 7782509
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/epoxy/egl.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ EPOXY_BEGIN_DECLS

EPOXY_PUBLIC bool epoxy_has_egl_extension(EGLDisplay dpy, const char *extension);
EPOXY_PUBLIC int epoxy_egl_version(EGLDisplay dpy);
EPOXY_PUBLIC bool epoxy_has_egl(void);

EPOXY_END_DECLS

Expand Down
1 change: 1 addition & 0 deletions include/epoxy/glx.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ EPOXY_BEGIN_DECLS

EPOXY_PUBLIC bool epoxy_has_glx_extension(Display *dpy, int screen, const char *extension);
EPOXY_PUBLIC int epoxy_glx_version(Display *dpy, int screen);
EPOXY_PUBLIC bool epoxy_has_glx(Display *dpy);

EPOXY_END_DECLS

Expand Down
16 changes: 14 additions & 2 deletions src/dispatch_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,16 +568,28 @@ epoxy_conservative_has_gl_extension(const char *ext)
return epoxy_internal_has_gl_extension(ext, true);
}

void *
epoxy_conservative_egl_dlsym(const char *name, bool exit_if_fails)
{
return do_dlsym(&api.egl_handle, EGL_LIB, name, exit_if_fails);
}

void *
epoxy_egl_dlsym(const char *name)
{
return do_dlsym(&api.egl_handle, EGL_LIB, name, true);
return epoxy_conservative_egl_dlsym(name, true);
}

void *
epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails)
{
return do_dlsym(&api.glx_handle, GLX_LIB, name, exit_if_fails);
}

void *
epoxy_glx_dlsym(const char *name)
{
return do_dlsym(&api.glx_handle, GLX_LIB, name, true);
return epoxy_conservative_glx_dlsym(name, true);
}

void *
Expand Down
2 changes: 2 additions & 0 deletions src/dispatch_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ bool epoxy_conservative_has_glx_extension(const char *name);
int epoxy_conservative_egl_version(void);
bool epoxy_conservative_has_egl_extension(const char *name);
bool epoxy_conservative_has_wgl_extension(const char *name);
void *epoxy_conservative_egl_dlsym(const char *name, bool exit_if_fails);
void *epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails);

bool epoxy_extension_in_string(const char *extension_list, const char *ext);

Expand Down
21 changes: 21 additions & 0 deletions src/dispatch_egl.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,24 @@ epoxy_has_egl_extension(EGLDisplay dpy, const char *ext)
{
return epoxy_extension_in_string(eglQueryString(dpy, EGL_EXTENSIONS), ext) || epoxy_extension_in_string(eglQueryString(NULL, EGL_EXTENSIONS), ext);
}

/**
* @brief Checks whether EGL is available.
*
* @return `true` if EGL is available
*/
bool
epoxy_has_egl(void)
{
#if !PLATFORM_HAS_EGL
return false;
#else
EGLDisplay* (* pf_eglGetCurrentDisplay) (void);

pf_eglGetCurrentDisplay = epoxy_conservative_egl_dlsym("eglGetCurrentDisplay", false);
if (pf_eglGetCurrentDisplay)
return true;

return false;
#endif /* PLATFORM_HAS_EGL */
}
26 changes: 25 additions & 1 deletion src/dispatch_glx.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ epoxy_conservative_has_glx_extension(const char *ext)
*/
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
Expand All @@ -142,3 +142,27 @@ epoxy_has_glx_extension(Display *dpy, int screen, const char *ext)
*/
return epoxy_extension_in_string(glXQueryExtensionsString(dpy, screen), ext);
}

/**
* @brief Checks whether GLX is available.
*
* @param dpy The X11 display
*
* @return `true` if GLX is available
*/
bool
epoxy_has_glx(Display *dpy)
{
#if !PLATFORM_HAS_GLX
return false;
#else
Bool (* pf_glXQueryExtension) (Display *, int *, int *);
int error_base, event_base;

pf_glXQueryExtension = epoxy_conservative_glx_dlsym("glXQueryExtension", false);
if (pf_glXQueryExtension && pf_glXQueryExtension(dpy, &error_base, &event_base))
return true;

return false;
#endif /* !PLATFORM_HAS_GLX */
}

0 comments on commit 7782509

Please sign in to comment.