Merge change 25883 into eclair

* changes:
  Draw a green triangle using OpenGL 2.0 APIs.
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index d4887ba..f97d347 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -21,8 +21,8 @@
 #include <sys/resource.h>
 
 #include <EGL/egl.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #include <utils/Timers.h>
 
@@ -31,144 +31,267 @@
 
 using namespace android;
 
-static void printGLString(const char *name, GLenum s)
-{
-     fprintf(stderr, "printGLString %s, %d\n", name, s);
-#if 0 // causes hangs
-     const char *v = (const char *)glGetString(s);
-     int error = glGetError();
-     fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
-         (unsigned int)v);
-     if ((v < (const char*) 0) || (v > (const char*) 0x10000))
-         fprintf(stderr, "GL %s = %s\n", name, v);
-     else
-         fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
-#endif
+static void printGLString(const char *name, GLenum s) {
+    // fprintf(stderr, "printGLString %s, %d\n", name, s);
+    const char *v = (const char *) glGetString(s);
+    // int error = glGetError();
+    // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+    //        (unsigned int) v);
+    // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+    //    fprintf(stderr, "GL %s = %s\n", name, v);
+    // else
+    //    fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+    fprintf(stderr, "GL %s = %s\n", name, v);
 }
 
 static const char* eglErrorToString[] = {
-    "EGL_SUCCESS",      // 0x3000 12288
-    "EGL_NOT_INITIALIZED",
-    "EGL_BAD_ACCESS",   // 0x3002 12290
-    "EGL_BAD_ALLOC",
-    "EGL_BAD_ATTRIBUTE",
-    "EGL_BAD_CONFIG",
-    "EGL_BAD_CONTEXT",  // 0x3006 12294
-    "EGL_BAD_CURRENT_SURFACE",
-    "EGL_BAD_DISPLAY",
-    "EGL_BAD_MATCH",
-    "EGL_BAD_NATIVE_PIXMAP",
-    "EGL_BAD_NATIVE_WINDOW",
-    "EGL_BAD_PARAMETER",  // 0x300c 12300
-    "EGL_BAD_SURFACE"
-};
+        "EGL_SUCCESS", // 0x3000 12288
+        "EGL_NOT_INITIALIZED",
+        "EGL_BAD_ACCESS", // 0x3002 12290
+        "EGL_BAD_ALLOC", "EGL_BAD_ATTRIBUTE",
+        "EGL_BAD_CONFIG",
+        "EGL_BAD_CONTEXT", // 0x3006 12294
+        "EGL_BAD_CURRENT_SURFACE", "EGL_BAD_DISPLAY", "EGL_BAD_MATCH",
+        "EGL_BAD_NATIVE_PIXMAP", "EGL_BAD_NATIVE_WINDOW", "EGL_BAD_PARAMETER", // 0x300c 12300
+        "EGL_BAD_SURFACE" };
 
 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
     if (returnVal != EGL_TRUE) {
         fprintf(stderr, "%s() returned %d\n", op, returnVal);
     }
 
-    for(EGLint error = eglGetError();
-		error != EGL_SUCCESS;
-	error = eglGetError()) {
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
         const char* errorString = "unknown";
         if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) {
             errorString = eglErrorToString[error - EGL_SUCCESS];
         }
-        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op,
-            errorString, error);
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, errorString,
+                error);
     }
 }
 
