Move EGL fields to a separate structure for reusability (e.g. upcoming Mesa X11 EGL support)

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1161 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
beuc 2012-03-16 23:23:19 +00:00
parent cb3dea2183
commit 31e0027e09
11 changed files with 106 additions and 54 deletions

1
.gitattributes vendored
View File

@ -70,6 +70,7 @@ freeglut/freeglut/src/egl/fg_init_egl.c -text
freeglut/freeglut/src/egl/fg_internal_egl.h -text freeglut/freeglut/src/egl/fg_internal_egl.h -text
freeglut/freeglut/src/egl/fg_structure_egl.c -text freeglut/freeglut/src/egl/fg_structure_egl.c -text
freeglut/freeglut/src/egl/fg_window_egl.c -text freeglut/freeglut/src/egl/fg_window_egl.c -text
freeglut/freeglut/src/egl/fg_window_egl.h -text
freeglut/freeglut/src/fg_callbacks.c svn_keywords=Author+Date+Id+Revision freeglut/freeglut/src/fg_callbacks.c svn_keywords=Author+Date+Id+Revision
freeglut/freeglut/src/fg_cursor.c svn_keywords=Author+Date+Id+Revision freeglut/freeglut/src/fg_cursor.c svn_keywords=Author+Date+Id+Revision
freeglut/freeglut/src/fg_display.c svn_keywords=Author+Date+Id+Revision freeglut/freeglut/src/fg_display.c svn_keywords=Author+Date+Id+Revision

View File

@ -100,6 +100,7 @@ ELSEIF(ANDROID)
src/egl/fg_init_egl.c src/egl/fg_init_egl.c
src/egl/fg_structure_egl.c src/egl/fg_structure_egl.c
src/egl/fg_window_egl.c src/egl/fg_window_egl.c
src/egl/fg_window_egl.h
src/android/native_app_glue/android_native_app_glue.c src/android/native_app_glue/android_native_app_glue.c
src/android/native_app_glue/android_native_app_glue.h src/android/native_app_glue/android_native_app_glue.h
src/android/fg_runtime_android.c src/android/fg_runtime_android.c

View File

@ -31,6 +31,23 @@
/* Android OpenGL ES is accessed through EGL */ /* Android OpenGL ES is accessed through EGL */
#include "egl/fg_internal_egl.h" #include "egl/fg_internal_egl.h"
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
/* The structure used by display initialization in freeglut_init.c */
typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
struct tagSFG_PlatformDisplay
{
struct tagSFG_PlatformDisplayEGL egl;
struct tagSFG_Window* single_window;
};
typedef struct tagSFG_PlatformContext SFG_PlatformContext;
/* SFG_PlatformContext is used for SFG_Window.Window */
struct tagSFG_PlatformContext
{
struct tagSFG_PlatformContextEGL egl;
};
/** /**
* Virtual PAD (spots on touchscreen that simulate keys) * Virtual PAD (spots on touchscreen that simulate keys)
*/ */

View File

