mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 03:52:01 +00:00
Make all EGL functions dynamically loaded
This commit is contained in:
parent
afe4aadade
commit
7e13a4909e
@ -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()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user