-int main(int argc, char** argv)
-{
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+    }
+}
+
+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+    "void main() {\n"
+    "  gl_Position = vPosition;\n"
+    "}\n";
+
+static const char gFragmentShader[] = "precision mediump float;\n"
+    "void main() {\n"
+    "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+    "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+    GLuint shader = glCreateShader(shaderType);
+    if (shader) {
+        glShaderSource(shader, 1, &pSource, NULL);
+        glCompileShader(shader);
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                    fprintf(stderr, "Could not compile shader %d:\n%s\n",
+                            shaderType, buf);
+                    free(buf);
+                }
+                glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+    }
+    return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+    if (!vertexShader) {
+        return 0;
+    }
+
+    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+    if (!pixelShader) {
+        return 0;
+    }
+
+    GLuint program = glCreateProgram();
+    if (program) {
+        glAttachShader(program, vertexShader);
+        checkGlError("glAttachShader");
+        glAttachShader(program, pixelShader);
+        checkGlError("glAttachShader");
+        glLinkProgram(program);
+        GLint linkStatus = GL_FALSE;
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+        if (linkStatus != GL_TRUE) {
+            GLint bufLength = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+            if (bufLength) {
+                char* buf = (char*) malloc(bufLength);
+                if (buf) {
+                    glGetProgramInfoLog(program, bufLength, NULL, buf);
+                    fprintf(stderr, "Could not link program:\n%s\n", buf);
+                    free(buf);
+                }
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    return program;
+}
+
+GLuint gProgram;
+GLuint gvPositionHandle;
+
+bool setupGraphics(int w, int h) {
+    gProgram = createProgram(gVertexShader, gFragmentShader);
+    if (!gProgram) {
+        return false;
+    }
+    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+    checkGlError("glGetAttribLocation");
+    fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n",
+            gvPositionHandle);
+
+    glViewport(0, 0, w, h);
+    checkGlError("glViewport");
+    return true;
+}
+
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+        0.5f, -0.5f };
+
+void renderFrame() {
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    checkGlError("glClearColor");
+    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    checkGlError("glClear");
+
+    glUseProgram(gProgram);
+    checkGlError("glUseProgram");
+
+    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+    checkGlError("glVertexAttribPointer");
+    glEnableVertexAttribArray(gvPositionHandle);
+    checkGlError("glEnableVertexAttribArray");
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+    checkGlError("glDrawArrays");
+}
+
+int main(int argc, char** argv) {
     EGLBoolean returnValue;
     EGLConfig configs[2];
     EGLint config_count;
 
-	EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
-    EGLint s_configAttribs[] = {
-	EGL_BUFFER_SIZE,     EGL_DONT_CARE,
-	EGL_RED_SIZE,        5,
-	EGL_GREEN_SIZE,      6,
-	EGL_BLUE_SIZE,       5,
-	EGL_DEPTH_SIZE,      8,
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-	EGL_NONE
-     };
+    EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint s_configAttribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_RED_SIZE,
+            5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 8,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
 
-     EGLint majorVersion;
-     EGLint minorVersion;
-     EGLContext context;
-     EGLSurface surface;
-     EGLint w, h;
+    EGLint s_configAttribs2[] =
+    {
+            EGL_DEPTH_SIZE,     16,
+            EGL_NONE
+    };
 
-     EGLDisplay dpy;
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLSurface surface;
+    EGLint w, h;
 
-     EGLNativeWindowType window = 0;
-     window = android_createDisplaySurface();
+    EGLDisplay dpy;
 
-     checkEglError("<init>");
-     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     checkEglError("eglGetDisplay");
-     if (dpy == EGL_NO_DISPLAY) {
-         printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
-         return 0;
-     }
-     returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
-     checkEglError("eglInitialize", returnValue);
-     fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    EGLNativeWindowType window = 0;
+    window = android_createDisplaySurface();
 
-     returnValue = eglGetConfigs (dpy, configs, 2, &config_count);
-     checkEglError("eglGetConfigs", returnValue);
-     fprintf(stderr, "Config count: %d\n", config_count);
-     for(int i = 0; i < config_count; i++) {
+    checkEglError("<init>");
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (dpy == EGL_NO_DISPLAY) {
+        printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+        return 0;
+    }
+
+    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    if (returnValue != EGL_TRUE) {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    returnValue = eglGetConfigs(dpy, configs, 2, &config_count);
+    checkEglError("eglGetConfigs", returnValue);
+    fprintf(stderr, "Config count: %d\n", config_count);
+    for (int i = 0; i < config_count; i++) {
         fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]);
-     }
+    }
+
 #if 0
-     EGLConfig config;
-     EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
-     checkEglError("EGLUtils::selectConfigForNativeWindow");
+    EGLConfig config;
+    EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
 #else
-    int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs, configs, 2, &config_count);
+    int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs2, configs, 2,
+            &config_count);
     checkEglError("eglChooseConfig", chooseConfigResult);
-    if (chooseConfigResult != EGL_TRUE )

-    {

+    if (chooseConfigResult != EGL_TRUE) {
         printf("eglChooseConfig failed\n");
-        return 0;

+        return 0;
     }
 #endif
 
-     surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
-     checkEglError("eglCreateWindowSurface");
-     if (surface == EGL_NO_SURFACE)
-	 {
-         printf("gelCreateWindowSurface failed.\n");
-         return 0;
-	 }
-     EGLint gl2_0Attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+    surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (surface == EGL_NO_SURFACE) {
+        printf("gelCreateWindowSurface failed.\n");
+        return 0;
+    }
+    EGLint gl2_0Attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
 
-     context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
-     checkEglError("eglCreateContext");
-	 if (context == EGL_NO_CONTEXT)
-     {
+    context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
         printf("eglCreateContext failed\n");
         return 0;
-	 }
-     eglMakeCurrent(dpy, surface, surface, context);
-     checkEglError("eglMakeCurrent");
-     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
-     checkEglError("eglQuerySurface");
-     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
-     checkEglError("eglQuerySurface");
-     GLint dim = w<h ? w : h;
+    }
+    eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent");
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+    checkEglError("eglQuerySurface");
+    GLint dim = w < h ? w : h;
 
-     fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
 
-     printGLString("Version", GL_VERSION);
-     printGLString("Vendor", GL_VENDOR);
-     printGLString("Renderer", GL_RENDERER);
-     printGLString("Extensions", GL_EXTENSIONS);
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);
 
-     return 0;
+    if(!setupGraphics(w, h)) {
+        fprintf(stderr, "Could not set up graphics.\n");
+        return 0;
+    }
+
+    for (;;) {
+        renderFrame();
+        eglSwapBuffers(dpy, surface);
+    }
+
+    return 0;
 }