diff --git a/CMakeLists.txt b/CMakeLists.txt index f1c41bc8f..edbe973c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -280,9 +280,6 @@ endif() # Use Vivante for window creation #-------------------------------------------------------------------- if (_GLFW_VIVANTE) - list(APPEND glfw_LIBRARIES "-lEGL") - list(APPEND glfw_PKG_LIBS "-lEGL") - list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8e59317b1..cf20d1dd6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -78,6 +78,11 @@ if (_GLFW_X11 OR _GLFW_WAYLAND) endif() endif() +if (_GLFW_VIVANTE) + set_source_files_properties(${glfw_SOURCES} PROPERTIES + COMPILE_DEFINITIONS EGL_API_FB=1) +endif() + if (APPLE) # For some reason, CMake doesn't know about .m set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C) diff --git a/src/egl_context.h b/src/egl_context.h index 926e01fe4..a361ac2c5 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -45,7 +45,6 @@ typedef struct wl_display* EGLNativeDisplayType; typedef struct wl_egl_window* EGLNativeWindowType; #elif defined(_GLFW_VIVANTE) #define EGLAPIENTRY - #define EGL_API_FB #include #else #error "No supported EGL platform selected" diff --git a/src/vivante_init.c b/src/vivante_init.c index 585305cb4..3de1e1fec 100644 --- a/src/vivante_init.c +++ b/src/vivante_init.c @@ -34,6 +34,54 @@ int _glfwPlatformInit(void) { + _glfw.vivante.handle = _glfw_dlopen("libEGL.so.1"); + if (!_glfw.vivante.handle) { + _glfw.vivante.handle = _glfw_dlopen("libEGL.so"); + if (!_glfw.vivante.handle) { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Vivante: EGL Library not found"); + + return GLFW_FALSE; + } + } + + _glfw.vivante.GetDisplay = (PFN_fbGetDisplay) + _glfw_dlsym(_glfw.vivante.handle, "fbGetDisplay"); + _glfw.vivante.GetDisplayByIndex = (PFN_fbGetDisplayByIndex) + _glfw_dlsym(_glfw.vivante.handle, "fbGetDisplayByIndex"); + _glfw.vivante.GetDisplayGeometry = (PFN_fbGetDisplayGeometry) + _glfw_dlsym(_glfw.vivante.handle, "fbGetDisplayGeometry"); + _glfw.vivante.GetDisplayInfo = (PFN_fbGetDisplayInfo) + _glfw_dlsym(_glfw.vivante.handle, "fbGetDisplayInfo"); + _glfw.vivante.DestroyDisplay = (PFN_fbDestroyDisplay) + _glfw_dlsym(_glfw.vivante.handle, "fbDestroyDisplay"); + _glfw.vivante.CreateWindow = (PFN_fbCreateWindow) + _glfw_dlsym(_glfw.vivante.handle, "fbCreateWindow"); + _glfw.vivante.GetWindowGeometry = (PFN_fbGetWindowGeometry) + _glfw_dlsym(_glfw.vivante.handle, "fbGetWindowGeometry"); + _glfw.vivante.GetWindowInfo = (PFN_fbGetWindowInfo) + _glfw_dlsym(_glfw.vivante.handle, "fbGetWindowInfo"); + _glfw.vivante.DestroyWindow = (PFN_fbDestroyWindow) + _glfw_dlsym(_glfw.vivante.handle, "fbDestroyWindow"); + + if (!_glfw.vivante.GetDisplay || + !_glfw.vivante.GetDisplayByIndex || + !_glfw.vivante.GetDisplayGeometry || + !_glfw.vivante.GetDisplayInfo || + !_glfw.vivante.DestroyDisplay || + !_glfw.vivante.CreateWindow || + !_glfw.vivante.GetWindowGeometry || + !_glfw.vivante.GetWindowInfo || + !_glfw.vivante.DestroyWindow) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Vivante: Failed to load required entry points"); + + _glfwTerminateEGL(); + return GLFW_FALSE; + } + + _glfw.vivante.display = fbGetDisplay(NULL); if (!_glfw.vivante.display) { @@ -43,10 +91,6 @@ int _glfwPlatformInit(void) return GLFW_FALSE; } - - - - _glfwInitTimerPOSIX(); if (!_glfwInitJoysticksLinux()) @@ -64,6 +108,12 @@ void _glfwPlatformTerminate(void) fbDestroyDisplay(_glfw.vivante.display); _glfw.vivante.display = NULL; } + + if (_glfw.vivante.handle) + { + _glfw_dlclose(_glfw.vivante.handle); + _glfw.vivante.handle = NULL; + } } const char* _glfwPlatformGetVersionString(void) diff --git a/src/vivante_platform.h b/src/vivante_platform.h index 57f9f3e5e..1fc4c8425 100644 --- a/src/vivante_platform.h +++ b/src/vivante_platform.h @@ -26,7 +26,6 @@ //======================================================================== #include -#include // TODO: remove it #define _GLFW_PLATFORM_CONTEXT_STATE #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE @@ -51,12 +50,36 @@ #define _GLFW_PLATFORM_MONITOR_STATE //_GLFWmonitorVivante vivante #define _GLFW_PLATFORM_CURSOR_STATE //_GLFWcursorVivante vivante +// EGL function pointer typedefs +typedef void * EGLNativeDisplayType; +typedef void * EGLNativeWindowType; + +typedef EGLNativeDisplayType (EGLAPIENTRY * PFN_fbGetDisplay)(void *context); +typedef EGLNativeDisplayType (EGLAPIENTRY * PFN_fbGetDisplayByIndex)(int DisplayIndex); +typedef void (EGLAPIENTRY * PFN_fbGetDisplayGeometry)(EGLNativeDisplayType Display, int *Width, int *Height); +typedef void (EGLAPIENTRY * PFN_fbGetDisplayInfo)(EGLNativeDisplayType Display, int *Width, int *Height, unsigned long *Physical, int *Stride, int *BitsPerPixel); +typedef void (EGLAPIENTRY * PFN_fbDestroyDisplay)(EGLNativeDisplayType Display); +typedef EGLNativeWindowType (EGLAPIENTRY * PFN_fbCreateWindow)(EGLNativeDisplayType Display, int X, int Y, int Width, int Height); +typedef void (EGLAPIENTRY * PFN_fbGetWindowGeometry)(EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height); +typedef void (EGLAPIENTRY * PFN_fbGetWindowInfo)(EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height, int *BitsPerPixel, unsigned int *Offset); +typedef void (EGLAPIENTRY * PFN_fbDestroyWindow)(EGLNativeWindowType Window); + +#define fbGetDisplay _glfw.vivante.GetDisplay +#define fbGetDisplayByIndex _glfw.vivante.GetDisplayByIndex +#define fbGetDisplayGeometry _glfw.vivante.GetDisplayGeometry +#define fbGetDisplayInfo _glfw.vivante.GetDisplayInfo +#define fbDestroyDisplay _glfw.vivante.DestroyDisplay +#define fbCreateWindow _glfw.vivante.CreateWindow +#define fbGetWindowGeometry _glfw.vivante.GetWindowGeometry +#define fbGetWindowInfo _glfw.vivante.GetWindowInfo +#define fbDestroyWindow _glfw.vivante.DestroyWindow + + // Vivante-specific per-window data // typedef struct _GLFWwindowVivante { EGLNativeWindowType native_window; - EGLSurface egl_surface; // Cached position and size used to filter out duplicate events int width, height; @@ -70,4 +93,16 @@ typedef struct _GLFWlibraryVivante { EGLNativeDisplayType display; + void* handle; + + PFN_fbGetDisplay GetDisplay; + PFN_fbGetDisplayByIndex GetDisplayByIndex; + PFN_fbGetDisplayGeometry GetDisplayGeometry; + PFN_fbGetDisplayInfo GetDisplayInfo; + PFN_fbDestroyDisplay DestroyDisplay; + PFN_fbCreateWindow CreateWindow; + PFN_fbGetWindowGeometry GetWindowGeometry; + PFN_fbGetWindowInfo GetWindowInfo; + PFN_fbDestroyWindow DestroyWindow; + } _GLFWlibraryVivante;