From 45f23cdbbbb47c7d46203a6a6ce89ac07326474c Mon Sep 17 00:00:00 2001 From: Jonathan De Wachter Date: Thu, 19 Dec 2013 16:27:42 +0100 Subject: [PATCH] Made the OpenGL ES implementation available on ARM-based Linux OSes --- cmake/Modules/FindEGL.cmake | 14 ++++++ cmake/Modules/FindGLES.cmake | 14 ++++++ include/SFML/OpenGL.hpp | 9 +++- src/SFML/Graphics/CMakeLists.txt | 8 ++++ src/SFML/Graphics/GLExtensions.cpp | 2 +- src/SFML/System/Android/Activity.hpp | 2 +- src/SFML/Window/Android/WindowImplAndroid.hpp | 2 +- src/SFML/Window/CMakeLists.txt | 24 +++++++--- src/SFML/Window/{Android => }/EglContext.cpp | 45 +++++++++++++------ src/SFML/Window/{Android => }/EglContext.hpp | 18 +++++++- src/SFML/Window/GlContext.cpp | 38 +++++++++------- src/SFML/Window/Unix/WindowImplX11.cpp | 10 ++++- 12 files changed, 143 insertions(+), 43 deletions(-) create mode 100644 cmake/Modules/FindEGL.cmake create mode 100644 cmake/Modules/FindGLES.cmake rename src/SFML/Window/{Android => }/EglContext.cpp (85%) rename src/SFML/Window/{Android => }/EglContext.hpp (89%) diff --git a/cmake/Modules/FindEGL.cmake b/cmake/Modules/FindEGL.cmake new file mode 100644 index 000000000..eb90be483 --- /dev/null +++ b/cmake/Modules/FindEGL.cmake @@ -0,0 +1,14 @@ +# +# Try to find EGL library and include path. +# Once done this will define +# +# EGL_FOUND +# EGL_INCLUDE_PATH +# EGL_LIBRARY +# + +find_path(EGL_INCLUDE_DIR EGL/egl.h) +find_library(EGL_LIBRARY NAMES EGL) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(EGL DEFAULT_MSG EGL_LIBRARY EGL_INCLUDE_DIR) diff --git a/cmake/Modules/FindGLES.cmake b/cmake/Modules/FindGLES.cmake new file mode 100644 index 000000000..8149e2ec3 --- /dev/null +++ b/cmake/Modules/FindGLES.cmake @@ -0,0 +1,14 @@ +# +# Try to find GLES library and include path. +# Once done this will define +# +# GLES_FOUND +# GLES_INCLUDE_PATH +# GLES_LIBRARY +# + +find_path(GLES_INCLUDE_DIR GLES/gl.h) +find_library(GLES_LIBRARY NAMES GLESv1_CM) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GLES DEFAULT_MSG GLES_LIBRARY GLES_INCLUDE_DIR) diff --git a/include/SFML/OpenGL.hpp b/include/SFML/OpenGL.hpp index 6345c6edb..3295eb9bb 100644 --- a/include/SFML/OpenGL.hpp +++ b/include/SFML/OpenGL.hpp @@ -48,8 +48,13 @@ #elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) - #include - #include + #if defined(SFML_OPENGL_ES) + #include + #include + #else + #include + #include + #endif #elif defined(SFML_SYSTEM_MACOS) diff --git a/src/SFML/Graphics/CMakeLists.txt b/src/SFML/Graphics/CMakeLists.txt index 59ae577db..005d8d8f4 100644 --- a/src/SFML/Graphics/CMakeLists.txt +++ b/src/SFML/Graphics/CMakeLists.txt @@ -117,6 +117,11 @@ if(NOT SFML_OPENGL_ES) endif() include_directories(${FREETYPE_INCLUDE_DIRS} ${GLEW_INCLUDE_PATH} ${JPEG_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) endif() +if(SFML_OPENGL_ES AND SFML_OS_LINUX) + find_package(EGL REQUIRED) + find_package(GLES REQUIRED) + include_directories(${EGL_INCLUDE_DIR} ${GLES_INCLUDE_DIR}) +endif() if(SFML_OS_ANDROID) find_host_package(JPEG REQUIRED) find_host_package(Freetype REQUIRED) @@ -133,6 +138,9 @@ if(NOT SFML_OPENGL_ES) list(APPEND GRAPHICS_EXT_LIBS ${X11_LIBRARIES}) endif() endif() +if(SFML_OPENGL_ES AND SFML_OS_LINUX) + list(APPEND GRAPHICS_EXT_LIBS ${EGL_LIBRARY} ${GLES_LIBRARY}) +endif() if(SFML_OS_IOS) list(APPEND GRAPHICS_EXT_LIBS "-framework OpenGLES") elseif(SFML_OS_ANDROID) diff --git a/src/SFML/Graphics/GLExtensions.cpp b/src/SFML/Graphics/GLExtensions.cpp index 1b7862de6..ed0c7d548 100644 --- a/src/SFML/Graphics/GLExtensions.cpp +++ b/src/SFML/Graphics/GLExtensions.cpp @@ -36,7 +36,7 @@ namespace priv //////////////////////////////////////////////////////////// void ensureExtensionsInit() { -#if !(defined SFML_SYSTEM_IOS || defined SFML_SYSTEM_ANDROID) +#if !defined(SFML_OPENGL_ES) static bool initialized = false; if (!initialized) { diff --git a/src/SFML/System/Android/Activity.hpp b/src/SFML/System/Android/Activity.hpp index a552fbf71..ff1eeb29f 100644 --- a/src/SFML/System/Android/Activity.hpp +++ b/src/SFML/System/Android/Activity.hpp @@ -29,7 +29,7 @@ // Headers //////////////////////////////////////////////////////////// #include -#include +#include #include #include #include diff --git a/src/SFML/Window/Android/WindowImplAndroid.hpp b/src/SFML/Window/Android/WindowImplAndroid.hpp index b7c2c32a1..290f8c5eb 100644 --- a/src/SFML/Window/Android/WindowImplAndroid.hpp +++ b/src/SFML/Window/Android/WindowImplAndroid.hpp @@ -30,7 +30,7 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include #include #include diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index 9732ac069..29555bb06 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -35,6 +35,10 @@ set(SRC ${SRCROOT}/WindowImpl.hpp ${INCROOT}/WindowStyle.hpp ) +if(SFML_OPENGL_ES) + list(APPEND SRC ${SRCROOT}/EglContext.cpp) + list(APPEND SRC ${SRCROOT}/EglContext.hpp) +endif() source_group("" FILES ${SRC}) # add platform specific sources @@ -58,14 +62,19 @@ elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD) set(PLATFORM_SRC ${SRCROOT}/Unix/Display.cpp ${SRCROOT}/Unix/Display.hpp - ${SRCROOT}/Unix/GlxContext.cpp - ${SRCROOT}/Unix/GlxContext.hpp ${SRCROOT}/Unix/InputImpl.cpp ${SRCROOT}/Unix/InputImpl.hpp ${SRCROOT}/Unix/VideoModeImpl.cpp ${SRCROOT}/Unix/WindowImplX11.cpp ${SRCROOT}/Unix/WindowImplX11.hpp ) + if(NOT SFML_OPENGL_ES) + set(PLATFORM_SRC + ${PLATFORM_SRC} + ${SRCROOT}/Unix/GlxContext.cpp + ${SRCROOT}/Unix/GlxContext.hpp + ) + endif() if(SFML_OS_LINUX) set(PLATFORM_SRC ${PLATFORM_SRC} @@ -144,8 +153,6 @@ elseif(SFML_OS_ANDROID) set(PLATFORM_SRC ${SRCROOT}/Android/WindowImplAndroid.hpp ${SRCROOT}/Android/WindowImplAndroid.cpp - ${SRCROOT}/Android/EglContext.hpp - ${SRCROOT}/Android/EglContext.cpp ${SRCROOT}/Android/VideoModeImpl.cpp ${SRCROOT}/Android/InputImpl.hpp ${SRCROOT}/Android/InputImpl.cpp @@ -171,6 +178,11 @@ if(NOT SFML_OPENGL_ES) include_directories(${UDEV_INCLUDE_DIR}) endif() endif() +if(SFML_OPENGL_ES AND SFML_OS_LINUX) + find_package(EGL REQUIRED) + find_package(GLES REQUIRED) + include_directories(${EGL_INCLUDE_DIR} ${GLES_INCLUDE_DIR}) +endif() # build the list of external libraries to link if(SFML_OS_WINDOWS) @@ -188,7 +200,9 @@ elseif(SFML_OS_ANDROID) list(APPEND WINDOW_EXT_LIBS "-landroid") endif() if(SFML_OPENGL_ES) - if(SFML_OS_IOS) + if(SFML_OS_LINUX) + list(APPEND WINDOW_EXT_LIBS ${EGL_LIBRARY} ${GLES_LIBRARY}) + elseif(SFML_OS_IOS) list(APPEND WINDOW_EXT_LIBS "-framework OpenGLES") elseif(SFML_OS_ANDROID) list(APPEND WINDOW_EXT_LIBS "-lEGL -lGLESv1_CM") diff --git a/src/SFML/Window/Android/EglContext.cpp b/src/SFML/Window/EglContext.cpp similarity index 85% rename from src/SFML/Window/Android/EglContext.cpp rename to src/SFML/Window/EglContext.cpp index fb8f866db..093fc6fd2 100644 --- a/src/SFML/Window/Android/EglContext.cpp +++ b/src/SFML/Window/EglContext.cpp @@ -26,15 +26,15 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include -#include +#include #include #include #include #include #include - -#include +#ifdef SFML_SYSTEM_ANDROID + #include +#endif namespace sf { @@ -46,12 +46,8 @@ m_display (EGL_NO_DISPLAY), m_context (EGL_NO_CONTEXT), m_surface (EGL_NO_SURFACE) { - // Get the activity states and protect it from concurent access - ActivityStates* states = getActivity(NULL); - Lock lock(states->mutex); - // Get the intialized EGL display - m_display = states->display; + m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); // Create the EGL surface const EGLint attribs[] = { @@ -83,14 +79,18 @@ m_display (EGL_NO_DISPLAY), m_context (EGL_NO_CONTEXT), m_surface (EGL_NO_SURFACE) { - // Get the activity states and protect it from concurent access +#ifdef SFML_SYSTEM_ANDROID + + // On Android, we must save the created context ActivityStates* states = getActivity(NULL); Lock lock(states->mutex); states->context = this; +#endif + // Get the intialized EGL display - m_display = states->display; + m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); // Create the EGL surface const EGLint attribs[] = { @@ -108,6 +108,10 @@ m_surface (EGL_NO_SURFACE) // Create the context createContext(shared, 0, config[0]); + +#ifdef SFML_OS_LINUX + createSurface((EGLNativeWindowType)owner->getSystemHandle()); +#endif } @@ -148,8 +152,7 @@ EglContext::~EglContext() //////////////////////////////////////////////////////////// bool EglContext::makeCurrent() { - bool success = m_surface != EGL_NO_SURFACE && eglCheck(eglMakeCurrent(m_display, m_surface, m_surface, m_context)); - return success; + return m_surface != EGL_NO_SURFACE && eglCheck(eglMakeCurrent(m_display, m_surface, m_surface, m_context)); } @@ -166,6 +169,8 @@ void EglContext::setVerticalSyncEnabled(bool enabled) eglCheck(eglSwapInterval(m_display, enabled ? 1 : 0)); } + +//////////////////////////////////////////////////////////// void EglContext::createContext(EglContext* shared, unsigned int bitsPerPixel, const EGLConfig settings) { EGLint contextVersion[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; @@ -182,7 +187,8 @@ void EglContext::createContext(EglContext* shared, unsigned int bitsPerPixel, co } -void EglContext::createSurface(ANativeWindow* window) +//////////////////////////////////////////////////////////// +void EglContext::createSurface(EGLNativeWindowType window) { // Create the EGL surface const EGLint attribs[] = { @@ -201,6 +207,8 @@ void EglContext::createSurface(ANativeWindow* window) m_surface = eglCheck(eglCreateWindowSurface(m_display, config[0], window, NULL)); } + +//////////////////////////////////////////////////////////// void EglContext::destroySurface() { eglCheck(eglDestroySurface(m_display, m_surface)); @@ -210,6 +218,15 @@ void EglContext::destroySurface() setActive(false); } + +#ifdef SFML_SYSTEM_LINUX +//////////////////////////////////////////////////////////// +XVisualInfo EglContext::selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings) +{ + return XVisualInfo(); +} +#endif + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Android/EglContext.hpp b/src/SFML/Window/EglContext.hpp similarity index 89% rename from src/SFML/Window/Android/EglContext.hpp rename to src/SFML/Window/EglContext.hpp index a8e1f24f6..302b51c6f 100644 --- a/src/SFML/Window/Android/EglContext.hpp +++ b/src/SFML/Window/EglContext.hpp @@ -123,10 +123,10 @@ public : /// This function must be called when the activity (re)start, or /// when the orientation change. /// - /// \param window : The Android window + /// \param window : The native window type /// //////////////////////////////////////////////////////////// - void createSurface(ANativeWindow* window); + void createSurface(EGLNativeWindowType window); //////////////////////////////////////////////////////////// /// \brief Destroy the EGL surface @@ -137,6 +137,20 @@ public : //////////////////////////////////////////////////////////// void destroySurface(); +#ifdef SFML_SYSTEM_LINUX + //////////////////////////////////////////////////////////// + /// \brief Select the best EGL visual for a given set of settings + /// + /// \param display X display + /// \param bitsPerPixel Pixel depth, in bits per pixel + /// \param settings Requested context settings + /// + /// \return The best visual + /// + //////////////////////////////////////////////////////////// + static XVisualInfo selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings); +#endif + private : //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/GlContext.cpp b/src/SFML/Window/GlContext.cpp index 058f031ce..f76f6c526 100644 --- a/src/SFML/Window/GlContext.cpp +++ b/src/SFML/Window/GlContext.cpp @@ -39,30 +39,38 @@ #include #endif -#if defined(SFML_SYSTEM_WINDOWS) +#if !defined(SFML_OPENGL_ES) - #include - typedef sf::priv::WglContext ContextType; + #if defined(SFML_SYSTEM_WINDOWS) -#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) + #include + typedef sf::priv::WglContext ContextType; - #include - typedef sf::priv::GlxContext ContextType; + #elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) -#elif defined(SFML_SYSTEM_MACOS) + #include + typedef sf::priv::GlxContext ContextType; - #include - typedef sf::priv::SFContext ContextType; + #elif defined(SFML_SYSTEM_MACOS) -#elif defined(SFML_SYSTEM_IOS) + #include + typedef sf::priv::SFContext ContextType; - #include - typedef sf::priv::EaglContext ContextType; + #endif -#elif defined(SFML_SYSTEM_ANDROID) +#else - #include - typedef sf::priv::EglContext ContextType; + #if defined(SFML_SYSTEM_IOS) + + #include + typedef sf::priv::EaglContext ContextType; + + #else + + #include + typedef sf::priv::EglContext ContextType; + + #endif #endif diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 7e9394fa8..77624d4c2 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////// #include // important to be included first (conflict with None) #include -#include #include #include #include @@ -42,6 +41,13 @@ #include #include +#ifdef SFML_OPENGL_ES + #include + typedef sf::priv::EglContext ContextType; +#else + #include + typedef sf::priv::GlxContext ContextType; +#endif //////////////////////////////////////////////////////////// // Private data @@ -151,7 +157,7 @@ m_useSizeHints(false) switchToFullscreen(mode); // Choose the visual according to the context settings - XVisualInfo visualInfo = GlxContext::selectBestVisual(m_display, mode.bitsPerPixel, settings); + XVisualInfo visualInfo = ContextType::selectBestVisual(m_display, mode.bitsPerPixel, settings); // Define the window attributes XSetWindowAttributes attributes;