From 1327c124a4ed50d5572474aa11eb5e84bc0bc036 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 07:56:17 +0300 Subject: [PATCH 01/18] Seperate Context from Window in CMakeLists, add option to build for EGL --- CMakeLists.txt | 96 +++++++++++++++++++++++++++++++++++++++------- src/CMakeLists.txt | 5 +++ 2 files changed, 88 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44dcb4d4..dd5c35aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,8 +12,14 @@ set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON) option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) option(BUILD_SHARED_LIBS "Build shared libraries" OFF) +option(GLFW_USE_EGL "Build for EGL and OpenGL ES platform (Currently only X11)" OFF) -find_package(OpenGL REQUIRED) +if (GLFW_USE_EGL) + SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake/modules) + find_package(EGL REQUIRED) +else() + find_package(OpenGL REQUIRED) +endif() #-------------------------------------------------------------------- # Enable all warnings on GCC, regardless of OS @@ -39,8 +45,14 @@ elseif (UNIX AND APPLE) set(_GLFW_COCOA_NSGL 1) message(STATUS "Building GLFW for Cocoa and NSOpenGL on Mac OS X") elseif (UNIX AND NOT APPLE) - set(_GLFW_X11_GLX 1) - message(STATUS "Building GLFW for X11 and GLX on a Unix-like system") + set(_GLFW_X11 1) + if (GLFW_USE_EGL) + set(_GLFW_X11_EGL 1) + message(STATUS "Building GLFW for X11 and EGL on a Unix-like system") + else() + set(_GLFW_X11_GLX 1) + message(STATUS "Building GLFW for X11 and GLX on a Unix-like system") + endif() else() message(FATAL_ERROR "No supported platform was detected") endif() @@ -62,20 +74,18 @@ if (_GLFW_WIN32_WGL) endif() #-------------------------------------------------------------------- -# Set up GLFW for Xlib and GLX on Unix-like systems with X Windows +# Set up GLFW for Xlib and GLX or EGL on Unix-like systems with X Windows #-------------------------------------------------------------------- -if (_GLFW_X11_GLX) +if (_GLFW_X11) find_package(X11 REQUIRED) - # Set up library and include paths - list(APPEND glfw_INCLUDE_DIRS ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR}) - list(APPEND glfw_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY}) - - set(GLFW_PKG_DEPS "gl x11") set(GLFW_PKG_LIBS "") + set(GLFW_PKG_DEPS "x11") - include(CheckFunctionExists) + # Set up library and include paths + list(APPEND glfw_INCLUDE_DIRS ${X11_X11_INCLUDE_PATH}) + list(APPEND glfw_LIBRARIES ${X11_X11_LIB}) # Check for XRandR (modern resolution switching extension) if (X11_Xrandr_FOUND) @@ -121,6 +131,25 @@ if (_GLFW_X11_GLX) set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -lm") endif() + if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set(_GLFW_USE_LINUX_JOYSTICKS 1) + endif() + +endif() + +#-------------------------------------------------------------------- +# GLX Context +#-------------------------------------------------------------------- +if (_GLFW_X11_GLX) + + # Set up library and include paths + list(APPEND glfw_INCLUDE_DIRS${OPENGL_INCLUDE_DIR}) + list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY}) + + set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} gl") + + include(CheckFunctionExists) + set(CMAKE_REQUIRED_LIBRARIES ${OPENGL_gl_LIBRARY}) check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) @@ -160,9 +189,50 @@ if (_GLFW_X11_GLX) endif() endif() - if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - set(_GLFW_USE_LINUX_JOYSTICKS 1) +endif() + +#-------------------------------------------------------------------- +# EGL Context +#-------------------------------------------------------------------- +if (_GLFW_X11_EGL) + + # Set up library and include paths + list(APPEND glfw_INCLUDE_DIRS${EGL_INCLUDE_DIR}) + list(APPEND glfw_LIBRARIES ${EGL_LIBRARY}) + + set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} egl") + + include(CheckFunctionExists) + + set(CMAKE_REQUIRED_LIBRARIES ${EGL_LIBRARY}) + + check_function_exists(eglGetProcAddress _GLFW_HAS_EGLGETPROCADDRESS) + + if (NOT _GLFW_HAS_EGLGETPROCADDRESS) + message(WARNING "No eglGetProcAddress found") + + # Check for dlopen support as a fallback + + find_library(DL_LIBRARY dl) + mark_as_advanced(DL_LIBRARY) + if (DL_LIBRARY) + set(CMAKE_REQUIRED_LIBRARIES ${DL_LIBRARY}) + else() + set(CMAKE_REQUIRED_LIBRARIES "") + endif() + + check_function_exists(dlopen _GLFW_HAS_DLOPEN) + + if (NOT _GLFW_HAS_DLOPEN) + message(FATAL_ERROR "No entry point retrieval mechanism found") + endif() + + if (DL_LIBRARY) + list(APPEND glfw_LIBRARIES ${DL_LIBRARY}) + set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -ldl") + endif() endif() + endif() #-------------------------------------------------------------------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index add05982..9a4fba68 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,11 @@ elseif (_GLFW_X11_GLX) set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c x11_gamma.c x11_init.c x11_input.c x11_joystick.c x11_keysym2unicode.c x11_opengl.c x11_time.c x11_window.c) +elseif (_GLFW_X11_EGL) + set(glfw_HEADERS ${common_HEADERS} x11_egl_platform.h) + set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c + x11_gamma.c x11_init.c x11_input.c x11_joystick.c + x11_keysym2unicode.c x11_egl_opengl.c x11_time.c x11_window.c) endif() add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) From 85067ede2e3f9c3beab04852e43b83fd580570b6 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 07:56:34 +0300 Subject: [PATCH 02/18] Add EGL related configurations --- src/config.h.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/config.h.in b/src/config.h.in index 01d541a2..ceb7e5a2 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -37,6 +37,8 @@ // Define this to 1 if building GLFW for X11/GLX #cmakedefine _GLFW_X11_GLX +// Define this to 1 if building GLFW for X11/EGL +#cmakedefine _GLFW_X11_EGL // Define this to 1 if building GLFW for Win32/WGL #cmakedefine _GLFW_WIN32_WGL // Define this to 1 if building GLFW for Cocoa/NSOpenGL @@ -63,6 +65,9 @@ // Define this to 1 if glXGetProcAddressEXT is available #cmakedefine _GLFW_HAS_GLXGETPROCADDRESSEXT +// Define this to 1 if eglGetProcAddress is available +#cmakedefine _GLFW_HAS_EGLGETPROCADDRESS 1 + // Define this to 1 if the Linux joystick API is available #cmakedefine _GLFW_USE_LINUX_JOYSTICKS From 778a76683a38b49d2fcaa9f580841726ee122792 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 07:56:50 +0300 Subject: [PATCH 03/18] Add EGL X11 platform header --- src/internal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/internal.h b/src/internal.h index 700b6c06..386d5858 100644 --- a/src/internal.h +++ b/src/internal.h @@ -82,6 +82,8 @@ typedef struct _GLFWlibrary _GLFWlibrary; #include "win32_platform.h" #elif defined(_GLFW_X11_GLX) #include "x11_platform.h" +#elif defined(_GLFW_X11_EGL) + #include "x11_egl_platform.h" #else #error "No supported platform selected" #endif From 27a7cc5aa8c0ae64c3ea3e8399583d353a7e4cb3 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 07:57:21 +0300 Subject: [PATCH 04/18] Add FindEGL.cmake module --- CMake/modules/FindEGL.cmake | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 CMake/modules/FindEGL.cmake diff --git a/CMake/modules/FindEGL.cmake b/CMake/modules/FindEGL.cmake new file mode 100644 index 00000000..0d5765ed --- /dev/null +++ b/CMake/modules/FindEGL.cmake @@ -0,0 +1,15 @@ +# Find EGL +# +# EGL_INCLUDE_DIR +# EGL_LIBRARY +# EGL_FOUND + +FIND_PATH(EGL_INCLUDE_DIR NAMES EGL/egl.h) + +SET(EGL_NAMES ${EGL_NAMES} egl EGL) +FIND_LIBRARY(EGL_LIBRARY NAMES ${EGL_NAMES}) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(EGL DEFAULT_MSG EGL_LIBRARY EGL_INCLUDE_DIR) + +MARK_AS_ADVANCED(EGL_INCLUDE_DIR EGL_LIBRARY) From 812ebe200d88843f674926fbb245239e6758cc64 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 07:58:07 +0300 Subject: [PATCH 05/18] Add EGL X11 platform header --- src/x11_egl_platform.h | 285 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 src/x11_egl_platform.h diff --git a/src/x11_egl_platform.h b/src/x11_egl_platform.h new file mode 100644 index 00000000..b1fb53cb --- /dev/null +++ b/src/x11_egl_platform.h @@ -0,0 +1,285 @@ +//======================================================================== +// GLFW - An OpenGL library +// Platform: X11/EGL +// API version: 3.0 +// WWW: http://www.glfw.org/ +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#ifndef _platform_h_ +#define _platform_h_ + +#include +#include +#include +#include +#include +#include +#include + +// Include EGL +#include + +// With XFree86, we can use the XF86VidMode extension +#if defined(_GLFW_HAS_XF86VIDMODE) + #include +#endif + +#if defined(_GLFW_HAS_XRANDR) + #include +#endif + +// Do we have support for dlopen/dlsym? +#if defined(_GLFW_HAS_DLOPEN) + #include +#endif + +// The Xkb extension provides improved keyboard support +#if defined(_GLFW_HAS_XKB) + #include +#endif + +// We support two different ways for getting addresses for EGL +// extension functions: eglGetProcAddress and dlsym +#if defined(_GLFW_HAS_EGLGETPROCADDRESS) + #define _glfw_eglGetProcAddress(x) eglGetProcAddress(x) +#elif defined(_GLFW_HAS_DLOPEN) + #define _glfw_eglGetProcAddress(x) dlsym(_glfwLibrary.EGL.libEGL, x) + #define _GLFW_DLOPEN_LIBEGL +#else + #error "No OpenGL entry point retrieval mechanism was enabled" +#endif + +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11 +#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL EGL +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 X11 +#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryEGL EGL + +// Clipboard format atom indices +#define _GLFW_CLIPBOARD_FORMAT_UTF8 0 +#define _GLFW_CLIPBOARD_FORMAT_COMPOUND 1 +#define _GLFW_CLIPBOARD_FORMAT_STRING 2 +#define _GLFW_CLIPBOARD_FORMAT_COUNT 3 + +// Clipboard conversion status tokens +#define _GLFW_CONVERSION_INACTIVE 0 +#define _GLFW_CONVERSION_SUCCEEDED 1 +#define _GLFW_CONVERSION_FAILED 2 + + +//======================================================================== +// GLFW platform specific types +//======================================================================== + +//------------------------------------------------------------------------ +// Pointer length integer +//------------------------------------------------------------------------ +typedef intptr_t GLFWintptr; + + +//------------------------------------------------------------------------ +// Platform-specific OpenGL context structure +//------------------------------------------------------------------------ +typedef struct _GLFWcontextEGL +{ + EGLConfig config; + EGLContext context; + EGLSurface surface; + XVisualInfo* visual; +} _GLFWcontextEGL; + + +//------------------------------------------------------------------------ +// Platform-specific window structure +//------------------------------------------------------------------------ +typedef struct _GLFWwindowX11 +{ + // Platform specific window resources + Colormap colormap; // Window colormap + Window handle; // Window handle + + // Various platform specific internal variables + GLboolean overrideRedirect; // True if window is OverrideRedirect + GLboolean keyboardGrabbed; // True if keyboard is currently grabbed + GLboolean cursorGrabbed; // True if cursor is currently grabbed + GLboolean cursorHidden; // True if cursor is currently hidden + GLboolean cursorCentered; // True if cursor was moved since last poll + int cursorPosX, cursorPosY; + +} _GLFWwindowX11; + +//------------------------------------------------------------------------ +// Platform-specific library global data for X11 +//------------------------------------------------------------------------ +typedef struct _GLFWlibraryX11 +{ + Display* display; + int screen; + Window root; + Cursor cursor; // Invisible cursor for hidden cursor + + Atom wmDeleteWindow; // WM_DELETE_WINDOW atom + Atom wmName; // _NET_WM_NAME atom + Atom wmIconName; // _NET_WM_ICON_NAME atom + Atom wmPing; // _NET_WM_PING atom + Atom wmState; // _NET_WM_STATE atom + Atom wmStateFullscreen; // _NET_WM_STATE_FULLSCREEN atom + Atom wmActiveWindow; // _NET_ACTIVE_WINDOW atom + + // True if window manager supports EWMH + GLboolean hasEWMH; + + struct { + GLboolean available; + int eventBase; + int errorBase; + } VidMode; + + struct { + GLboolean available; + int eventBase; + int errorBase; + int majorVersion; + int minorVersion; + GLboolean gammaBroken; + } RandR; + + struct { + GLboolean available; + int majorOpcode; + int eventBase; + int errorBase; + int majorVersion; + int minorVersion; + } Xkb; + + // Key code LUT (mapping X11 key codes to GLFW key codes) + int keyCodeLUT[256]; + + // Screensaver data + struct { + GLboolean changed; + int timeout; + int interval; + int blanking; + int exposure; + } saver; + + // Fullscreen data + struct { + GLboolean modeChanged; +#if defined(_GLFW_HAS_XRANDR) + SizeID oldSizeID; + int oldWidth; + int oldHeight; + Rotation oldRotation; +#endif /*_GLFW_HAS_XRANDR*/ +#if defined(_GLFW_HAS_XF86VIDMODE) + XF86VidModeModeInfo oldMode; +#endif /*_GLFW_HAS_XF86VIDMODE*/ + } FS; + + // Timer data + struct { + GLboolean monotonic; + double resolution; + uint64_t base; + } timer; + + // Selection data + struct { + Atom atom; + Atom formats[_GLFW_CLIPBOARD_FORMAT_COUNT]; + char* string; + Atom target; + Atom targets; + Atom property; + int status; + } selection; + +} _GLFWlibraryX11; + +//------------------------------------------------------------------------ +// Platform-specific library global data for EGL +//------------------------------------------------------------------------ +typedef struct _GLFWlibraryEGL +{ + EGLDisplay display; + EGLint majorVersion, minorVersion; + +#if defined(_GLFW_DLOPEN_LIBEGL) + void* libEGL; // dlopen handle for libEGL.so +#endif +} _GLFWlibraryEGL; + +//------------------------------------------------------------------------ +// Joystick information & state +//------------------------------------------------------------------------ +GLFWGLOBAL struct { + int Present; + int fd; + int NumAxes; + int NumButtons; + float* Axis; + unsigned char* Button; +} _glfwJoy[GLFW_JOYSTICK_LAST + 1]; + + +//======================================================================== +// Prototypes for platform specific internal functions +//======================================================================== + +// Time +void _glfwInitTimer(void); + +// OpenGL(|ES) support +int _glfwInitOpenGL(void); +void _glfwTerminateOpenGL(void); +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig); +void _glfwDestroyContext(_GLFWwindow* window); + +// Fullscreen support +int _glfwGetClosestVideoMode(int* width, int* height, int* rate); +void _glfwSetVideoModeMODE(int mode, int rate); +void _glfwSetVideoMode(int* width, int* height, int* rate); +void _glfwRestoreVideoMode(void); + +// Joystick input +void _glfwInitJoysticks(void); +void _glfwTerminateJoysticks(void); + +// Unicode support +long _glfwKeySym2Unicode(KeySym keysym); + +// Clipboard handling +GLboolean _glfwReadSelection(XSelectionEvent* request); +Atom _glfwWriteSelection(XSelectionRequestEvent* request); + +// Event processing +void _glfwProcessPendingEvents(void); + +#endif // _platform_h_ From c878281487f1e2f3c1c4c0663d9bdd6c90bdcb4d Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 07:58:27 +0300 Subject: [PATCH 06/18] Add EGL platform opengl implentation --- src/x11_egl_opengl.c | 462 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100644 src/x11_egl_opengl.c diff --git a/src/x11_egl_opengl.c b/src/x11_egl_opengl.c new file mode 100644 index 00000000..efbadc06 --- /dev/null +++ b/src/x11_egl_opengl.c @@ -0,0 +1,462 @@ +//======================================================================== +// GLFW - An OpenGL library +// Platform: X11/EGL/GLES +// API version: 3.0 +// WWW: http://www.glfw.org/ +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include +#include + +// Max number of EGL configuration we handle +#define _GLFW_EGL_CONFIG_IN 15 + +//======================================================================== +// Returns the specified attribute of the specified EGLConfig +//======================================================================== + +static int getFBConfigAttrib(_GLFWwindow* window, EGLConfig fbconfig, int attrib) +{ + int value; + eglGetConfigAttrib(_glfwLibrary.EGL.display, fbconfig, attrib, &value); + return value; +} + + +//======================================================================== +// Return a list of available and usable framebuffer configs +//======================================================================== + +static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) +{ + EGLConfig fbconfigs[_GLFW_EGL_CONFIG_IN]; + _GLFWfbconfig* result; + int i, count = 0; + + *found = 0; + + + eglGetConfigs(_glfwLibrary.EGL.display, fbconfigs, + _GLFW_EGL_CONFIG_IN, &count); + if (!count) + { + _glfwSetError(GLFW_OPENGL_UNAVAILABLE, + "X11/EGL: No EGLConfigs returned"); + return NULL; + } + + result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count); + if (!result) + { + _glfwSetError(GLFW_OUT_OF_MEMORY, + "X11/EGL: Failed to allocate _GLFWfbconfig array"); + return NULL; + } + + for (i = 0; i < count; i++) + { + if (!getFBConfigAttrib(window, fbconfigs[i], EGL_NATIVE_VISUAL_ID)) + { + // Only consider EGLConfigs with associated visuals + continue; + } + + if (!(getFBConfigAttrib(window, + fbconfigs[i], + EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER)) + { + // Only consider RGB(A) EGLConfigs + continue; + } + + if (!(getFBConfigAttrib(window, fbconfigs[i], EGL_RENDERABLE_TYPE) & EGL_WINDOW_BIT)) + { + // Only consider window EGLConfigs + continue; + } + + result[*found].redBits = getFBConfigAttrib(window, fbconfigs[i], EGL_RED_SIZE); + result[*found].greenBits = getFBConfigAttrib(window, fbconfigs[i], EGL_GREEN_SIZE); + result[*found].blueBits = getFBConfigAttrib(window, fbconfigs[i], EGL_BLUE_SIZE); + + result[*found].alphaBits = getFBConfigAttrib(window, fbconfigs[i], EGL_ALPHA_SIZE); + result[*found].depthBits = getFBConfigAttrib(window, fbconfigs[i], EGL_DEPTH_SIZE); + result[*found].stencilBits = getFBConfigAttrib(window, fbconfigs[i], EGL_STENCIL_SIZE); + + result[*found].samples = getFBConfigAttrib(window, fbconfigs[i], EGL_SAMPLES); + + result[*found].platformID = (GLFWintptr) getFBConfigAttrib(window, fbconfigs[i], EGL_CONFIG_ID); + + (*found)++; + } + + return result; +} + +//======================================================================== +// Read back framebuffer parameters from the context +//======================================================================== + +static void refreshContextParams(_GLFWwindow* window, EGLint fbconfigID) +{ + EGLint dummy; + EGLConfig fbconfig[_GLFW_EGL_CONFIG_IN]; + + int attribs[] = { EGL_CONFIG_ID, fbconfigID, None }; + + eglChooseConfig(_glfwLibrary.EGL.display, + attribs, + fbconfig, + _GLFW_EGL_CONFIG_IN, + &dummy); + if (!dummy) + { + // This should never ever happen + // TODO: Flag this as an error and propagate up + _glfwSetError(GLFW_PLATFORM_ERROR, "X11/EGL: Cannot find known " + "EGLConfig by ID. This cannot " + "happen. Have a nice day.\n"); + abort(); + } + + // There is no clear definition of an "accelerated" context on X11/EGL, and + // true sounds better than false, so we hardcode true here + window->accelerated = GL_TRUE; + + window->redBits = getFBConfigAttrib(window, *fbconfig, EGL_RED_SIZE); + window->greenBits = getFBConfigAttrib(window, *fbconfig, EGL_GREEN_SIZE); + window->blueBits = getFBConfigAttrib(window, *fbconfig, EGL_BLUE_SIZE); + + window->alphaBits = getFBConfigAttrib(window, *fbconfig, EGL_ALPHA_SIZE); + window->depthBits = getFBConfigAttrib(window, *fbconfig, EGL_DEPTH_SIZE); + window->stencilBits = getFBConfigAttrib(window, *fbconfig, EGL_STENCIL_SIZE); + + // Get FSAA buffer sample count + window->samples = getFBConfigAttrib(window, *fbconfig, EGL_SAMPLES); +} + + +//======================================================================== +// Create the actual OpenGL(|ES) context +//======================================================================== + +#define setEGLattrib(attribs, index, attribName, attribValue) \ + attribs[index++] = attribName; \ + attribs[index++] = attribValue; + +static int createContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + EGLint fbconfigID) +{ + int attribs[40]; + EGLint dummy, index, vid; + EGLConfig fbconfig[_GLFW_EGL_CONFIG_IN]; + EGLContext share = NULL; + XVisualInfo visTemplate; + + if (wndconfig->share) + share = wndconfig->share->EGL.context; + + // Retrieve the previously selected EGLConfig + { + index = 0; + + setEGLattrib(attribs, index, EGL_CONFIG_ID, fbconfigID); + setEGLattrib(attribs, index, None, None); + + eglChooseConfig(_glfwLibrary.EGL.display, + attribs, + fbconfig, + _GLFW_EGL_CONFIG_IN, + &dummy); + + if (!dummy) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11/EGL: Failed to retrieve the selected EGLConfig"); + return GL_FALSE; + } + } + + // Retrieve the corresponding visual + if (!eglGetConfigAttrib(_glfwLibrary.EGL.display, *fbconfig, EGL_NATIVE_VISUAL_ID, &vid)) { + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11/EGL: Failed to retrieve visual for EGLConfig"); + return GL_FALSE; + } + + // The X window visual must match the EGL config + visTemplate.visualid = vid; + window->EGL.visual = XGetVisualInfo(_glfwLibrary.X11.display, VisualIDMask, &visTemplate, &dummy); + if (window->EGL.visual == NULL) { + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11/GLX: Failed to retrieve visual for EGLConfig"); + return GL_FALSE; + } + + if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE) + { + setEGLattrib(attribs, index, EGL_CONTEXT_CLIENT_VERSION, 2); + } + else + { + setEGLattrib(attribs, index, EGL_CONTEXT_CLIENT_VERSION, 1); + } + + setEGLattrib(attribs, index, EGL_NONE, EGL_NONE); + + eglBindAPI(EGL_OPENGL_ES_API); + + window->EGL.context = eglCreateContext(_glfwLibrary.EGL.display, *fbconfig, share, attribs); + if (window->EGL.context == EGL_NO_CONTEXT) + { + // TODO: Handle all the various error codes here + + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11/EGL: Failed to create OpenGL(|ES) context"); + return GL_FALSE; + } + + refreshContextParams(window, fbconfigID); + + return GL_TRUE; +} + +#undef setEGLattrib + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Initialize EGL +//======================================================================== + +int _glfwInitOpenGL(void) +{ +#ifdef _GLFW_DLOPEN_LIBGL + int i; + char* libEGL_names[ ] = + { + "libEGL.so", + "libEGL.so.1", + "/usr/lib/libEGL.so", + "/usr/lib/libEGL.so.1", + NULL + }; + + for (i = 0; libEGL_names[i] != NULL; i++) + { + _glfwLibrary.EGL.libEGL = dlopen(libEGL_names[i], RTLD_LAZY | RTLD_GLOBAL); + if (_glfwLibrary.EGL.libEGL) + break; + } + + if (!_glfwLibrary.EGL.libEGL) + { + _glfwSetError(GLFW_PLATFORM_ERROR, "X11/EGL: Failed to find libEGL"); + return GL_FALSE; + } +#endif + + _glfwLibrary.EGL.display = eglGetDisplay((EGLNativeDisplayType)_glfwLibrary.X11.display); + if (_glfwLibrary.EGL.display == EGL_NO_DISPLAY) + { + _glfwSetError(GLFW_OPENGL_UNAVAILABLE, + "X11/EGL: Failed to get EGL display"); + return GL_FALSE; + } + + if (!eglInitialize(_glfwLibrary.EGL.display, + &_glfwLibrary.EGL.majorVersion, + &_glfwLibrary.EGL.minorVersion)) + { + _glfwSetError(GLFW_OPENGL_UNAVAILABLE, + "X11/EGL: Failed to initialize EGL"); + return GL_FALSE; + } + + return GL_TRUE; +} + + +//======================================================================== +// Terminate EGL +//======================================================================== + +void _glfwTerminateOpenGL(void) +{ + // Unload libEGL.so if necessary +#ifdef _GLFW_DLOPEN_LIBGL + if (_glfwLibrary.EGL.libEGL != NULL) + { + dlclose(_glfwLibrary.EGL.libEGL); + _glfwLibrary.EGL.libEGL = NULL; + } +#endif + eglTerminate(_glfwLibrary.EGL.display); +} + + +//======================================================================== +// Prepare for creation of the OpenGL context +//======================================================================== + +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) +{ + _GLFWfbconfig closest; + + // Choose the best available fbconfig + { + unsigned int fbcount; + _GLFWfbconfig* fbconfigs; + const _GLFWfbconfig* result; + + fbconfigs = getFBConfigs(window, &fbcount); + if (!fbconfigs) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11/EGL: No usable EGLFBConfigs found"); + return GL_FALSE; + } + + result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); + if (!result) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11/EGL: No EGLFBConfig matched the criteria"); + + free(fbconfigs); + return GL_FALSE; + } + + closest = *result; + free(fbconfigs); + } + + return createContext(window, wndconfig, closest.platformID); +} + + +//======================================================================== +// Destroy the OpenGL context +//======================================================================== + +void _glfwDestroyContext(_GLFWwindow* window) +{ + if (window->EGL.context) + { + // Release and destroy the context + eglMakeCurrent(_glfwLibrary.EGL.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + window->EGL.context = NULL; + } +} + + +//======================================================================== +// Make the OpenGL context associated with the specified window current +//======================================================================== + +void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) +{ + if (window) + { + eglMakeCurrent(_glfwLibrary.EGL.display, + window->EGL.surface, + window->EGL.surface, + window->EGL.context); + } + else + eglMakeCurrent(_glfwLibrary.EGL.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); +} + + +//======================================================================== +// Swap OpenGL buffers +//======================================================================== + +void _glfwPlatformSwapBuffers(void) +{ + eglSwapBuffers(_glfwLibrary.EGL.display, + _glfwLibrary.currentWindow->EGL.surface); +} + + +//======================================================================== +// Set double buffering swap interval +//======================================================================== + +void _glfwPlatformSwapInterval(int interval) +{ + eglSwapInterval(_glfwLibrary.EGL.display, interval); +} + + +//======================================================================== +// Check if an OpenGL extension is available at runtime +//======================================================================== + +int _glfwPlatformExtensionSupported(const char* extension) +{ + const char* extensions; + + // Get list of GLX extensions + extensions = eglQueryString(_glfwLibrary.EGL.display, + EGL_EXTENSIONS); + if (extensions != NULL) + { + if (_glfwStringInExtensionString(extension, (unsigned char*)extensions)) + return GL_TRUE; + } + + return GL_FALSE; +} + + +//======================================================================== +// Get the function pointer to an OpenGL function +//======================================================================== + +void* _glfwPlatformGetProcAddress(const char* procname) +{ + return (void*) _glfw_eglGetProcAddress(procname); +} + + +//======================================================================== +// Copies the specified OpenGL state categories from src to dst +//======================================================================== + +void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long mask) +{ + // AFAIK, EGL doesn't have this +} + From 29b4ed4e9a6731a2ccda09020d65d84e1a5281a3 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 09:33:29 +0300 Subject: [PATCH 07/18] Don't build tests and examples when building with EGL --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd5c35aa..8680aec2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,10 @@ elseif (UNIX AND NOT APPLE) set(_GLFW_X11 1) if (GLFW_USE_EGL) set(_GLFW_X11_EGL 1) + set(GLFW_BUILD_EXAMPLES 0) + set(GLFW_BUILD_TESTS 0) message(STATUS "Building GLFW for X11 and EGL on a Unix-like system") + message(STATUS "NOTE: Examples and tests are disabled for EGL") else() set(_GLFW_X11_GLX 1) message(STATUS "Building GLFW for X11 and GLX on a Unix-like system") From d99e2385c12e41085cd9fc90c8be9c260f23e19a Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 09:34:00 +0300 Subject: [PATCH 08/18] Add temporary #ifdef in x11_fullscreen so EGL compiles --- src/x11_fullscreen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/x11_fullscreen.c b/src/x11_fullscreen.c index 7ad11ec5..a17acde4 100644 --- a/src/x11_fullscreen.c +++ b/src/x11_fullscreen.c @@ -357,6 +357,8 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) rgbarray = (int*) malloc(sizeof(int) * viscount); rgbcount = 0; + // Temporary solution +#if !defined(_GLFW_X11_EGL) // Build RGB array for (k = 0; k < viscount; k++) { @@ -386,6 +388,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) } } } +#endif XFree(vislist); From 28db982d0ab3565bd1817b7bacf686140b6a8b47 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 09:34:42 +0300 Subject: [PATCH 09/18] Add x11_fullscreen.c to the source list --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9a4fba68..3ba760f9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,7 +27,7 @@ elseif (_GLFW_X11_GLX) x11_keysym2unicode.c x11_opengl.c x11_time.c x11_window.c) elseif (_GLFW_X11_EGL) set(glfw_HEADERS ${common_HEADERS} x11_egl_platform.h) - set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c + set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c x11_gamma.c x11_init.c x11_input.c x11_joystick.c x11_keysym2unicode.c x11_egl_opengl.c x11_time.c x11_window.c) endif() From e06515eaa09f2baf73532cc678c0f51c0039d581 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 09:35:02 +0300 Subject: [PATCH 10/18] Improve OpenGL version parsing from string --- src/opengl.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/opengl.c b/src/opengl.c index 67b5e728..957e4d24 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -32,6 +32,7 @@ #include #include +#include //======================================================================== @@ -42,13 +43,16 @@ static void parseGLVersion(int* major, int* minor, int* rev) { GLuint _major, _minor = 0, _rev = 0; const GLubyte* version; - const GLubyte* ptr; - const char* glesPrefix = "OpenGL ES "; version = glGetString(GL_VERSION); if (!version) return; +#if 0 + // Old version detection code. This doesn't work very well + const GLubyte* ptr; + const char* glesPrefix = "OpenGL ES "; + if (strncmp((const char*) version, glesPrefix, strlen(glesPrefix)) == 0) { // The version string on OpenGL ES has a prefix before the version @@ -76,6 +80,12 @@ static void parseGLVersion(int* major, int* minor, int* rev) _rev = 10 * _rev + (*ptr - '0'); } } +#endif + + // Find version from OpenGL string + for (; version && + !sscanf(version, "%d.%d.%d", &_major, &_minor, &_rev); + ++version); // Store result *major = _major; From 478eac2fe0a5101f42adb945badb52be6976fad1 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 09:35:47 +0300 Subject: [PATCH 11/18] Create window surface and add fallback for visual info retival --- src/x11_egl_opengl.c | 110 ++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 32 deletions(-) diff --git a/src/x11_egl_opengl.c b/src/x11_egl_opengl.c index efbadc06..12bf71f5 100644 --- a/src/x11_egl_opengl.c +++ b/src/x11_egl_opengl.c @@ -40,7 +40,7 @@ // Returns the specified attribute of the specified EGLConfig //======================================================================== -static int getFBConfigAttrib(_GLFWwindow* window, EGLConfig fbconfig, int attrib) +static int getFBConfigAttrib(EGLConfig fbconfig, int attrib) { int value; eglGetConfigAttrib(_glfwLibrary.EGL.display, fbconfig, attrib, &value); @@ -80,37 +80,36 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) for (i = 0; i < count; i++) { - if (!getFBConfigAttrib(window, fbconfigs[i], EGL_NATIVE_VISUAL_ID)) + if (!getFBConfigAttrib(fbconfigs[i], EGL_NATIVE_VISUAL_ID)) { // Only consider EGLConfigs with associated visuals continue; } - if (!(getFBConfigAttrib(window, - fbconfigs[i], + if (!(getFBConfigAttrib(fbconfigs[i], EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER)) { // Only consider RGB(A) EGLConfigs continue; } - if (!(getFBConfigAttrib(window, fbconfigs[i], EGL_RENDERABLE_TYPE) & EGL_WINDOW_BIT)) + if (!(getFBConfigAttrib(fbconfigs[i], EGL_RENDERABLE_TYPE) & EGL_WINDOW_BIT)) { // Only consider window EGLConfigs continue; } - result[*found].redBits = getFBConfigAttrib(window, fbconfigs[i], EGL_RED_SIZE); - result[*found].greenBits = getFBConfigAttrib(window, fbconfigs[i], EGL_GREEN_SIZE); - result[*found].blueBits = getFBConfigAttrib(window, fbconfigs[i], EGL_BLUE_SIZE); + result[*found].redBits = getFBConfigAttrib(fbconfigs[i], EGL_RED_SIZE); + result[*found].greenBits = getFBConfigAttrib(fbconfigs[i], EGL_GREEN_SIZE); + result[*found].blueBits = getFBConfigAttrib(fbconfigs[i], EGL_BLUE_SIZE); - result[*found].alphaBits = getFBConfigAttrib(window, fbconfigs[i], EGL_ALPHA_SIZE); - result[*found].depthBits = getFBConfigAttrib(window, fbconfigs[i], EGL_DEPTH_SIZE); - result[*found].stencilBits = getFBConfigAttrib(window, fbconfigs[i], EGL_STENCIL_SIZE); + result[*found].alphaBits = getFBConfigAttrib(fbconfigs[i], EGL_ALPHA_SIZE); + result[*found].depthBits = getFBConfigAttrib(fbconfigs[i], EGL_DEPTH_SIZE); + result[*found].stencilBits = getFBConfigAttrib(fbconfigs[i], EGL_STENCIL_SIZE); - result[*found].samples = getFBConfigAttrib(window, fbconfigs[i], EGL_SAMPLES); + result[*found].samples = getFBConfigAttrib(fbconfigs[i], EGL_SAMPLES); - result[*found].platformID = (GLFWintptr) getFBConfigAttrib(window, fbconfigs[i], EGL_CONFIG_ID); + result[*found].platformID = (GLFWintptr) getFBConfigAttrib(fbconfigs[i], EGL_CONFIG_ID); (*found)++; } @@ -148,16 +147,16 @@ static void refreshContextParams(_GLFWwindow* window, EGLint fbconfigID) // true sounds better than false, so we hardcode true here window->accelerated = GL_TRUE; - window->redBits = getFBConfigAttrib(window, *fbconfig, EGL_RED_SIZE); - window->greenBits = getFBConfigAttrib(window, *fbconfig, EGL_GREEN_SIZE); - window->blueBits = getFBConfigAttrib(window, *fbconfig, EGL_BLUE_SIZE); + window->redBits = getFBConfigAttrib(*fbconfig, EGL_RED_SIZE); + window->greenBits = getFBConfigAttrib(*fbconfig, EGL_GREEN_SIZE); + window->blueBits = getFBConfigAttrib(*fbconfig, EGL_BLUE_SIZE); - window->alphaBits = getFBConfigAttrib(window, *fbconfig, EGL_ALPHA_SIZE); - window->depthBits = getFBConfigAttrib(window, *fbconfig, EGL_DEPTH_SIZE); - window->stencilBits = getFBConfigAttrib(window, *fbconfig, EGL_STENCIL_SIZE); + window->alphaBits = getFBConfigAttrib(*fbconfig, EGL_ALPHA_SIZE); + window->depthBits = getFBConfigAttrib(*fbconfig, EGL_DEPTH_SIZE); + window->stencilBits = getFBConfigAttrib(*fbconfig, EGL_STENCIL_SIZE); // Get FSAA buffer sample count - window->samples = getFBConfigAttrib(window, *fbconfig, EGL_SAMPLES); + window->samples = getFBConfigAttrib(*fbconfig, EGL_SAMPLES); } @@ -173,8 +172,9 @@ static int createContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, EGLint fbconfigID) { - int attribs[40]; - EGLint dummy, index, vid; + int attribs[40], visMask; + EGLint dummy, index, vid = 0; + EGLint red_size, green_size, blue_size, alpha_size; EGLConfig fbconfig[_GLFW_EGL_CONFIG_IN]; EGLContext share = NULL; XVisualInfo visTemplate; @@ -187,7 +187,7 @@ static int createContext(_GLFWwindow* window, index = 0; setEGLattrib(attribs, index, EGL_CONFIG_ID, fbconfigID); - setEGLattrib(attribs, index, None, None); + setEGLattrib(attribs, index, EGL_NONE, EGL_NONE); eglChooseConfig(_glfwLibrary.EGL.display, attribs, @@ -204,21 +204,47 @@ static int createContext(_GLFWwindow* window, } // Retrieve the corresponding visual - if (!eglGetConfigAttrib(_glfwLibrary.EGL.display, *fbconfig, EGL_NATIVE_VISUAL_ID, &vid)) { - _glfwSetError(GLFW_PLATFORM_ERROR, - "X11/EGL: Failed to retrieve visual for EGLConfig"); - return GL_FALSE; + // NOTE: This is the only non-portable code in this file. + // Maybe it would not hurt too much to add #ifdefs for different platforms? + eglGetConfigAttrib(_glfwLibrary.EGL.display, *fbconfig, EGL_NATIVE_VISUAL_ID, &vid); + + // Init visual template + visTemplate.screen = _glfwLibrary.X11.screen; + visMask = VisualScreenMask; + + if (vid != 0) + { + // The X window visual must match the EGL config + visTemplate.visualid = vid; + visMask |= VisualIDMask; + } + else + { + // some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID + // attribute, so attempt to find the closest match. + + eglGetConfigAttrib(_glfwLibrary.EGL.display, *fbconfig, + EGL_RED_SIZE, &red_size); + eglGetConfigAttrib (_glfwLibrary.EGL.display, *fbconfig, + EGL_GREEN_SIZE, &green_size); + eglGetConfigAttrib (_glfwLibrary.EGL.display, *fbconfig, + EGL_BLUE_SIZE, &blue_size); + eglGetConfigAttrib (_glfwLibrary.EGL.display, *fbconfig, + EGL_ALPHA_SIZE, &alpha_size); + + visTemplate.depth = red_size + green_size + blue_size + alpha_size; + visMask |= VisualDepthMask; } - // The X window visual must match the EGL config - visTemplate.visualid = vid; - window->EGL.visual = XGetVisualInfo(_glfwLibrary.X11.display, VisualIDMask, &visTemplate, &dummy); + // Get X Visual + window->EGL.visual = XGetVisualInfo(_glfwLibrary.X11.display, visMask, &visTemplate, &dummy); if (window->EGL.visual == NULL) { _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to retrieve visual for EGLConfig"); return GL_FALSE; } + index = 0; if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE) { setEGLattrib(attribs, index, EGL_CONTEXT_CLIENT_VERSION, 2); @@ -242,6 +268,9 @@ static int createContext(_GLFWwindow* window, return GL_FALSE; } + // store configuraion + window->EGL.config = *fbconfig; + refreshContextParams(window, fbconfigID); return GL_TRUE; @@ -372,11 +401,18 @@ int _glfwCreateContext(_GLFWwindow* window, void _glfwDestroyContext(_GLFWwindow* window) { + if (window->EGL.surface) + { + // Release and destroy the surface + eglDestroySurface(_glfwLibrary.EGL.display, window->EGL.surface); + window->EGL.surface = EGL_NO_SURFACE; + } + if (window->EGL.context) { // Release and destroy the context - eglMakeCurrent(_glfwLibrary.EGL.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - window->EGL.context = NULL; + eglDestroyContext(_glfwLibrary.EGL.display, window->EGL.context); + window->EGL.context = EGL_NO_CONTEXT; } } @@ -389,6 +425,16 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) { if (window) { + if (window->EGL.surface == EGL_NO_SURFACE) + { + window->EGL.surface = eglCreateWindowSurface(_glfwLibrary.EGL.display, + window->EGL.config, (EGLNativeWindowType)window->X11.handle, NULL); + if (window->EGL.surface == EGL_NO_SURFACE) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11/EGL: Failed to create window surface"); + } + } eglMakeCurrent(_glfwLibrary.EGL.display, window->EGL.surface, window->EGL.surface, From 819b09d479dc1eac5adad7718fb934117ea584a3 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Wed, 25 Apr 2012 09:36:38 +0300 Subject: [PATCH 12/18] Add member struct defines for window's context members so code can be shared --- src/x11_egl_platform.h | 1 + src/x11_platform.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/x11_egl_platform.h b/src/x11_egl_platform.h index b1fb53cb..f2fe4092 100644 --- a/src/x11_egl_platform.h +++ b/src/x11_egl_platform.h @@ -76,6 +76,7 @@ #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL EGL #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 X11 #define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryEGL EGL +#define _GLFW_CTX EGL // Clipboard format atom indices #define _GLFW_CLIPBOARD_FORMAT_UTF8 0 diff --git a/src/x11_platform.h b/src/x11_platform.h index 39593655..28e749fe 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -85,6 +85,7 @@ #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 X11 #define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryGLX GLX +#define _GLFW_CTX GLX // Clipboard format atom indices #define _GLFW_CLIPBOARD_FORMAT_UTF8 0 From 2815630688ce777f9bd34408ee7365ef04e74b0e Mon Sep 17 00:00:00 2001 From: Cloudef Date: Thu, 26 Apr 2012 02:26:01 +0300 Subject: [PATCH 13/18] Reflect X visual changes to EGL code --- src/x11_egl_opengl.c | 14 ++++++++++++++ src/x11_egl_platform.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/x11_egl_opengl.c b/src/x11_egl_opengl.c index 12bf71f5..923e3e22 100644 --- a/src/x11_egl_opengl.c +++ b/src/x11_egl_opengl.c @@ -401,6 +401,12 @@ int _glfwCreateContext(_GLFWwindow* window, void _glfwDestroyContext(_GLFWwindow* window) { + if (window->EGL.visual) + { + XFree(window->EGL.visual); + window->EGL.visual = NULL; + } + if (window->EGL.surface) { // Release and destroy the surface @@ -416,6 +422,14 @@ void _glfwDestroyContext(_GLFWwindow* window) } } +//======================================================================== +// Return the X visual associated with the specified context +//======================================================================== + +XVisualInfo* _glfwGetContextVisual(_GLFWwindow* window) +{ + return window->EGL.visual; +} //======================================================================== // Make the OpenGL context associated with the specified window current diff --git a/src/x11_egl_platform.h b/src/x11_egl_platform.h index f2fe4092..87ba39a0 100644 --- a/src/x11_egl_platform.h +++ b/src/x11_egl_platform.h @@ -262,6 +262,7 @@ int _glfwCreateContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyContext(_GLFWwindow* window); +XVisualInfo* _glfwGetContextVisual(_GLFWwindow* window); // Fullscreen support int _glfwGetClosestVideoMode(int* width, int* height, int* rate); From 5cf8b8d3fa949e400a6b30b94630eb415a040177 Mon Sep 17 00:00:00 2001 From: Cloudef Date: Fri, 11 May 2012 23:02:38 +0300 Subject: [PATCH 14/18] Remove useless define --- src/x11_egl_platform.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/x11_egl_platform.h b/src/x11_egl_platform.h index 87ba39a0..9e0e21b4 100644 --- a/src/x11_egl_platform.h +++ b/src/x11_egl_platform.h @@ -76,7 +76,6 @@ #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL EGL #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 X11 #define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryEGL EGL -#define _GLFW_CTX EGL // Clipboard format atom indices #define _GLFW_CLIPBOARD_FORMAT_UTF8 0 From 2e7d91ea5a3c25f0cc8b7547461eb40f580f9219 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 30 Jun 2012 22:25:26 +0300 Subject: [PATCH 15/18] Only consider OpenGL ES contexes EGL_WINDOW_BIT is compared agaist wrong attribute --- src/x11_egl_opengl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/x11_egl_opengl.c b/src/x11_egl_opengl.c index 923e3e22..7df15963 100644 --- a/src/x11_egl_opengl.c +++ b/src/x11_egl_opengl.c @@ -93,12 +93,19 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) continue; } - if (!(getFBConfigAttrib(fbconfigs[i], EGL_RENDERABLE_TYPE) & EGL_WINDOW_BIT)) + if (!(getFBConfigAttrib(fbconfigs[i], EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) { // Only consider window EGLConfigs continue; } + if (!(getFBConfigAttrib(fbconfigs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT) && + !(getFBConfigAttrib(fbconfigs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) + { + // Only consider OpenGL ES context + continue; + } + result[*found].redBits = getFBConfigAttrib(fbconfigs[i], EGL_RED_SIZE); result[*found].greenBits = getFBConfigAttrib(fbconfigs[i], EGL_GREEN_SIZE); result[*found].blueBits = getFBConfigAttrib(fbconfigs[i], EGL_BLUE_SIZE); From 739be03373aea279e0bb6c7566e1af094fac247e Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 30 Jun 2012 22:35:26 +0300 Subject: [PATCH 16/18] Obey the OPENGL_ES2_PROFILE hint --- src/x11_egl_opengl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/x11_egl_opengl.c b/src/x11_egl_opengl.c index 7df15963..90507f86 100644 --- a/src/x11_egl_opengl.c +++ b/src/x11_egl_opengl.c @@ -52,7 +52,7 @@ static int getFBConfigAttrib(EGLConfig fbconfig, int attrib) // Return a list of available and usable framebuffer configs //======================================================================== -static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) +static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, unsigned int* found) { EGLConfig fbconfigs[_GLFW_EGL_CONFIG_IN]; _GLFWfbconfig* result; @@ -106,6 +106,13 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) continue; } + if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE && + !(getFBConfigAttrib(fbconfigs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) + { + // User requested only OpenGL ES 2.0 context + continue; + } + result[*found].redBits = getFBConfigAttrib(fbconfigs[i], EGL_RED_SIZE); result[*found].greenBits = getFBConfigAttrib(fbconfigs[i], EGL_GREEN_SIZE); result[*found].blueBits = getFBConfigAttrib(fbconfigs[i], EGL_BLUE_SIZE); @@ -376,7 +383,7 @@ int _glfwCreateContext(_GLFWwindow* window, _GLFWfbconfig* fbconfigs; const _GLFWfbconfig* result; - fbconfigs = getFBConfigs(window, &fbcount); + fbconfigs = getFBConfigs(window, wndconfig, &fbcount); if (!fbconfigs) { _glfwSetError(GLFW_PLATFORM_ERROR, From db0a4b599d6275c832f2a2cfa540f2f7eaa071fa Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Tue, 17 Jul 2012 22:29:09 +0300 Subject: [PATCH 17/18] Fix GLubyte warning, by casting to (char*) --- src/opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl.c b/src/opengl.c index 957e4d24..59097e1e 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -84,7 +84,7 @@ static void parseGLVersion(int* major, int* minor, int* rev) // Find version from OpenGL string for (; version && - !sscanf(version, "%d.%d.%d", &_major, &_minor, &_rev); + !sscanf((char*)version, "%d.%d.%d", &_major, &_minor, &_rev); ++version); // Store result From 6b1344af3cb283f751edba3a036f6aeccb98b6a4 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Tue, 17 Jul 2012 23:06:30 +0300 Subject: [PATCH 18/18] Use GLFWglproc return type --- src/x11_egl_opengl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/x11_egl_opengl.c b/src/x11_egl_opengl.c index 90507f86..e1eed5cd 100644 --- a/src/x11_egl_opengl.c +++ b/src/x11_egl_opengl.c @@ -519,9 +519,9 @@ int _glfwPlatformExtensionSupported(const char* extension) // Get the function pointer to an OpenGL function //======================================================================== -void* _glfwPlatformGetProcAddress(const char* procname) +GLFWglproc _glfwPlatformGetProcAddress(const char* procname) { - return (void*) _glfw_eglGetProcAddress(procname); + return _glfw_eglGetProcAddress(procname); }