Merge pull request #9 from Cloudef/EGL

EGL work.
This commit is contained in:
Camilla Löwy Berglund 2012-07-19 07:49:07 -07:00
commit 11143baa95
10 changed files with 951 additions and 15 deletions

View File

@ -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)

View File

@ -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_EXAMPLES "Build the GLFW example programs" ON)
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF) 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 # Enable all warnings on GCC, regardless of OS
@ -39,8 +45,17 @@ elseif (UNIX AND APPLE)
set(_GLFW_COCOA_NSGL 1) set(_GLFW_COCOA_NSGL 1)
message(STATUS "Building GLFW for Cocoa and NSOpenGL on Mac OS X") message(STATUS "Building GLFW for Cocoa and NSOpenGL on Mac OS X")
elseif (UNIX AND NOT APPLE) elseif (UNIX AND NOT APPLE)
set(_GLFW_X11_GLX 1) set(_GLFW_X11 1)
message(STATUS "Building GLFW for X11 and GLX on a Unix-like system") 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")
endif()
else() else()
message(FATAL_ERROR "No supported platform was detected") message(FATAL_ERROR "No supported platform was detected")
endif() endif()
@ -62,20 +77,18 @@ if (_GLFW_WIN32_WGL)
endif() 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) 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_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) # Check for XRandR (modern resolution switching extension)
if (X11_Xrandr_FOUND) if (X11_Xrandr_FOUND)
@ -121,6 +134,25 @@ if (_GLFW_X11_GLX)
set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -lm") set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -lm")
endif() 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}) set(CMAKE_REQUIRED_LIBRARIES ${OPENGL_gl_LIBRARY})
check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS)
@ -160,9 +192,50 @@ if (_GLFW_X11_GLX)
endif() endif()
endif() endif()
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") endif()
set(_GLFW_USE_LINUX_JOYSTICKS 1)
#--------------------------------------------------------------------
# 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()
endif() endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------

View File

@ -25,6 +25,11 @@ elseif (_GLFW_X11_GLX)
set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.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_gamma.c x11_init.c x11_input.c x11_joystick.c
x11_keysym2unicode.c x11_opengl.c x11_time.c x11_window.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_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() endif()
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})

View File

@ -37,6 +37,8 @@
// Define this to 1 if building GLFW for X11/GLX // Define this to 1 if building GLFW for X11/GLX
#cmakedefine _GLFW_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 // Define this to 1 if building GLFW for Win32/WGL
#cmakedefine _GLFW_WIN32_WGL #cmakedefine _GLFW_WIN32_WGL
// Define this to 1 if building GLFW for Cocoa/NSOpenGL // Define this to 1 if building GLFW for Cocoa/NSOpenGL
@ -63,6 +65,9 @@
// Define this to 1 if glXGetProcAddressEXT is available // Define this to 1 if glXGetProcAddressEXT is available
#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSEXT #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 // Define this to 1 if the Linux joystick API is available
#cmakedefine _GLFW_USE_LINUX_JOYSTICKS #cmakedefine _GLFW_USE_LINUX_JOYSTICKS

View File

@ -82,6 +82,8 @@ typedef struct _GLFWlibrary _GLFWlibrary;
#include "win32_platform.h" #include "win32_platform.h"
#elif defined(_GLFW_X11_GLX) #elif defined(_GLFW_X11_GLX)
#include "x11_platform.h" #include "x11_platform.h"
#elif defined(_GLFW_X11_EGL)
#include "x11_egl_platform.h"
#else #else
#error "No supported platform selected" #error "No supported platform selected"
#endif #endif

View File