@ -329,7 +329,7 @@ void handle_cmd(struct android_app* app, int32_t cmd) {
break; break;
case APP_CMD_WINDOW_RESIZED: case APP_CMD_WINDOW_RESIZED:
LOGI("handle_cmd: APP_CMD_WINDOW_RESIZED"); LOGI("handle_cmd: APP_CMD_WINDOW_RESIZED");
if (fgDisplay.pDisplay.single_window->Window.pContext.eglSurface != EGL_NO_SURFACE) if (fgDisplay.pDisplay.single_window->Window.pContext.egl.Surface != EGL_NO_SURFACE)
/* Make ProcessSingleEvent detect the new size, only available /* Make ProcessSingleEvent detect the new size, only available
after the next SwapBuffer */ after the next SwapBuffer */
glutPostRedisplay(); glutPostRedisplay();

View File

@ -29,7 +29,7 @@
#define FREEGLUT_BUILDING_LIB #define FREEGLUT_BUILDING_LIB
#include <GL/freeglut.h> #include <GL/freeglut.h>
#include "fg_internal.h" #include "fg_internal.h"
extern EGLSurface fghEGLPlatformOpenWindow( EGLNativeWindowType handle ); #include "egl/fg_window_egl.h"
/* /*
* Opens a window. Requires a SFG_Window object created and attached * Opens a window. Requires a SFG_Window object created and attached
@ -52,6 +52,8 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
return; return;
} }
fghCreateNewContextEGL(window);
/* Wait until window is available and OpenGL context is created */ /* Wait until window is available and OpenGL context is created */
/* Normally events are processed through glutMainLoop(), but the /* Normally events are processed through glutMainLoop(), but the
user didn't call it yet, and the Android may not have initialized user didn't call it yet, and the Android may not have initialized
@ -64,14 +66,23 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
fgPlatformProcessSingleEvent(); fgPlatformProcessSingleEvent();
} }
EGLDisplay display = fgDisplay.pDisplay.eglDisplay; EGLDisplay display = fgDisplay.pDisplay.egl.Display;
EGLint format = fgDisplay.pDisplay.eglContextFormat; EGLint format = fgDisplay.pDisplay.single_window->Window.pContext.egl.ContextFormat;
ANativeWindow_setBuffersGeometry(window->Window.Handle, 0, 0, format); ANativeWindow_setBuffersGeometry(window->Window.Handle, 0, 0, format);
window->Window.pContext.eglSurface = fghEGLPlatformOpenWindow(window->Window.Handle); fghPlatformOpenWindowEGL(window);
window->State.Visible = GL_TRUE; window->State.Visible = GL_TRUE;
} }
/*
* Closes a window, destroying the frame and OpenGL context
*/
void fgPlatformCloseWindow( SFG_Window* window )
{
fghPlatformCloseWindowEGL(window);
/* Window pre-created by Android, no way to delete it */
}
void fgPlatformSetWindow ( SFG_Window *window ) void fgPlatformSetWindow ( SFG_Window *window )
{ {
/* TODO: only a single window possible? */ /* TODO: only a single window possible? */

View File

@ -32,6 +32,6 @@
void fgPlatformGlutSwapBuffers( SFG_PlatformDisplay *pDisplayPtr, SFG_Window* CurrentWindow ) void fgPlatformGlutSwapBuffers( SFG_PlatformDisplay *pDisplayPtr, SFG_Window* CurrentWindow )
{ {
/* LOGI("Swap!"); */ /* LOGI("Swap!"); */
if (!eglSwapBuffers(pDisplayPtr->eglDisplay, CurrentWindow->Window.pContext.eglSurface)) if (!eglSwapBuffers(pDisplayPtr->egl.Display, CurrentWindow->Window.pContext.egl.Surface))
fgError("eglSwapBuffers: error %x\n", eglGetError()); fgError("eglSwapBuffers: error %x\n", eglGetError());
} }

View File

@ -40,16 +40,13 @@ void fgPlatformInitialize( const char* displayName )
/* CreateDisplay */ /* CreateDisplay */
/* Using EGL_DEFAULT_DISPLAY, or a specific native display */ /* Using EGL_DEFAULT_DISPLAY, or a specific native display */
EGLNativeDisplayType nativeDisplay = EGL_DEFAULT_DISPLAY; EGLNativeDisplayType nativeDisplay = EGL_DEFAULT_DISPLAY;
fgDisplay.pDisplay.eglDisplay = eglGetDisplay(nativeDisplay); fgDisplay.pDisplay.egl.Display = eglGetDisplay(nativeDisplay);
FREEGLUT_INTERNAL_ERROR_EXIT(fgDisplay.pDisplay.eglDisplay != EGL_NO_DISPLAY, FREEGLUT_INTERNAL_ERROR_EXIT(fgDisplay.pDisplay.egl.Display != EGL_NO_DISPLAY,
"No display available", "fgPlatformInitialize"); "No display available", "fgPlatformInitialize");
if (!eglInitialize(fgDisplay.pDisplay.eglDisplay, NULL, NULL)) if (!eglInitialize(fgDisplay.pDisplay.egl.Display, NULL, NULL))
fgError("eglInitialize: error %x\n", eglGetError()); fgError("eglInitialize: error %x\n", eglGetError());
/* CreateContext */
fghCreateContext();
// fgDisplay.ScreenWidth = ...; // fgDisplay.ScreenWidth = ...;
// fgDisplay.ScreenHeight = ...; // fgDisplay.ScreenHeight = ...;
// fgDisplay.ScreenWidthMM = ...; // fgDisplay.ScreenWidthMM = ...;
@ -58,15 +55,9 @@ void fgPlatformInitialize( const char* displayName )
void fgPlatformCloseDisplay ( void ) void fgPlatformCloseDisplay ( void )
{ {
eglMakeCurrent(fgDisplay.pDisplay.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); if (fgDisplay.pDisplay.egl.Display != EGL_NO_DISPLAY) {
if (fgDisplay.pDisplay.eglContext != EGL_NO_CONTEXT) { eglTerminate(fgDisplay.pDisplay.egl.Display);
eglDestroyContext(fgDisplay.pDisplay.eglDisplay, fgDisplay.pDisplay.eglContext); fgDisplay.pDisplay.egl.Display = EGL_NO_DISPLAY;
fgDisplay.pDisplay.eglContext = EGL_NO_CONTEXT;
}
if (fgDisplay.pDisplay.eglDisplay != EGL_NO_DISPLAY) {
eglTerminate(fgDisplay.pDisplay.eglDisplay);
fgDisplay.pDisplay.eglDisplay = EGL_NO_DISPLAY;
} }
} }
@ -76,5 +67,5 @@ void fgPlatformCloseDisplay ( void )
void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext ) void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext )
{ {
if (MContext != EGL_NO_CONTEXT) if (MContext != EGL_NO_CONTEXT)
eglDestroyContext(pDisplay.eglDisplay, MContext); eglDestroyContext(pDisplay.egl.Display, MContext);
} }

View File

@ -30,16 +30,11 @@
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
/* The structure used by display initialization in freeglut_init.c */ /* The structure used by display initialization in freeglut_init.c */
typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
struct tagSFG_Window; struct tagSFG_Window;
struct tagSFG_PlatformDisplay struct tagSFG_PlatformDisplayEGL
{ {
/* Used to initialize and deinitialize EGL */ /* Used to initialize and deinitialize EGL */
EGLDisplay eglDisplay; EGLDisplay Display;
EGLContext eglContext;
EGLConfig eglContextConfig;
EGLint eglContextFormat;
struct tagSFG_Window* single_window;
}; };
@ -49,11 +44,11 @@ struct tagSFG_PlatformDisplay
*/ */
typedef EGLNativeWindowType SFG_WindowHandleType ; typedef EGLNativeWindowType SFG_WindowHandleType ;
typedef EGLContext SFG_WindowContextType ; typedef EGLContext SFG_WindowContextType ;
typedef struct tagSFG_PlatformContext SFG_PlatformContext; struct tagSFG_PlatformContextEGL
/* SFG_PlatformContext is used for SFG_Window.Window */
struct tagSFG_PlatformContext
{ {
EGLSurface eglSurface; EGLSurface Surface;
EGLConfig ContextConfig;
EGLint ContextFormat;
}; };

View File

@ -30,5 +30,6 @@ extern SFG_Structure fgStructure;
void fgPlatformCreateWindow ( SFG_Window *window ) void fgPlatformCreateWindow ( SFG_Window *window )
{ {
window->Window.pContext.eglSurface = EGL_NO_SURFACE; window->Window.pContext.egl.Surface = EGL_NO_SURFACE;
window->Window.pContext.egl.ContextConfig = NULL;
} }

View File

@ -29,7 +29,7 @@
/** /**
* Initialize an EGL context for the current display. * Initialize an EGL context for the current display.
*/ */
void fghCreateContext( ) { void fghCreateNewContextEGL( SFG_Window* window ) {
/* /*
* Here specify the attributes of the desired configuration. * Here specify the attributes of the desired configuration.
* Below, we select an EGLConfig with at least 8 bits per color * Below, we select an EGLConfig with at least 8 bits per color
@ -56,10 +56,7 @@ void fghCreateContext( ) {
EGLConfig config; EGLConfig config;
EGLContext context; EGLContext context;
EGLDisplay eglDisplay = fgDisplay.pDisplay.eglDisplay; EGLDisplay eglDisplay = fgDisplay.pDisplay.egl.Display;
/* TODO : apply DisplayMode */
/* (GLUT_DEPTH already applied in attribs[] above) */
/* Here, the application chooses the configuration it desires. In this /* Here, the application chooses the configuration it desires. In this
* sample, we have a very simplified selection process, where we pick * sample, we have a very simplified selection process, where we pick
@ -86,44 +83,49 @@ void fghCreateContext( ) {
fghContextCreationError(); fghContextCreationError();
} }
EGLint ver = -1; EGLint ver = -1;
eglQueryContext(fgDisplay.pDisplay.eglDisplay, context, EGL_CONTEXT_CLIENT_VERSION, &ver); eglQueryContext(fgDisplay.pDisplay.egl.Display, context, EGL_CONTEXT_CLIENT_VERSION, &ver);
if (ver != 2) if (ver != 2)
fgError("Wrong GLES major version: %d\n", ver); fgError("Wrong GLES major version: %d\n", ver);
fgDisplay.pDisplay.eglContext = context; window->Window.Context = context;
fgDisplay.pDisplay.eglContextConfig = config; window->Window.pContext.egl.ContextConfig = config;
fgDisplay.pDisplay.eglContextFormat = format; window->Window.pContext.egl.ContextFormat = format;
} }
/* /*
* Really opens a window when handle is available * Really opens a window when handle is available
*/ */
EGLSurface fghEGLPlatformOpenWindow( EGLNativeWindowType handle ) void fghPlatformOpenWindowEGL( SFG_Window* window )
{ {
EGLDisplay display = fgDisplay.pDisplay.eglDisplay; EGLDisplay display = fgDisplay.pDisplay.egl.Display;
EGLContext context = fgDisplay.pDisplay.eglContext; EGLConfig config = window->Window.pContext.egl.ContextConfig;
EGLConfig config = fgDisplay.pDisplay.eglContextConfig;
EGLSurface surface = eglCreateWindowSurface(display, config, handle, NULL); EGLSurface surface = eglCreateWindowSurface(display, config, window->Window.Handle, NULL);
if (surface == EGL_NO_SURFACE) if (surface == EGL_NO_SURFACE)
fgError("Cannot create EGL window surface, err=%x\n", eglGetError()); fgError("Cannot create EGL window surface, err=%x\n", eglGetError());
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) if (eglMakeCurrent(display, surface, surface, window->Window.Context) == EGL_FALSE)
fgError("eglMakeCurrent: err=%x\n", eglGetError()); fgError("eglMakeCurrent: err=%x\n", eglGetError());
//EGLint w, h; //EGLint w, h;
//eglQuerySurface(display, surface, EGL_WIDTH, &w); //eglQuerySurface(display, surface, EGL_WIDTH, &w);
//eglQuerySurface(display, surface, EGL_HEIGHT, &h); //eglQuerySurface(display, surface, EGL_HEIGHT, &h);
return surface; window->Window.pContext.egl.Surface = surface;
} }
/* /*
* Closes a window, destroying the frame and OpenGL context * Closes a window, destroying the frame and OpenGL context
*/ */
void fgPlatformCloseWindow( SFG_Window* window ) void fghPlatformCloseWindowEGL( SFG_Window* window )
{ {
if (window->Window.pContext.eglSurface != EGL_NO_SURFACE) { eglMakeCurrent(fgDisplay.pDisplay.egl.Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(fgDisplay.pDisplay.eglDisplay, window->Window.pContext.eglSurface); if (window->Window.Context != EGL_NO_CONTEXT) {
window->Window.pContext.eglSurface = EGL_NO_SURFACE; eglDestroyContext(fgDisplay.pDisplay.egl.Display, window->Window.Context);
window->Window.Context = EGL_NO_CONTEXT;
}
if (window->Window.pContext.egl.Surface != EGL_NO_SURFACE) {
eglDestroySurface(fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Surface);
window->Window.pContext.egl.Surface = EGL_NO_SURFACE;
} }
} }

View File

@ -0,0 +1,33 @@
/*
* freeglut_display_android.c
*
* Window management methods for EGL
*
* Copyright (C) 2012 Sylvain Beucler
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __FG_WINDOW_EGL_H__
#define __FG_WINDOW_EGL_H__
extern void fghPlatformOpenWindowEGL( SFG_Window* window );
extern void fghCreateNewContextEGL( SFG_Window* window );
extern void fghPlatformCloseWindowEGL( SFG_Window* window );
#endif