Make all EGL functions dynamically loaded

This commit is contained in:
Camilla Berglund 2015-08-24 16:39:01 +02:00
parent afe4aadade
commit 7e13a4909e
4 changed files with 187 additions and 42 deletions

View File

@ -402,6 +402,11 @@ if (_GLFW_EGL)
list(APPEND glfw_PKG_DEPS "glesv2")
endif()
if (CMAKE_DL_LIBS)
list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}")
list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
endif()
endif()
#--------------------------------------------------------------------

View File

@ -102,6 +102,7 @@ GLFW bundles a number of dependencies in the `deps/` directory.
- [GLX] Made all GLX functions dynamically loaded
- [GLX] Removed `_GLFW_HAS_GLXGETPROCADDRESS*` and `_GLFW_HAS_DLOPEN`
compile-time options
- [EGL] Made all EGL functions dynamically loaded
## Contact

View File

@ -78,7 +78,7 @@ static const char* getErrorString(EGLint error)
static int getConfigAttrib(EGLConfig config, int attrib)
{
int value;
eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
_glfw_eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
return value;
}
@ -93,7 +93,7 @@ static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* closest;
int i, nativeCount, usableCount;
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
_glfw_eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
if (!nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
@ -101,7 +101,8 @@ static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
}
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
_glfw_eglGetConfigs(_glfw.egl.display, nativeConfigs,
nativeCount, &nativeCount);
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
@ -178,23 +179,86 @@ static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
//
int _glfwInitContextAPI(void)
{
int i;
const char* sonames[] =
{
#if defined(_GLFW_WIN32)
"libEGL.dll",
"EGL.dll",
#elif defined(_GLFW_COCOA)
"libEGL.dylib",
#else
"libEGL.so.1",
#endif
NULL
};
if (!_glfwCreateContextTLS())
return GL_FALSE;
_glfw.egl.display = eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY);
for (i = 0; sonames[i]; i++)
{
_glfw.egl.handle = _glfw_dlopen(sonames[i]);
if (_glfw.egl.handle)
break;
}
if (!_glfw.egl.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to load EGL");
return GL_FALSE;
}
_glfw.egl.GetConfigAttrib =
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
_glfw.egl.GetConfigs =
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
_glfw.egl.GetDisplay =
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
_glfw.egl.GetError =
_glfw_dlsym(_glfw.egl.handle, "eglGetError");
_glfw.egl.Initialize =
_glfw_dlsym(_glfw.egl.handle, "eglInitialize");
_glfw.egl.Terminate =
_glfw_dlsym(_glfw.egl.handle, "eglTerminate");
_glfw.egl.BindAPI =
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI");
_glfw.egl.CreateContext =
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext");
_glfw.egl.DestroySurface =
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");
_glfw.egl.DestroyContext =
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface =
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.MakeCurrent =
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers =
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");
_glfw.egl.SwapInterval =
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");
_glfw.egl.QueryString =
_glfw_dlsym(_glfw.egl.handle, "eglQueryString");
_glfw.egl.GetProcAddress =
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
_glfw.egl.display =
_glfw_eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to get EGL display: %s",
getErrorString(eglGetError()));
getErrorString(_glfw_eglGetError()));
return GL_FALSE;
}
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
if (!_glfw_eglInitialize(_glfw.egl.display,
&_glfw.egl.major,
&_glfw.egl.minor))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to initialize EGL: %s",
getErrorString(eglGetError()));
getErrorString(_glfw_eglGetError()));
return GL_FALSE;
}
@ -208,7 +272,14 @@ int _glfwInitContextAPI(void)
//
void _glfwTerminateContextAPI(void)
{
eglTerminate(_glfw.egl.display);
if (_glfw_eglTerminate)
_glfw_eglTerminate(_glfw.egl.display);
if (_glfw.egl.handle)
{
_glfw_dlclose(_glfw.egl.handle);
_glfw.egl.handle = NULL;
}
_glfwDestroyContextTLS();
}
@ -248,8 +319,8 @@ int _glfwCreateContext(_GLFWwindow* window,
EGLint redBits, greenBits, blueBits, alphaBits, visualID = 0;
XVisualInfo info;
eglGetConfigAttrib(_glfw.egl.display, config,
EGL_NATIVE_VISUAL_ID, &visualID);
_glfw_eglGetConfigAttrib(_glfw.egl.display, config,
EGL_NATIVE_VISUAL_ID, &visualID);
info.screen = _glfw.x11.screen;
mask = VisualScreenMask;
@ -265,14 +336,14 @@ int _glfwCreateContext(_GLFWwindow* window,
// Some EGL drivers do not implement the EGL_NATIVE_VISUAL_ID
// attribute, so attempt to find the closest match
eglGetConfigAttrib(_glfw.egl.display, config,
EGL_RED_SIZE, &redBits);
eglGetConfigAttrib(_glfw.egl.display, config,
EGL_GREEN_SIZE, &greenBits);
eglGetConfigAttrib(_glfw.egl.display, config,
EGL_BLUE_SIZE, &blueBits);
eglGetConfigAttrib(_glfw.egl.display, config,
EGL_ALPHA_SIZE, &alphaBits);
_glfw_eglGetConfigAttrib(_glfw.egl.display, config,
EGL_RED_SIZE, &redBits);
_glfw_eglGetConfigAttrib(_glfw.egl.display, config,
EGL_GREEN_SIZE, &greenBits);
_glfw_eglGetConfigAttrib(_glfw.egl.display, config,
EGL_BLUE_SIZE, &blueBits);
_glfw_eglGetConfigAttrib(_glfw.egl.display, config,
EGL_ALPHA_SIZE, &alphaBits);
info.depth = redBits + greenBits + blueBits + alphaBits;
mask |= VisualDepthMask;
@ -291,21 +362,21 @@ int _glfwCreateContext(_GLFWwindow* window,
if (ctxconfig->api == GLFW_OPENGL_ES_API)
{
if (!eglBindAPI(EGL_OPENGL_ES_API))
if (!_glfw_eglBindAPI(EGL_OPENGL_ES_API))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL ES: %s",
getErrorString(eglGetError()));
getErrorString(_glfw_eglGetError()));
return GL_FALSE;
}
}
else
{
if (!eglBindAPI(EGL_OPENGL_API))
if (!_glfw_eglBindAPI(EGL_OPENGL_API))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL: %s",
getErrorString(eglGetError()));
getErrorString(_glfw_eglGetError()));
return GL_FALSE;
}
}
@ -371,14 +442,14 @@ int _glfwCreateContext(_GLFWwindow* window,
// Context release behaviors (GL_KHR_context_flush_control) are not yet
// supported on EGL but are not a hard constraint, so ignore and continue
window->egl.context = eglCreateContext(_glfw.egl.display,
config, share, attribs);
window->egl.context = _glfw_eglCreateContext(_glfw.egl.display,
config, share, attribs);
if (window->egl.context == EGL_NO_CONTEXT)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"EGL: Failed to create context: %s",
getErrorString(eglGetError()));
getErrorString(_glfw_eglGetError()));
return GL_FALSE;
}
@ -403,13 +474,13 @@ void _glfwDestroyContext(_GLFWwindow* window)
if (window->egl.surface)
{
eglDestroySurface(_glfw.egl.display, window->egl.surface);
_glfw_eglDestroySurface(_glfw.egl.display, window->egl.surface);
window->egl.surface = EGL_NO_SURFACE;
}
if (window->egl.context)
{
eglDestroyContext(_glfw.egl.display, window->egl.context);
_glfw_eglDestroyContext(_glfw.egl.display, window->egl.context);
window->egl.context = EGL_NO_CONTEXT;
}
}
@ -438,27 +509,30 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
{
if (window->egl.surface == EGL_NO_SURFACE)
{
window->egl.surface = eglCreateWindowSurface(_glfw.egl.display,
window->egl.config,
(EGLNativeWindowType)_GLFW_EGL_NATIVE_WINDOW,
NULL);
window->egl.surface =
_glfw_eglCreateWindowSurface(_glfw.egl.display,
window->egl.config,
(EGLNativeWindowType)_GLFW_EGL_NATIVE_WINDOW,
NULL);
if (window->egl.surface == EGL_NO_SURFACE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to create window surface: %s",
getErrorString(eglGetError()));
getErrorString(_glfw_eglGetError()));
}
}
eglMakeCurrent(_glfw.egl.display,
window->egl.surface,
window->egl.surface,
window->egl.context);
_glfw_eglMakeCurrent(_glfw.egl.display,
window->egl.surface,
window->egl.surface,
window->egl.context);
}
else
{
eglMakeCurrent(_glfw.egl.display,
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
_glfw_eglMakeCurrent(_glfw.egl.display,
EGL_NO_SURFACE,
EGL_NO_SURFACE,
EGL_NO_CONTEXT);
}
_glfwSetContextTLS(window);
@ -466,17 +540,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
void _glfwPlatformSwapBuffers(_GLFWwindow* window)
{
eglSwapBuffers(_glfw.egl.display, window->egl.surface);
_glfw_eglSwapBuffers(_glfw.egl.display, window->egl.surface);
}
void _glfwPlatformSwapInterval(int interval)
{
eglSwapInterval(_glfw.egl.display, interval);
_glfw_eglSwapInterval(_glfw.egl.display, interval);
}
int _glfwPlatformExtensionSupported(const char* extension)
{
const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
const char* extensions = _glfw_eglQueryString(_glfw.egl.display,
EGL_EXTENSIONS);
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
@ -488,7 +563,7 @@ int _glfwPlatformExtensionSupported(const char* extension)
GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
{
return eglGetProcAddress(procname);
return _glfw_eglGetProcAddress(procname);
}

View File

@ -28,6 +28,17 @@
#ifndef _glfw3_egl_context_h_
#define _glfw3_egl_context_h_
#if defined(_GLFW_WIN32)
#define _glfw_dlopen(name) LoadLibraryA(name)
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#else
#include <dlfcn.h>
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#endif
#include <EGL/egl.h>
// This path may need to be changed if you build GLFW using your own setup
@ -35,6 +46,40 @@
// extensions and not all operating systems come with an up-to-date version
#include "../deps/EGL/eglext.h"
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETCONFIGATTRIBPROC)(EGLDisplay,EGLConfig,EGLint,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETCONFIGSPROC)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType);
typedef EGLint (EGLAPIENTRY * PFNEGLGETERRORPROC)(void);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLINITIALIZEPROC)(EGLDisplay,EGLint*,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLTERMINATEPROC)(EGLDisplay);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLBINDAPIPROC)(EGLenum);
typedef EGLContext (EGLAPIENTRY * PFNEGLCREATECONTEXTPROC)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYSURFACEPROC)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYCONTEXTPROC)(EGLDisplay,EGLContext);
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLMAKECURRENTPROC)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPBUFFERSPROC)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPINTERVALPROC)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFNEGLQUERYSTRINGPROC)(EGLDisplay,EGLint);
typedef GLFWglproc (EGLAPIENTRY * PFNEGLGETPROCADDRESSPROC)(const char*);
#define _glfw_eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define _glfw_eglGetConfigs _glfw.egl.GetConfigs
#define _glfw_eglGetDisplay _glfw.egl.GetDisplay
#define _glfw_eglGetError _glfw.egl.GetError
#define _glfw_eglInitialize _glfw.egl.Initialize
#define _glfw_eglTerminate _glfw.egl.Terminate
#define _glfw_eglBindAPI _glfw.egl.BindAPI
#define _glfw_eglCreateContext _glfw.egl.CreateContext
#define _glfw_eglDestroySurface _glfw.egl.DestroySurface
#define _glfw_eglDestroyContext _glfw.egl.DestroyContext
#define _glfw_eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define _glfw_eglMakeCurrent _glfw.egl.MakeCurrent
#define _glfw_eglSwapBuffers _glfw.egl.SwapBuffers
#define _glfw_eglSwapInterval _glfw.egl.SwapInterval
#define _glfw_eglQueryString _glfw.egl.QueryString
#define _glfw_eglGetProcAddress _glfw.egl.GetProcAddress
#define _GLFW_PLATFORM_FBCONFIG EGLConfig egl
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL egl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl
@ -64,6 +109,25 @@ typedef struct _GLFWlibraryEGL
GLboolean KHR_create_context;
void* handle;
PFNEGLGETCONFIGATTRIBPROC GetConfigAttrib;
PFNEGLGETCONFIGSPROC GetConfigs;
PFNEGLGETDISPLAYPROC GetDisplay;
PFNEGLGETERRORPROC GetError;
PFNEGLINITIALIZEPROC Initialize;
PFNEGLTERMINATEPROC Terminate;
PFNEGLBINDAPIPROC BindAPI;
PFNEGLCREATECONTEXTPROC CreateContext;
PFNEGLDESTROYSURFACEPROC DestroySurface;
PFNEGLDESTROYCONTEXTPROC DestroyContext;
PFNEGLCREATEWINDOWSURFACEPROC CreateWindowSurface;
PFNEGLMAKECURRENTPROC MakeCurrent;
PFNEGLSWAPBUFFERSPROC SwapBuffers;
PFNEGLSWAPINTERVALPROC SwapInterval;
PFNEGLQUERYSTRINGPROC QueryString;
PFNEGLGETPROCADDRESSPROC GetProcAddress;
} _GLFWlibraryEGL;