@ -32,6 +32,7 @@
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <stdio.h>
//======================================================================== //========================================================================
@ -42,13 +43,16 @@ static void parseGLVersion(int* major, int* minor, int* rev)
{ {
GLuint _major, _minor = 0, _rev = 0; GLuint _major, _minor = 0, _rev = 0;
const GLubyte* version; const GLubyte* version;
const GLubyte* ptr;
const char* glesPrefix = "OpenGL ES ";
version = glGetString(GL_VERSION); version = glGetString(GL_VERSION);
if (!version) if (!version)
return; 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) if (strncmp((const char*) version, glesPrefix, strlen(glesPrefix)) == 0)
{ {
// The version string on OpenGL ES has a prefix before the version // 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'); _rev = 10 * _rev + (*ptr - '0');
} }
} }
#endif
// Find version from OpenGL string
for (; version &&
!sscanf((char*)version, "%d.%d.%d", &_major, &_minor, &_rev);
++version);
// Store result // Store result
*major = _major; *major = _major;

536
src/x11_egl_opengl.c Normal file
View File

@ -0,0 +1,536 @@
//========================================================================
// 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 <elmindreda@elmindreda.org>
//
// 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 <stdio.h>
#include <stdlib.h>
// Max number of EGL configuration we handle
#define _GLFW_EGL_CONFIG_IN 15
//========================================================================
// Returns the specified attribute of the specified EGLConfig
//========================================================================
static int getFBConfigAttrib(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, const _GLFWwndconfig* wndconfig, 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(fbconfigs[i], EGL_NATIVE_VISUAL_ID))
{
// Only consider EGLConfigs with associated visuals
continue;
}
if (!(getFBConfigAttrib(fbconfigs[i],
EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER))
{
// Only consider RGB(A) EGLConfigs
continue;
}
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;
}
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);
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(fbconfigs[i], EGL_SAMPLES);
result[*found].platformID = (GLFWintptr) getFBConfigAttrib(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(*fbconfig, EGL_RED_SIZE);
window->greenBits = getFBConfigAttrib(*fbconfig, EGL_GREEN_SIZE);
window->blueBits = getFBConfigAttrib(*fbconfig, EGL_BLUE_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(*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], 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;
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, EGL_NONE, EGL_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
// 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;
}
// 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);
}
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;
}
// store configuraion
window->EGL.config = *fbconfig;
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, wndconfig, &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.visual)
{
XFree(window->EGL.visual);
window->EGL.visual = NULL;
}
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
eglDestroyContext(_glfwLibrary.EGL.display, window->EGL.context);
window->EGL.context = EGL_NO_CONTEXT;
}
}
//========================================================================
// 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
//========================================================================
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,
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
//========================================================================
GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
{
return _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
}

286
src/x11_egl_platform.h Normal file
View File

@ -0,0 +1,286 @@
//========================================================================
// 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 <elmindreda@elmindreda.org>
//
// 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 <unistd.h>
#include <signal.h>
#include <stdint.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
// Include EGL
#include <EGL/egl.h>
// With XFree86, we can use the XF86VidMode extension
#if defined(_GLFW_HAS_XF86VIDMODE)
#include <X11/extensions/xf86vmode.h>
#endif
#if defined(_GLFW_HAS_XRANDR)
#include <X11/extensions/Xrandr.h>
#endif
// Do we have support for dlopen/dlsym?
#if defined(_GLFW_HAS_DLOPEN)
#include <dlfcn.h>
#endif
// The Xkb extension provides improved keyboard support
#if defined(_GLFW_HAS_XKB)
#include <X11/XKBlib.h>
#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);
XVisualInfo* _glfwGetContextVisual(_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_

View File

@ -357,6 +357,8 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
rgbarray = (int*) malloc(sizeof(int) * viscount); rgbarray = (int*) malloc(sizeof(int) * viscount);
rgbcount = 0; rgbcount = 0;
// Temporary solution
#if !defined(_GLFW_X11_EGL)
// Build RGB array // Build RGB array
for (k = 0; k < viscount; k++) for (k = 0; k < viscount; k++)
{ {
@ -386,6 +388,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
} }
} }
} }
#endif
XFree(vislist); XFree(vislist);

View File

@ -85,6 +85,7 @@
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 X11 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 X11
#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryGLX GLX #define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryGLX GLX
#define _GLFW_CTX GLX
// Clipboard format atom indices // Clipboard format atom indices
#define _GLFW_CLIPBOARD_FORMAT_UTF8 0 #define _GLFW_CLIPBOARD_FORMAT_UTF8 0