From 5d6c1b44f4040b967ce55f9db465aa1af874099f Mon Sep 17 00:00:00 2001 From: beuc Date: Sun, 18 Mar 2012 12:38:07 +0000 Subject: [PATCH] Add support for X11+EGL. The changes are made with minimalism and clarity in mind: - Either the functions are common and are kept in _x11.c files - Either the functions have small differences and dealt with #ifdef - Either the functions are largely different, and split in: - Specialized portable code in egl/ - Specialized GLX code in _x11_glx.c files Using EGL or GLX is decided at compile time (CMake FREEGLUT_GLES1 or FREEGLUT_GLES2 option enabled).. git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1196 7f0cb862-5218-0410-a997-914c9d46530a --- freeglut/freeglut/CMakeLists.txt | 19 +- freeglut/freeglut/src/x11/fg_init_x11.c | 6 + freeglut/freeglut/src/x11/fg_internal_x11.h | 28 +- freeglut/freeglut/src/x11/fg_state_x11.c | 325 ++++------------ freeglut/freeglut/src/x11/fg_structure_x11.c | 4 + freeglut/freeglut/src/x11/fg_window_x11.c | 379 +++---------------- 6 files changed, 166 insertions(+), 595 deletions(-) diff --git a/freeglut/freeglut/CMakeLists.txt b/freeglut/freeglut/CMakeLists.txt index 9ca349d..2f0b146 100644 --- a/freeglut/freeglut/CMakeLists.txt +++ b/freeglut/freeglut/CMakeLists.txt @@ -125,7 +125,6 @@ ELSEIF(ANDROID) ELSE() LIST(APPEND FREEGLUT_SRCS src/x11/fg_cursor_x11.c - src/x11/fg_display_x11.c src/x11/fg_ext_x11.c src/x11/fg_gamemode_x11.c src/x11/fg_glutfont_definitions_x11.c @@ -141,6 +140,24 @@ ELSE() src/x11/fg_window_x11.c src/x11/fg_xinput_x11.c ) + IF(FREEGLUT_GLES2 OR FREEGLUT_GLES1) + LIST(APPEND FREEGLUT_SRCS + src/egl/fg_internal_egl.h + src/egl/fg_display_egl.c + src/egl/fg_init_egl.c + src/egl/fg_state_egl.c + src/egl/fg_structure_egl.c + src/egl/fg_window_egl.c + ) + ELSE() + LIST(APPEND FREEGLUT_SRCS + src/x11/fg_internal_x11_glx.h + src/x11/fg_display_x11_glx.c + src/x11/fg_state_x11_glx.c + src/x11/fg_window_x11_glx.c + src/x11/fg_window_x11_glx.h + ) + ENDIF() ENDIF() # For OpenGL ES (GLES): diff --git a/freeglut/freeglut/src/x11/fg_init_x11.c b/freeglut/freeglut/src/x11/fg_init_x11.c index 83fe287..45ac0d1 100644 --- a/freeglut/freeglut/src/x11/fg_init_x11.c +++ b/freeglut/freeglut/src/x11/fg_init_x11.c @@ -174,9 +174,13 @@ void fgPlatformInitialize( const char* displayName ) if( fgDisplay.pDisplay.Display == NULL ) fgError( "failed to open display '%s'", XDisplayName( displayName ) ); +#ifdef EGL_VERSION_1_0 + fghPlatformInitializeEGL(); +#else if( !glXQueryExtension( fgDisplay.pDisplay.Display, NULL, NULL ) ) fgError( "OpenGL GLX extension not supported by display '%s'", XDisplayName( displayName ) ); +#endif fgDisplay.pDisplay.Screen = DefaultScreen( fgDisplay.pDisplay.Display ); fgDisplay.pDisplay.RootWindow = RootWindow( @@ -266,8 +270,10 @@ void fgPlatformCloseDisplay ( void ) } +#ifndef EGL_VERSION_1_0 void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext ) { /* Note that the MVisualInfo is not owned by the MenuContext! */ glXDestroyContext( pDisplay.Display, MContext ); } +#endif diff --git a/freeglut/freeglut/src/x11/fg_internal_x11.h b/freeglut/freeglut/src/x11/fg_internal_x11.h index 8a8e197..0d969f4 100644 --- a/freeglut/freeglut/src/x11/fg_internal_x11.h +++ b/freeglut/freeglut/src/x11/fg_internal_x11.h @@ -30,7 +30,12 @@ /* -- PLATFORM-SPECIFIC INCLUDES ------------------------------------------- */ +#ifdef EGL_VERSION_1_0 +#include "egl/fg_internal_egl.h" +#else #include +#include "x11/fg_internal_x11_glx.h" +#endif #include #include #include @@ -41,15 +46,6 @@ #ifdef HAVE_X11_EXTENSIONS_XRANDR_H # include #endif -/* If GLX is too old, we will fail during runtime when multisampling - is requested, but at least freeglut compiles. */ -#ifndef GLX_SAMPLE_BUFFERS -# define GLX_SAMPLE_BUFFERS 0x80A8 -#endif -#ifndef GLX_SAMPLES -# define GLX_SAMPLES 0x80A9 -#endif - /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ @@ -83,6 +79,10 @@ struct tagSFG_PlatformDisplay int DisplayViewPortY; /* saved Y location of the viewport */ #endif /* HAVE_X11_EXTENSIONS_XF86VMODE_H */ +#ifdef EGL_VERSION_1_0 + struct tagSFG_PlatformDisplayEGL egl; +#endif + int DisplayPointerX; /* saved X location of the pointer */ int DisplayPointerY; /* saved Y location of the pointer */ }; @@ -93,11 +93,19 @@ struct tagSFG_PlatformDisplay * much conditionally-compiled code later in the library. */ typedef Window SFG_WindowHandleType ; +#ifdef EGL_VERSION_1_0 +typedef EGLContext SFG_WindowContextType ; +#else typedef GLXContext SFG_WindowContextType ; +#endif typedef struct tagSFG_PlatformContext SFG_PlatformContext; struct tagSFG_PlatformContext { - GLXFBConfig* FBConfig; /* The window's FBConfig */ +#ifdef EGL_VERSION_1_0 + struct tagSFG_PlatformContextEGL egl; +#else + GLXFBConfig FBConfig; /* The window's FBConfig */ +#endif }; diff --git a/freeglut/freeglut/src/x11/fg_state_x11.c b/freeglut/freeglut/src/x11/fg_state_x11.c index 3523477..9765319 100644 --- a/freeglut/freeglut/src/x11/fg_state_x11.c +++ b/freeglut/freeglut/src/x11/fg_state_x11.c @@ -28,95 +28,50 @@ #include #include "../fg_internal.h" -/* - * TODO BEFORE THE STABLE RELEASE: - * - * fgPlatformChooseFBConfig() -- OK, but what about glutInitDisplayString()? - */ - -/* A helper function to check if a display mode is possible to use */ -GLXFBConfig* fgPlatformChooseFBConfig( int* numcfgs ); - -/* - * Queries the GL context about some attributes - */ -int fgPlatformGetConfig( int attribute ) +int fgPlatformGlutDeviceGet ( GLenum eWhat ) { - int returnValue = 0; - int result; /* Not checked */ + switch( eWhat ) + { + case GLUT_HAS_KEYBOARD: + /* + * X11 has a core keyboard by definition, although it can + * be present as a virtual/dummy keyboard. For now, there + * is no reliable way to tell if a real keyboard is present. + */ + return 1; - if( fgStructure.CurrentWindow ) - result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display, - *(fgStructure.CurrentWindow->Window.pContext.FBConfig), - attribute, - &returnValue ); + /* X11 has a mouse by definition */ + case GLUT_HAS_MOUSE: + return 1 ; - return returnValue; + case GLUT_NUM_MOUSE_BUTTONS: + /* We should be able to pass NULL when the last argument is zero, + * but at least one X server has a bug where this causes a segfault. + * + * In XFree86/Xorg servers, a mouse wheel is seen as two buttons + * rather than an Axis; "freeglut_main.c" expects this when + * checking for a wheel event. + */ + { + unsigned char map; + int nbuttons = XGetPointerMapping(fgDisplay.pDisplay.Display, &map,0); + return nbuttons; + } + + default: + fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat ); + break; + } + + /* And now -- the failure. */ + return -1; } + int fgPlatformGlutGet ( GLenum eWhat ) { - int nsamples = 0; - switch( eWhat ) { - /* - * The window/context specific queries are handled mostly by - * fgPlatformGetConfig(). - */ - case GLUT_WINDOW_NUM_SAMPLES: -#ifdef GLX_VERSION_1_3 - glGetIntegerv(GL_SAMPLES, &nsamples); -#endif - return nsamples; - - /* - * The rest of GLX queries under X are general enough to use a macro to - * check them - */ -# define GLX_QUERY(a,b) case a: return fgPlatformGetConfig( b ); - - GLX_QUERY( GLUT_WINDOW_RGBA, GLX_RGBA ); - GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER, GLX_DOUBLEBUFFER ); - GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE, GLX_BUFFER_SIZE ); - GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE, GLX_STENCIL_SIZE ); - GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE, GLX_DEPTH_SIZE ); - GLX_QUERY( GLUT_WINDOW_RED_SIZE, GLX_RED_SIZE ); - GLX_QUERY( GLUT_WINDOW_GREEN_SIZE, GLX_GREEN_SIZE ); - GLX_QUERY( GLUT_WINDOW_BLUE_SIZE, GLX_BLUE_SIZE ); - GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE, GLX_ALPHA_SIZE ); - GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE, GLX_ACCUM_RED_SIZE ); - GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE, GLX_ACCUM_GREEN_SIZE ); - GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE, GLX_ACCUM_BLUE_SIZE ); - GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE, GLX_ACCUM_ALPHA_SIZE ); - GLX_QUERY( GLUT_WINDOW_STEREO, GLX_STEREO ); - -# undef GLX_QUERY - - /* Colormap size is handled in a bit different way than all the rest */ - case GLUT_WINDOW_COLORMAP_SIZE: - if( (fgPlatformGetConfig( GLX_RGBA )) || (fgStructure.CurrentWindow == NULL) ) - { - /* - * We've got a RGBA visual, so there is no colormap at all. - * The other possibility is that we have no current window set. - */ - return 0; - } - else - { - const GLXFBConfig * fbconfig = - fgStructure.CurrentWindow->Window.pContext.FBConfig; - - XVisualInfo * visualInfo = - glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, *fbconfig ); - - const int result = visualInfo->visual->map_entries; - - XFree(visualInfo); - - return result; - } /* * Those calls are somewhat similiar, as they use XGetWindowAttributes() @@ -177,187 +132,53 @@ int fgPlatformGlutGet ( GLenum eWhat ) case GLUT_WINDOW_HEIGHT: return winAttributes.height ; } } - - /* I do not know yet if there will be a fgChooseVisual() function for Win32 */ - case GLUT_DISPLAY_MODE_POSSIBLE: - { - /* We should not have to call fgPlatformChooseFBConfig again here. */ - GLXFBConfig * fbconfig; - int isPossible; - - fbconfig = fgPlatformChooseFBConfig(NULL); - - if (fbconfig == NULL) + + /* Colormap size is handled in a bit different way than all the rest */ + case GLUT_WINDOW_COLORMAP_SIZE: + if( +#ifndef EGL_VERSION_1_0 + fgPlatformGetConfig( GLX_RGBA ) || +#endif + fgStructure.CurrentWindow == NULL) { - isPossible = 0; + /* + * We've got a RGBA visual, so there is no colormap at all. + * The other possibility is that we have no current window set. + */ + return 0; } else { - isPossible = 1; - XFree(fbconfig); - } + XVisualInfo * visualInfo; +#ifdef EGL_VERSION_1_0 + EGLint vid = 0; + XVisualInfo visualTemplate; + int num_visuals; + if (!eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display, + fgStructure.CurrentWindow->Window.pContext.egl.Config, + EGL_NATIVE_VISUAL_ID, &vid)) + fgError("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed"); + visualTemplate.visualid = vid; + visualInfo = XGetVisualInfo(fgDisplay.pDisplay.Display, VisualIDMask, &visualTemplate, &num_visuals); +#else + const GLXFBConfig fbconfig = + fgStructure.CurrentWindow->Window.pContext.FBConfig; - return isPossible; - } + visualInfo = + glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, fbconfig ); +#endif + const int result = visualInfo->visual->map_entries; - /* This is system-dependant */ - case GLUT_WINDOW_FORMAT_ID: - if( fgStructure.CurrentWindow == NULL ) - return 0; + XFree(visualInfo); - return fgPlatformGetConfig( GLX_VISUAL_ID ); - - default: - fgWarning( "glutGet(): missing enum handle %d", eWhat ); - break; - } - - return -1; -} - - -int fgPlatformGlutDeviceGet ( GLenum eWhat ) -{ - switch( eWhat ) - { - case GLUT_HAS_KEYBOARD: - /* - * X11 has a core keyboard by definition, although it can - * be present as a virtual/dummy keyboard. For now, there - * is no reliable way to tell if a real keyboard is present. - */ - return 1; - - /* X11 has a mouse by definition */ - case GLUT_HAS_MOUSE: - return 1 ; - - case GLUT_NUM_MOUSE_BUTTONS: - /* We should be able to pass NULL when the last argument is zero, - * but at least one X server has a bug where this causes a segfault. - * - * In XFree86/Xorg servers, a mouse wheel is seen as two buttons - * rather than an Axis; "freeglut_main.c" expects this when - * checking for a wheel event. - */ - { - unsigned char map; - int nbuttons = XGetPointerMapping(fgDisplay.pDisplay.Display, &map,0); - return nbuttons; + return result; } default: - fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat ); - break; +#ifdef EGL_VERSION_1_0 + return fghPlatformGlutGetEGL(eWhat); +#else + return fghPlatformGlutGetGLX(eWhat); +#endif } - - /* And now -- the failure. */ - return -1; } - - -int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size) -{ - int *array; - - int attributes[9]; - GLXFBConfig * fbconfigArray; /* Array of FBConfigs */ - int fbconfigArraySize; /* Number of FBConfigs in the array */ - int attribute_name = 0; - - array = NULL; - *size = 0; - - switch (eWhat) - { - case GLUT_AUX: - case GLUT_MULTISAMPLE: - - attributes[0] = GLX_BUFFER_SIZE; - attributes[1] = GLX_DONT_CARE; - - switch (eWhat) - { - case GLUT_AUX: - /* - FBConfigs are now sorted by increasing number of auxiliary - buffers. We want at least one buffer. - */ - attributes[2] = GLX_AUX_BUFFERS; - attributes[3] = 1; - attributes[4] = None; - - attribute_name = GLX_AUX_BUFFERS; - - break; - - - case GLUT_MULTISAMPLE: - attributes[2] = GLX_AUX_BUFFERS; - attributes[3] = GLX_DONT_CARE; - attributes[4] = GLX_SAMPLE_BUFFERS; - attributes[5] = 1; - /* - FBConfigs are now sorted by increasing number of samples per - pixel. We want at least one sample. - */ - attributes[6] = GLX_SAMPLES; - attributes[7] = 1; - attributes[8] = None; - - attribute_name = GLX_SAMPLES; - - break; - } - - fbconfigArray = glXChooseFBConfig(fgDisplay.pDisplay.Display, - fgDisplay.pDisplay.Screen, - attributes, - &fbconfigArraySize); - - if (fbconfigArray != NULL) - { - int * temp_array; - int result; /* Returned by glXGetFBConfigAttrib. Not checked. */ - int previous_value; - int i; - - temp_array = malloc(sizeof(int) * fbconfigArraySize); - previous_value = 0; - - for (i = 0; i < fbconfigArraySize; i++) - { - int value; - - result = glXGetFBConfigAttrib(fgDisplay.pDisplay.Display, - fbconfigArray[i], - attribute_name, - &value); - if (value > previous_value) - { - temp_array[*size] = value; - previous_value = value; - (*size)++; - } - } - - array = malloc(sizeof(int) * (*size)); - for (i = 0; i < *size; i++) - { - array[i] = temp_array[i]; - } - - free(temp_array); - XFree(fbconfigArray); - } - - break; - - default: - break; - } - - return array; -} - - diff --git a/freeglut/freeglut/src/x11/fg_structure_x11.c b/freeglut/freeglut/src/x11/fg_structure_x11.c index cbc9129..e1d5eb4 100644 --- a/freeglut/freeglut/src/x11/fg_structure_x11.c +++ b/freeglut/freeglut/src/x11/fg_structure_x11.c @@ -33,7 +33,11 @@ extern SFG_Structure fgStructure; void fgPlatformCreateWindow ( SFG_Window *window ) { +#ifdef EGL_VERSION_1_0 + fghPlatformCreateWindowEGL(window); +#else window->Window.pContext.FBConfig = NULL; +#endif window->State.pWState.OldHeight = window->State.pWState.OldWidth = -1; } diff --git a/freeglut/freeglut/src/x11/fg_window_x11.c b/freeglut/freeglut/src/x11/fg_window_x11.c index 44c9952..2b9012c 100644 --- a/freeglut/freeglut/src/x11/fg_window_x11.c +++ b/freeglut/freeglut/src/x11/fg_window_x11.c @@ -32,313 +32,13 @@ #include /* usleep */ #include "../fg_internal.h" -/* pushing attribute/value pairs into an array */ -#define ATTRIB(a) attributes[where++]=(a) -#define ATTRIB_VAL(a,v) {ATTRIB(a); ATTRIB(v);} - - -#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 +#ifdef EGL_VERSION_1_0 +#include "egl/fg_window_egl.h" +#define fghCreateNewContext fghCreateNewContextEGL +#else +#include "x11/fg_window_x11_glx.h" #endif -#ifndef GLX_CONTEXT_MAJOR_VERSION_ARB -#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#endif - -#ifndef GLX_CONTEXT_MINOR_VERSION_ARB -#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 -#endif - -#ifndef GLX_CONTEXT_FLAGS_ARB -#define GLX_CONTEXT_FLAGS_ARB 0x2094 -#endif - -#ifndef GLX_CONTEXT_PROFILE_MASK_ARB -#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 -#endif - -#ifndef GLX_CONTEXT_DEBUG_BIT_ARB -#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 -#endif - -#ifndef GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB -#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 -#endif - -#ifndef GLX_CONTEXT_CORE_PROFILE_BIT_ARB -#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#endif - -#ifndef GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB -#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#endif - -#ifndef GLX_RGBA_FLOAT_TYPE -#define GLX_RGBA_FLOAT_TYPE 0x20B9 -#endif - -#ifndef GLX_RGBA_FLOAT_BIT -#define GLX_RGBA_FLOAT_BIT 0x00000004 -#endif - - -/* - * Chooses a visual basing on the current display mode settings - */ - -GLXFBConfig* fgPlatformChooseFBConfig( int *numcfgs ) -{ - GLboolean wantIndexedMode = GL_FALSE; - int attributes[ 100 ]; - int where = 0, numAuxBuffers; - - /* First we have to process the display mode settings... */ - if( fgState.DisplayMode & GLUT_INDEX ) { - ATTRIB_VAL( GLX_BUFFER_SIZE, 8 ); - /* Buffer size is selected later. */ - - ATTRIB_VAL( GLX_RENDER_TYPE, GLX_COLOR_INDEX_BIT ); - wantIndexedMode = GL_TRUE; - } else { - ATTRIB_VAL( GLX_RED_SIZE, 1 ); - ATTRIB_VAL( GLX_GREEN_SIZE, 1 ); - ATTRIB_VAL( GLX_BLUE_SIZE, 1 ); - if( fgState.DisplayMode & GLUT_ALPHA ) { - ATTRIB_VAL( GLX_ALPHA_SIZE, 1 ); - } - } - - if( fgState.DisplayMode & GLUT_DOUBLE ) { - ATTRIB_VAL( GLX_DOUBLEBUFFER, True ); - } - - if( fgState.DisplayMode & GLUT_STEREO ) { - ATTRIB_VAL( GLX_STEREO, True ); - } - - if( fgState.DisplayMode & GLUT_DEPTH ) { - ATTRIB_VAL( GLX_DEPTH_SIZE, 1 ); - } - - if( fgState.DisplayMode & GLUT_STENCIL ) { - ATTRIB_VAL( GLX_STENCIL_SIZE, 1 ); - } - - if( fgState.DisplayMode & GLUT_ACCUM ) { - ATTRIB_VAL( GLX_ACCUM_RED_SIZE, 1 ); - ATTRIB_VAL( GLX_ACCUM_GREEN_SIZE, 1 ); - ATTRIB_VAL( GLX_ACCUM_BLUE_SIZE, 1 ); - if( fgState.DisplayMode & GLUT_ALPHA ) { - ATTRIB_VAL( GLX_ACCUM_ALPHA_SIZE, 1 ); - } - } - - numAuxBuffers = fghNumberOfAuxBuffersRequested(); - if ( numAuxBuffers > 0 ) { - ATTRIB_VAL( GLX_AUX_BUFFERS, numAuxBuffers ); - } - - if( fgState.DisplayMode & GLUT_SRGB ) { - ATTRIB_VAL( GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True ); - } - - if (fgState.DisplayMode & GLUT_MULTISAMPLE) { - ATTRIB_VAL(GLX_SAMPLE_BUFFERS, 1); - ATTRIB_VAL(GLX_SAMPLES, fgState.SampleNumber); - } - - /* Push a terminator at the end of the list */ - ATTRIB( None ); - - { - GLXFBConfig * fbconfigArray; /* Array of FBConfigs */ - GLXFBConfig * fbconfig; /* The FBConfig we want */ - int fbconfigArraySize; /* Number of FBConfigs in the array */ - - - /* Get all FBConfigs that match "attributes". */ - fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display, - fgDisplay.pDisplay.Screen, - attributes, - &fbconfigArraySize ); - - if (fbconfigArray != NULL) - { - int result; /* Returned by glXGetFBConfigAttrib, not checked. */ - - - if( wantIndexedMode ) - { - /* - * In index mode, we want the largest buffer size, i.e. visual - * depth. Here, FBConfigs are sorted by increasing buffer size - * first, so FBConfigs with the largest size come last. - */ - - int bufferSizeMin, bufferSizeMax; - - /* Get bufferSizeMin. */ - result = - glXGetFBConfigAttrib( fgDisplay.pDisplay.Display, - fbconfigArray[0], - GLX_BUFFER_SIZE, - &bufferSizeMin ); - /* Get bufferSizeMax. */ - result = - glXGetFBConfigAttrib( fgDisplay.pDisplay.Display, - fbconfigArray[fbconfigArraySize - 1], - GLX_BUFFER_SIZE, - &bufferSizeMax ); - - if (bufferSizeMax > bufferSizeMin) - { - /* - * Free and reallocate fbconfigArray, keeping only FBConfigs - * with the largest buffer size. - */ - XFree(fbconfigArray); - - /* Add buffer size token at the end of the list. */ - where--; - ATTRIB_VAL( GLX_BUFFER_SIZE, bufferSizeMax ); - ATTRIB( None ); - - fbconfigArray = glXChooseFBConfig( fgDisplay.pDisplay.Display, - fgDisplay.pDisplay.Screen, - attributes, - &fbconfigArraySize ); - } - } - - /* - * We now have an array of FBConfigs, the first one being the "best" - * one. So we should return only this FBConfig: - * - * int fbconfigXID; - * - * - pick the XID of the FBConfig we want - * result = glXGetFBConfigAttrib( fgDisplay.pDisplay.Display, - * fbconfigArray[0], - * GLX_FBCONFIG_ID, - * &fbconfigXID ); - * - * - free the array - * XFree(fbconfigArray); - * - * - reset "attributes" with the XID - * where = 0; - * ATTRIB_VAL( GLX_FBCONFIG_ID, fbconfigXID ); - * ATTRIB( None ); - * - * - get our FBConfig only - * fbconfig = glXChooseFBConfig( fgDisplay.pDisplay.Display, - * fgDisplay.pDisplay.Screen, - * attributes, - * &fbconfigArraySize ); - * - * However, for some configurations (for instance multisampling with - * Mesa 6.5.2 and ATI drivers), this does not work: - * glXChooseFBConfig returns NULL, whereas fbconfigXID is a valid - * XID. Further investigation is needed. - * - * So, for now, we return the whole array of FBConfigs. This should - * not produce any side effects elsewhere. - */ - fbconfig = fbconfigArray; - } - else - { - fbconfig = NULL; - } - - if (numcfgs) - *numcfgs = fbconfigArraySize; - - return fbconfig; - } -} - - -static void fghFillContextAttributes( int *attributes ) { - int where = 0, contextFlags, contextProfile; - - if ( !fghIsLegacyContextVersionRequested() ) { - ATTRIB_VAL( GLX_CONTEXT_MAJOR_VERSION_ARB, fgState.MajorVersion ); - ATTRIB_VAL( GLX_CONTEXT_MINOR_VERSION_ARB, fgState.MinorVersion ); - } - - contextFlags = - fghMapBit( fgState.ContextFlags, GLUT_DEBUG, GLX_CONTEXT_DEBUG_BIT_ARB ) | - fghMapBit( fgState.ContextFlags, GLUT_FORWARD_COMPATIBLE, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB ); - if ( contextFlags != 0 ) { - ATTRIB_VAL( GLX_CONTEXT_FLAGS_ARB, contextFlags ); - } - - contextProfile = - fghMapBit( fgState.ContextProfile, GLUT_CORE_PROFILE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB ) | - fghMapBit( fgState.ContextProfile, GLUT_COMPATIBILITY_PROFILE, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ); - if ( contextProfile != 0 ) { - ATTRIB_VAL( GLX_CONTEXT_PROFILE_MASK_ARB, contextProfile ); - } - - ATTRIB( 0 ); -} - -typedef GLXContext (*CreateContextAttribsProc)(Display *dpy, GLXFBConfig config, - GLXContext share_list, Bool direct, - const int *attrib_list); - -static GLXContext fghCreateNewContext( SFG_Window* window ) -{ - /* for color model calculation */ - int menu = ( window->IsMenu && !fgStructure.MenuContext ); - int index_mode = ( fgState.DisplayMode & GLUT_INDEX ); - - /* "classic" context creation */ - Display *dpy = fgDisplay.pDisplay.Display; - GLXFBConfig config = *(window->Window.pContext.FBConfig); - int render_type = ( !menu && index_mode ) ? GLX_COLOR_INDEX_TYPE : GLX_RGBA_TYPE; - GLXContext share_list = NULL; - Bool direct = ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ); - GLXContext context; - - /* new context creation */ - int attributes[9]; - CreateContextAttribsProc createContextAttribs = (CreateContextAttribsProc) fgPlatformGetProcAddress( "glXCreateContextAttribsARB" ); - - /* glXCreateContextAttribsARB not found, yet the user has requested the new context creation */ - if ( !createContextAttribs && !fghIsLegacyContextRequested() ) { - fgWarning( "OpenGL >2.1 context requested but glXCreateContextAttribsARB is not available! Falling back to legacy context creation" ); - fgState.MajorVersion = 2; - fgState.MinorVersion = 1; - } - - /* If nothing fancy has been required, simply use the old context creation GLX API entry */ - if ( fghIsLegacyContextRequested() || !createContextAttribs ) - { - context = glXCreateNewContext( dpy, config, render_type, share_list, direct ); - if ( context == NULL ) { - fghContextCreationError(); - } - return context; - } - - /* color index mode is not available anymore with OpenGL 3.0 */ - if ( render_type == GLX_COLOR_INDEX_TYPE ) { - fgWarning( "color index mode is deprecated, using RGBA mode" ); - } - - fghFillContextAttributes( attributes ); - - context = createContextAttribs( dpy, config, share_list, direct, attributes ); - if ( context == NULL ) { - fghContextCreationError(); - } - return context; -} - - -#define _NET_WM_STATE_TOGGLE 2 static int fghResizeFullscrToggle(void) { XWindowAttributes attributes; @@ -370,6 +70,7 @@ static int fghResizeFullscrToggle(void) return 0; } +#define _NET_WM_STATE_TOGGLE 2 static int fghEwmhFullscrToggle(void) { XEvent xev; @@ -409,19 +110,6 @@ static int fghToggleFullscreen(void) return -1; } -void fgPlatformSetWindow ( SFG_Window *window ) -{ - if ( window ) - { - glXMakeContextCurrent( - fgDisplay.pDisplay.Display, - window->Window.Handle, - window->Window.Handle, - window->Window.Context - ); - } -} - static Bool fghWindowIsVisible( Display *display, XEvent *event, XPointer arg) { Window window = (Window)arg; @@ -451,43 +139,56 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ; - window->Window.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs ); +#ifdef EGL_VERSION_1_0 +#define WINDOW_CONFIG window->Window.pContext.egl.Config +#else +#define WINDOW_CONFIG window->Window.pContext.FBConfig +#endif + fghChooseConfig(&WINDOW_CONFIG); if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = current_DisplayMode ; - if( ! window->Window.pContext.FBConfig ) + if( ! WINDOW_CONFIG ) { /* - * The "fgPlatformChooseFBConfig" returned a null meaning that the visual + * The "fghChooseConfig" returned a null meaning that the visual * context is not available. * Try a couple of variations to see if they will work. */ +#ifndef EGL_VERSION_1_0 if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) { fgState.DisplayMode |= GLUT_DOUBLE ; - window->Window.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs ); + fghChooseConfig(&WINDOW_CONFIG); fgState.DisplayMode &= ~GLUT_DOUBLE; } +#endif if( fgState.DisplayMode & GLUT_MULTISAMPLE ) { fgState.DisplayMode &= ~GLUT_MULTISAMPLE ; - window->Window.pContext.FBConfig = fgPlatformChooseFBConfig( &num_FBConfigs ); + fghChooseConfig(&WINDOW_CONFIG); fgState.DisplayMode |= GLUT_MULTISAMPLE; } } - FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.pContext.FBConfig != NULL, + FREEGLUT_INTERNAL_ERROR_EXIT( WINDOW_CONFIG != NULL, "FBConfig with necessary capabilities not found", "fgOpenWindow" ); /* Get the X visual. */ - for (i = 0; i < num_FBConfigs; i++) { - visualInfo = glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, - window->Window.pContext.FBConfig[i] ); - if (visualInfo) - break; - } +#ifdef EGL_VERSION_1_0 + EGLint vid = 0; + XVisualInfo visualTemplate; + int num_visuals; + if (!eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Config, EGL_NATIVE_VISUAL_ID, &vid)) + fgError("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed"); + visualTemplate.visualid = vid; + visualInfo = XGetVisualInfo(fgDisplay.pDisplay.Display, VisualIDMask, &visualTemplate, &num_visuals); +#else + visualInfo = glXGetVisualFromFBConfig( fgDisplay.pDisplay.Display, + window->Window.pContext.FBConfig ); +#endif FREEGLUT_INTERNAL_ERROR_EXIT( visualInfo != NULL, "visualInfo could not be retrieved from FBConfig", "fgOpenWindow" ); @@ -562,7 +263,12 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, } else if( fgState.UseCurrentContext ) { + +#ifdef EGL_VERSION_1_0 + window->Window.Context = eglGetCurrentContext( ); +#else window->Window.Context = glXGetCurrentContext( ); +#endif if( ! window->Window.Context ) window->Window.Context = fghCreateNewContext( window ); @@ -570,7 +276,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, else window->Window.Context = fghCreateNewContext( window ); -#if !defined( __FreeBSD__ ) && !defined( __NetBSD__ ) +#if !defined( __FreeBSD__ ) && !defined( __NetBSD__ ) && !defined(EGL_VERSION_1_0) if( !glXIsDirect( fgDisplay.pDisplay.Display, window->Window.Context ) ) { if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) @@ -625,12 +331,16 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, XSetWMProtocols( fgDisplay.pDisplay.Display, window->Window.Handle, &fgDisplay.pDisplay.DeleteWindow, 1 ); +#ifdef EGL_VERSION_1_0 + fghPlatformOpenWindowEGL(window); +#else glXMakeContextCurrent( fgDisplay.pDisplay.Display, window->Window.Handle, window->Window.Handle, window->Window.Context ); +#endif /* register extension events _before_ window is mapped */ #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H @@ -643,6 +353,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, if( !isSubWindow) XPeekIfEvent( fgDisplay.pDisplay.Display, &eventReturnBuffer, &fghWindowIsVisible, (XPointer)(window->Window.Handle) ); +#undef WINDOW_CONFIG } @@ -651,9 +362,13 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, */ void fgPlatformCloseWindow( SFG_Window* window ) { +#ifdef EGL_VERSION_1_0 + fghPlatformCloseWindowEGL(window); +#else if( window->Window.Context ) glXDestroyContext( fgDisplay.pDisplay.Display, window->Window.Context ); - XFree( window->Window.pContext.FBConfig ); + window->Window.pContext.FBConfig = NULL; +#endif if( window->Window.Handle ) { XDestroyWindow( fgDisplay.pDisplay.Display, window->Window.Handle );