| /* San Angeles Observation OpenGL ES version example | 
 |  * Copyright 2004-2005 Jetro Lauha | 
 |  * All rights reserved. | 
 |  * Web: http://iki.fi/jetro/ | 
 |  * | 
 |  * This source is free software; you can redistribute it and/or | 
 |  * modify it under the terms of EITHER: | 
 |  *   (1) The GNU Lesser General Public License as published by the Free | 
 |  *       Software Foundation; either version 2.1 of the License, or (at | 
 |  *       your option) any later version. The text of the GNU Lesser | 
 |  *       General Public License is included with this source in the | 
 |  *       file LICENSE-LGPL.txt. | 
 |  *   (2) The BSD-style license that is included with this source in | 
 |  *       the file LICENSE-BSD.txt. | 
 |  * | 
 |  * This source is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files | 
 |  * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details. | 
 |  * | 
 |  * $Id: app-linux.c,v 1.4 2005/02/08 18:42:48 tonic Exp $ | 
 |  * $Revision: 1.4 $ | 
 |  * | 
 |  * Parts of this source file is based on test/example code from | 
 |  * GLESonGL implementation by David Blythe. Here is copy of the | 
 |  * license notice from that source: | 
 |  * | 
 |  * Copyright (C) 2003  David Blythe   All Rights Reserved. | 
 |  * | 
 |  * 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 | 
 |  * DAVID BLYTHE 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. | 
 |  */ | 
 |  | 
 | #include <stdlib.h> | 
 | #include <stdio.h> | 
 | #include <sys/time.h> | 
 |  | 
 | #include <EGL/egl.h> | 
 | #include <GLES/gl.h> | 
 |  | 
 | #include <EGLUtils.h> | 
 | #include <WindowSurface.h> | 
 |  | 
 | using namespace android; | 
 |  | 
 | #include "app.h" | 
 |  | 
 |  | 
 | int gAppAlive = 1; | 
 |  | 
 | static int sWindowWidth = WINDOW_DEFAULT_WIDTH; | 
 | static int sWindowHeight = WINDOW_DEFAULT_HEIGHT; | 
 | static EGLDisplay sEglDisplay = EGL_NO_DISPLAY; | 
 | static EGLContext sEglContext = EGL_NO_CONTEXT; | 
 | static EGLSurface sEglSurface = EGL_NO_SURFACE; | 
 |  | 
 | const char *egl_strerror(unsigned err) | 
 | { | 
 |     switch(err){ | 
 |         case EGL_SUCCESS: return "SUCCESS"; | 
 |         case EGL_NOT_INITIALIZED: return "NOT INITIALIZED"; | 
 |         case EGL_BAD_ACCESS: return "BAD ACCESS"; | 
 |         case EGL_BAD_ALLOC: return "BAD ALLOC"; | 
 |         case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE"; | 
 |         case EGL_BAD_CONFIG: return "BAD CONFIG"; | 
 |         case EGL_BAD_CONTEXT: return "BAD CONTEXT"; | 
 |         case EGL_BAD_CURRENT_SURFACE: return "BAD CURRENT SURFACE"; | 
 |         case EGL_BAD_DISPLAY: return "BAD DISPLAY"; | 
 |         case EGL_BAD_MATCH: return "BAD MATCH"; | 
 |         case EGL_BAD_NATIVE_PIXMAP: return "BAD NATIVE PIXMAP"; | 
 |         case EGL_BAD_NATIVE_WINDOW: return "BAD NATIVE WINDOW"; | 
 |         case EGL_BAD_PARAMETER: return "BAD PARAMETER"; | 
 |         case EGL_BAD_SURFACE: return "BAD_SURFACE"; | 
 |         //    case EGL_CONTEXT_LOST: return "CONTEXT LOST"; | 
 |         default: return "UNKNOWN"; | 
 |     } | 
 | } | 
 |  | 
 | void egl_error(const char *name) | 
 | { | 
 |     unsigned err = eglGetError(); | 
 |     if(err != EGL_SUCCESS) { | 
 |         fprintf(stderr,"%s(): egl error 0x%x (%s)\n",  | 
 |                 name, err, egl_strerror(err)); | 
 |     } | 
 | } | 
 |  | 
 | static void checkGLErrors() | 
 | { | 
 |     GLenum error = glGetError(); | 
 |     if (error != GL_NO_ERROR) | 
 |         fprintf(stderr, "GL Error: 0x%04x\n", (int)error); | 
 | } | 
 |  | 
 |  | 
 | static void checkEGLErrors() | 
 | { | 
 |     EGLint error = eglGetError(); | 
 |     // GLESonGL seems to be returning 0 when there is no errors? | 
 |     if (error && error != EGL_SUCCESS) | 
 |         fprintf(stderr, "EGL Error: 0x%04x\n", (int)error); | 
 | } | 
 |  | 
 | static int initGraphics(EGLint samples, const WindowSurface& windowSurface) | 
 | { | 
 |     EGLint configAttribs[] = { | 
 |             EGL_DEPTH_SIZE, 16, | 
 |             EGL_SAMPLE_BUFFERS, samples ? 1 : 0, | 
 |                     EGL_SAMPLES, samples, | 
 |                     EGL_NONE | 
 |     }; | 
 |  | 
 |     EGLint majorVersion; | 
 |     EGLint minorVersion; | 
 |     EGLContext context; | 
 |     EGLConfig config; | 
 |     EGLSurface surface; | 
 |     EGLDisplay dpy; | 
 |  | 
 |     EGLNativeWindowType window = windowSurface.getSurface(); | 
 |  | 
 |     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 
 |     eglInitialize(dpy, &majorVersion, &minorVersion); | 
 |  | 
 |     status_t err = EGLUtils::selectConfigForNativeWindow( | 
 |             dpy, configAttribs, window, &config); | 
 |     if (err) { | 
 |         fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n"); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     surface = eglCreateWindowSurface(dpy, config, window, NULL); | 
 |     egl_error("eglCreateWindowSurface"); | 
 |  | 
 |     fprintf(stderr,"surface = %p\n", surface); | 
 |  | 
 |     context = eglCreateContext(dpy, config, NULL, NULL); | 
 |     egl_error("eglCreateContext"); | 
 |     fprintf(stderr,"context = %p\n", context); | 
 |  | 
 |     eglMakeCurrent(dpy, surface, surface, context); | 
 |     egl_error("eglMakeCurrent"); | 
 |  | 
 |     eglQuerySurface(dpy, surface, EGL_WIDTH, &sWindowWidth); | 
 |     eglQuerySurface(dpy, surface, EGL_HEIGHT, &sWindowHeight); | 
 |  | 
 |     sEglDisplay = dpy; | 
 |     sEglSurface = surface; | 
 |     sEglContext = context; | 
 |  | 
 |     if (samples == 0) { | 
 |         // GL_MULTISAMPLE is enabled by default | 
 |         glDisable(GL_MULTISAMPLE); | 
 |     } | 
 |  | 
 |     return EGL_TRUE; | 
 | } | 
 |  | 
 |  | 
 | static void deinitGraphics() | 
 | { | 
 |     eglMakeCurrent(sEglDisplay, NULL, NULL, NULL); | 
 |     eglDestroyContext(sEglDisplay, sEglContext); | 
 |     eglDestroySurface(sEglDisplay, sEglSurface); | 
 |     eglTerminate(sEglDisplay); | 
 | } | 
 |  | 
 |  | 
 | int main(int argc, char *argv[]) | 
 | { | 
 |     unsigned samples = 0; | 
 |     printf("usage: %s [samples]\n", argv[0]); | 
 |     if (argc == 2) { | 
 |         samples = atoi( argv[1] ); | 
 |         printf("Multisample enabled: GL_SAMPLES = %u\n", samples); | 
 |     } | 
 |  | 
 |     WindowSurface windowSurface; | 
 |     if (!initGraphics(samples, windowSurface)) | 
 |     { | 
 |         fprintf(stderr, "Graphics initialization failed.\n"); | 
 |         return EXIT_FAILURE; | 
 |     } | 
 |  | 
 |     appInit(); | 
 |  | 
 |     struct timeval timeTemp; | 
 |     int frameCount = 0; | 
 |     gettimeofday(&timeTemp, NULL); | 
 |     double totalTime = timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec; | 
 |  | 
 |     while (gAppAlive) | 
 |     { | 
 |         struct timeval timeNow; | 
 |  | 
 |         gettimeofday(&timeNow, NULL); | 
 |         appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000, | 
 |                 sWindowWidth, sWindowHeight); | 
 |         checkGLErrors(); | 
 |         eglSwapBuffers(sEglDisplay, sEglSurface); | 
 |         checkEGLErrors(); | 
 |         frameCount++; | 
 |     } | 
 |  | 
 |     gettimeofday(&timeTemp, NULL); | 
 |  | 
 |     appDeinit(); | 
 |     deinitGraphics(); | 
 |  | 
 |     totalTime = (timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec) - totalTime; | 
 |     printf("totalTime=%f s, frameCount=%d, %.2f fps\n", | 
 |             totalTime, frameCount, frameCount/totalTime); | 
 |  | 
 |     return EXIT_SUCCESS; | 
 | } |