From d1cccef518bc222b3733706aa1e5776c6cb9fec9 Mon Sep 17 00:00:00 2001 From: Sylvain Beucler Date: Fri, 16 Mar 2012 23:23:19 +0000 Subject: [PATCH] Move EGL fields to a separate structure for reusability (e.g. upcoming Mesa X11 EGL support) git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1161 7f0cb862-5218-0410-a997-914c9d46530a --- CMakeLists.txt | 1 + src/android/fg_internal_android.h | 17 +++++++++++++++ src/android/fg_main_android.c | 2 +- src/android/fg_window_android.c | 19 +++++++++++++---- src/egl/fg_display_egl.c | 2 +- src/egl/fg_init_egl.c | 23 +++++++------------- src/egl/fg_internal_egl.h | 17 ++++++--------- src/egl/fg_structure_egl.c | 3 ++- src/egl/fg_window_egl.c | 42 +++++++++++++++++++------------------ src/egl/fg_window_egl.h | 33 +++++++++++++++++++++++++++++ 10 files changed, 105 insertions(+), 54 deletions(-) create mode 100644 src/egl/fg_window_egl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 387a697..ba5a7f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,6 +100,7 @@ ELSEIF(ANDROID) src/egl/fg_init_egl.c src/egl/fg_structure_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.h src/android/fg_runtime_android.c diff --git a/src/android/fg_internal_android.h b/src/android/fg_internal_android.h index 83373de..e13b675 100644 --- a/src/android/fg_internal_android.h +++ b/src/android/fg_internal_android.h @@ -31,6 +31,23 @@ /* Android OpenGL ES is accessed through EGL */ #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) */ diff --git a/src/android/fg_main_android.c b/src/android/fg_main_android.c index 83aac13..3f973f2 100644 --- a/src/android/fg_main_android.c +++ b/src/android/fg_main_android.c @@ -329,7 +329,7 @@ void handle_cmd(struct android_app* app, int32_t cmd) { break; case 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 after the next SwapBuffer */ glutPostRedisplay(); diff --git a/src/android/fg_window_android.c b/src/android/fg_window_android.c index 8b1f682..bbd17fd 100644 --- a/src/android/fg_window_android.c +++ b/src/android/fg_window_android.c @@ -29,7 +29,7 @@ #define FREEGLUT_BUILDING_LIB #include #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 @@ -52,6 +52,8 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, return; } + fghCreateNewContextEGL(window); + /* Wait until window is available and OpenGL context is created */ /* Normally events are processed through glutMainLoop(), but the 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(); } - EGLDisplay display = fgDisplay.pDisplay.eglDisplay; - EGLint format = fgDisplay.pDisplay.eglContextFormat; + EGLDisplay display = fgDisplay.pDisplay.egl.Display; + EGLint format = fgDisplay.pDisplay.single_window->Window.pContext.egl.ContextFormat; ANativeWindow_setBuffersGeometry(window->Window.Handle, 0, 0, format); - window->Window.pContext.eglSurface = fghEGLPlatformOpenWindow(window->Window.Handle); + fghPlatformOpenWindowEGL(window); 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 ) { /* TODO: only a single window possible? */ diff --git a/src/egl/fg_display_egl.c b/src/egl/fg_display_egl.c index f94d873..4bf3283 100644 --- a/src/egl/fg_display_egl.c +++ b/src/egl/fg_display_egl.c @@ -32,6 +32,6 @@ void fgPlatformGlutSwapBuffers( SFG_PlatformDisplay *pDisplayPtr, SFG_Window* CurrentWindow ) { /* 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()); } diff --git a/src/egl/fg_init_egl.c b/src/egl/fg_init_egl.c index a58812a..1bd4b14 100644 --- a/src/egl/fg_init_egl.c +++ b/src/egl/fg_init_egl.c @@ -40,16 +40,13 @@ void fgPlatformInitialize( const char* displayName ) /* CreateDisplay */ /* Using EGL_DEFAULT_DISPLAY, or a specific native 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"); - if (!eglInitialize(fgDisplay.pDisplay.eglDisplay, NULL, NULL)) + if (!eglInitialize(fgDisplay.pDisplay.egl.Display, NULL, NULL)) fgError("eglInitialize: error %x\n", eglGetError()); - /* CreateContext */ - fghCreateContext(); - // fgDisplay.ScreenWidth = ...; // fgDisplay.ScreenHeight = ...; // fgDisplay.ScreenWidthMM = ...; @@ -58,15 +55,9 @@ void fgPlatformInitialize( const char* displayName ) void fgPlatformCloseDisplay ( void ) { - eglMakeCurrent(fgDisplay.pDisplay.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (fgDisplay.pDisplay.eglContext != EGL_NO_CONTEXT) { - eglDestroyContext(fgDisplay.pDisplay.eglDisplay, fgDisplay.pDisplay.eglContext); - fgDisplay.pDisplay.eglContext = EGL_NO_CONTEXT; - } - - if (fgDisplay.pDisplay.eglDisplay != EGL_NO_DISPLAY) { - eglTerminate(fgDisplay.pDisplay.eglDisplay); - fgDisplay.pDisplay.eglDisplay = EGL_NO_DISPLAY; + if (fgDisplay.pDisplay.egl.Display != EGL_NO_DISPLAY) { + eglTerminate(fgDisplay.pDisplay.egl.Display); + fgDisplay.pDisplay.egl.Display = EGL_NO_DISPLAY; } } @@ -76,5 +67,5 @@ void fgPlatformCloseDisplay ( void ) void fgPlatformDestroyContext ( SFG_PlatformDisplay pDisplay, SFG_WindowContextType MContext ) { if (MContext != EGL_NO_CONTEXT) - eglDestroyContext(pDisplay.eglDisplay, MContext); + eglDestroyContext(pDisplay.egl.Display, MContext); } diff --git a/src/egl/fg_internal_egl.h b/src/egl/fg_internal_egl.h index 1a4def8..a10383d 100644 --- a/src/egl/fg_internal_egl.h +++ b/src/egl/fg_internal_egl.h @@ -30,16 +30,11 @@ /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ /* The structure used by display initialization in freeglut_init.c */ -typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay; struct tagSFG_Window; -struct tagSFG_PlatformDisplay +struct tagSFG_PlatformDisplayEGL { /* Used to initialize and deinitialize EGL */ - EGLDisplay eglDisplay; - EGLContext eglContext; - EGLConfig eglContextConfig; - EGLint eglContextFormat; - struct tagSFG_Window* single_window; + EGLDisplay Display; }; @@ -49,11 +44,11 @@ struct tagSFG_PlatformDisplay */ typedef EGLNativeWindowType SFG_WindowHandleType ; typedef EGLContext SFG_WindowContextType ; -typedef struct tagSFG_PlatformContext SFG_PlatformContext; -/* SFG_PlatformContext is used for SFG_Window.Window */ -struct tagSFG_PlatformContext +struct tagSFG_PlatformContextEGL { - EGLSurface eglSurface; + EGLSurface Surface; + EGLConfig ContextConfig; + EGLint ContextFormat; }; diff --git a/src/egl/fg_structure_egl.c b/src/egl/fg_structure_egl.c index 0466bc8..d636bf8 100644 --- a/src/egl/fg_structure_egl.c +++ b/src/egl/fg_structure_egl.c @@ -30,5 +30,6 @@ extern SFG_Structure fgStructure; 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; } diff --git a/src/egl/fg_window_egl.c b/src/egl/fg_window_egl.c index 6b980bd..f8536fc 100644 --- a/src/egl/fg_window_egl.c +++ b/src/egl/fg_window_egl.c @@ -29,7 +29,7 @@ /** * Initialize an EGL context for the current display. */ -void fghCreateContext( ) { +void fghCreateNewContextEGL( SFG_Window* window ) { /* * Here specify the attributes of the desired configuration. * Below, we select an EGLConfig with at least 8 bits per color @@ -56,10 +56,7 @@ void fghCreateContext( ) { EGLConfig config; EGLContext context; - EGLDisplay eglDisplay = fgDisplay.pDisplay.eglDisplay; - - /* TODO : apply DisplayMode */ - /* (GLUT_DEPTH already applied in attribs[] above) */ + EGLDisplay eglDisplay = fgDisplay.pDisplay.egl.Display; /* Here, the application chooses the configuration it desires. In this * sample, we have a very simplified selection process, where we pick @@ -86,44 +83,49 @@ void fghCreateContext( ) { fghContextCreationError(); } 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) fgError("Wrong GLES major version: %d\n", ver); - fgDisplay.pDisplay.eglContext = context; - fgDisplay.pDisplay.eglContextConfig = config; - fgDisplay.pDisplay.eglContextFormat = format; + window->Window.Context = context; + window->Window.pContext.egl.ContextConfig = config; + window->Window.pContext.egl.ContextFormat = format; } /* * Really opens a window when handle is available */ -EGLSurface fghEGLPlatformOpenWindow( EGLNativeWindowType handle ) +void fghPlatformOpenWindowEGL( SFG_Window* window ) { - EGLDisplay display = fgDisplay.pDisplay.eglDisplay; - EGLContext context = fgDisplay.pDisplay.eglContext; - EGLConfig config = fgDisplay.pDisplay.eglContextConfig; + EGLDisplay display = fgDisplay.pDisplay.egl.Display; + EGLConfig config = window->Window.pContext.egl.ContextConfig; - EGLSurface surface = eglCreateWindowSurface(display, config, handle, NULL); + EGLSurface surface = eglCreateWindowSurface(display, config, window->Window.Handle, NULL); if (surface == EGL_NO_SURFACE) 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()); //EGLint w, h; //eglQuerySurface(display, surface, EGL_WIDTH, &w); //eglQuerySurface(display, surface, EGL_HEIGHT, &h); - return surface; + window->Window.pContext.egl.Surface = surface; } /* * 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) { - eglDestroySurface(fgDisplay.pDisplay.eglDisplay, window->Window.pContext.eglSurface); - window->Window.pContext.eglSurface = EGL_NO_SURFACE; + eglMakeCurrent(fgDisplay.pDisplay.egl.Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (window->Window.Context != EGL_NO_CONTEXT) { + 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; } } diff --git a/src/egl/fg_window_egl.h b/src/egl/fg_window_egl.h new file mode 100644 index 0000000..23a74aa --- /dev/null +++ b/src/egl/fg_window_egl.h @@ -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 -- 1.7.10.4