Improving context switch test.

The new test renders the same workload but varies the number of switches
between the contexts.
Additionally cleaned up tracing, tweaked some benchmarks and added an
FBO read back.

Change-Id: I27f54e811735997d1fd905840d821db0b38db7e3
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp b/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
index 439e451..5b74bf3 100644
--- a/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
+++ b/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
@@ -139,7 +139,7 @@
 
     GLuint err = glGetError();
     if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+        ALOGE("GLError %d", err);
         return false;
     }
 
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp b/suite/pts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
index bd132b9..1d9cc88 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
@@ -92,6 +92,9 @@
 extern "C" JNIEXPORT void JNICALL
 Java_com_android_pts_opengl_primitive_GLActivity_setupContextSwitchBenchmark(
         JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    gRenderer = new ContextSwitchRenderer(
-            ANativeWindow_fromSurface(env, surface), offscreen, workload);
+    if (workload <= 8) {
+        // This test uses 8 iterations, so workload can't be more than 8.
+        gRenderer = new ContextSwitchRenderer(
+                ANativeWindow_fromSurface(env, surface), offscreen, workload);
+    }
 }
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/Renderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/Renderer.cpp
index 4bc0cda..fa3ec83 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/Renderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/Renderer.cpp
@@ -18,8 +18,7 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
 static const EGLint contextAttribs[] = {
         EGL_CONTEXT_CLIENT_VERSION, 2,
@@ -42,7 +41,7 @@
 }
 
 bool Renderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     if (EGL_NO_DISPLAY == mEglDisplay || EGL_SUCCESS != eglGetError()) {
         return false;
@@ -87,12 +86,16 @@
     glViewport(0, 0, width, height);
 
     if (mOffscreen) {
-        int w = GLUtils::roundUpToSmallestPowerOf2(width);
-        int h = GLUtils::roundUpToSmallestPowerOf2(height);
-        if (!GLUtils::createFBO(mFboId, mRboId, mCboId, w, h)) {
+        mFboWidth = GLUtils::roundUpToSmallestPowerOf2(width);
+        mFboHeight = GLUtils::roundUpToSmallestPowerOf2(height);
+        if (!GLUtils::createFBO(mFboId, mRboId, mCboId, mFboWidth, mFboHeight)) {
             return false;
         }
+        mBuffer = new GLushort[mFboWidth * mFboHeight];
     } else {
+        mFboWidth = 0;
+        mFboHeight = 0;
+        mBuffer = 0;
         mFboId = 0;
         mRboId = 0;
         mCboId = 0;
@@ -100,14 +103,17 @@
 
     GLuint err = glGetError();
     if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+        ALOGE("GLError %d", err);
         return false;
     }
     return true;
 }
 
 bool Renderer::tearDown() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
+    if (mBuffer != 0) {
+        delete[] mBuffer;
+    }
     if (mFboId != 0) {
         glDeleteFramebuffers(1, &mFboId);
         mFboId = 0;
@@ -135,3 +141,20 @@
     }
     return EGL_SUCCESS == eglGetError();
 }
+
+bool Renderer::draw() {
+    SCOPED_TRACE();
+    GLuint err = glGetError();
+    if (err != GL_NO_ERROR) {
+        ALOGE("GLError %d", err);
+        return false;
+    }
+
+    if (mOffscreen) {
+        // Read the pixels back from the frame buffer.
+        glReadPixels(0, 0, mFboWidth, mFboHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, mBuffer);
+        return true;
+    } else {
+        return eglSwapBuffers(mEglDisplay, mEglSurface);
+    }
+}
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/Renderer.h b/suite/pts/deviceTests/opengl/jni/primitive/Renderer.h
index 49c7e98..cbe9419 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/Renderer.h
+++ b/suite/pts/deviceTests/opengl/jni/primitive/Renderer.h
@@ -25,7 +25,7 @@
     Renderer(ANativeWindow* window, bool offscreen, int workload);
     virtual bool setUp();
     virtual bool tearDown();
-    virtual bool draw() = 0;
+    virtual bool draw();
     virtual ~Renderer() {};
 protected:
     ANativeWindow* mWindow;
@@ -33,9 +33,12 @@
     EGLSurface mEglSurface;
     EGLContext mEglContext;
     EGLConfig mGlConfig;
-    GLuint mFboId; //Frame buffer
-    GLuint mRboId; //Depth buffer
-    GLuint mCboId; //Color buffer
+    int mFboWidth;// Frame buffer width
+    int mFboHeight;// Frame buffer height
+    GLuint mFboId;// Frame buffer id
+    GLuint mRboId;// Depth buffer id
+    GLuint mCboId;// Color buffer id
+    GLushort* mBuffer;// Used for FBO read back
     GLuint mProgramId;
     EGLint width;
     EGLint height;
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/Trace.h b/suite/pts/deviceTests/opengl/jni/primitive/Trace.h
new file mode 100644
index 0000000..713d3a0
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/primitive/Trace.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+#ifndef TRACE_H
+#define TRACE_H
+
+// #define TRACE
+
+#ifdef TRACE
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <utils/Trace.h>
+#define SCOPED_TRACE() android::ScopedTrace st(ATRACE_TAG, __func__)
+#else
+#define SCOPED_TRACE()
+#endif
+
+#endif
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
index cdfaaec..e365db6 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
@@ -27,21 +27,22 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
 static const EGLint contextAttribs[] =
         { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
 
+static const int NUM_WORKER_CONTEXTS = 7;
+
 static const int CS_NUM_VERTICES = 6;
 
 static const float CS_VERTICES[CS_NUM_VERTICES * 3] = {
-        1.0f, 1.0f, -1.0f,
-        -1.0f, 1.0f, -1.0f,
-        -1.0f, -1.0f, -1.0f,
-        -1.0f, -1.0f, -1.0f,
-        1.0f, -1.0f, -1.0f,
-        1.0f, 1.0f, -1.0f };
+        0.1f, 0.1f, -0.1f,
+        -0.1f, 0.1f, -0.1f,
+        -0.1f, -0.1f, -0.1f,
+        -0.1f, -0.1f, -0.1f,
+        0.1f, -0.1f, -0.1f,
+        0.1f, 0.1f, -0.1f };
 
 static const float CS_TEX_COORDS[CS_NUM_VERTICES * 2] = {
         1.0f, 1.0f,
@@ -54,10 +55,12 @@
 static const char* CS_VERTEX =
         "attribute vec4 a_Position;"
         "attribute vec2 a_TexCoord;"
+        "uniform float u_Translate;"
         "varying vec2 v_TexCoord;"
         "void main() {"
         "  v_TexCoord = a_TexCoord;"
         "  gl_Position = a_Position;"
+        "  gl_Position.x = a_Position.x + u_Translate;"
         "}";
 
 static const char* CS_FRAGMENT =
@@ -73,31 +76,32 @@
 }
 
 bool ContextSwitchRenderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (!Renderer::setUp()) {
         return false;
     }
 
-    // We don't need the context created by Renderer.
-    eglDestroyContext(mEglDisplay, mEglContext);
-    mEglContext = EGL_NO_CONTEXT;
-
-    int w = GLUtils::roundUpToSmallestPowerOf2(width);
-    int h = GLUtils::roundUpToSmallestPowerOf2(height);
-
-    mContexts = new EGLContext[mWorkload];
-    mTextureIds = new GLuint[mWorkload];
-    mProgramIds = new GLuint[mWorkload];
-    mTextureUniformHandles = new GLuint[mWorkload];
-    mPositionHandles = new GLuint[mWorkload];
-    mTexCoordHandles = new GLuint[mWorkload];
-    if (mOffscreen) {
-        mFboIds = new GLuint[mWorkload];
-        mRboIds = new GLuint[mWorkload];
-        mCboIds = new GLuint[mWorkload];
+    // Setup texture.
+    mTextureId = GLUtils::genRandTex(64, 64);
+    if (mTextureId == 0) {
+        return false;
     }
-    for (int i = 0; i < mWorkload; i++) {
-        mContexts[i] = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, contextAttribs);
+
+    // Create program.
+    mProgramId = GLUtils::createProgram(&CS_VERTEX, &CS_FRAGMENT);
+    if (mProgramId == 0) {
+        return false;
+    }
+    // Bind attributes.
+    mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
+    mTranslateUniformHandle = glGetUniformLocation(mProgramId, "u_Translate");
+    mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
+    mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");
+
+    mContexts = new EGLContext[NUM_WORKER_CONTEXTS];
+    for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
+        // Create the contexts, they share data with the main one.
+        mContexts[i] = eglCreateContext(mEglDisplay, mGlConfig, mEglContext, contextAttribs);
         if (EGL_NO_CONTEXT == mContexts[i] || EGL_SUCCESS != eglGetError()) {
             return false;
         }
@@ -106,34 +110,11 @@
                 || EGL_SUCCESS != eglGetError()) {
             return false;
         }
-
-        if (mOffscreen) {
-            // Setup FBOs.
-            if (!GLUtils::createFBO(mFboIds[i], mRboIds[i], mCboIds[i], w, h)) {
-                return false;
-            }
-        }
-
-        // Setup textures.
-        mTextureIds[i] = GLUtils::genRandTex(64, 64);
-        if (mTextureIds[i] == 0) {
-            return false;
-        }
-
-        // Create program.
-        mProgramIds[i] = GLUtils::createProgram(&CS_VERTEX, &CS_FRAGMENT);
-        if (mProgramIds[i] == 0) {
-            return false;
-        }
-        // Bind attributes.
-        mTextureUniformHandles[i] = glGetUniformLocation(mProgramIds[i], "u_Texture");
-        mPositionHandles[i] = glGetAttribLocation(mProgramIds[i], "a_Position");
-        mTexCoordHandles[i] = glGetAttribLocation(mProgramIds[i], "a_TexCoord");
     }
 
     GLuint err = glGetError();
     if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+        ALOGE("GLError %d", err);
         return false;
     }
 
@@ -141,30 +122,17 @@
 }
 
 bool ContextSwitchRenderer::tearDown() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mContexts) {
-        for (int i = 0; i < mWorkload; i++) {
+        // Destroy the contexts, the main one will be handled by Renderer::tearDown().
+        for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
             eglDestroyContext(mEglDisplay, mContexts[i]);
         }
         delete[] mContexts;
     }
-    if (mOffscreen) {
-        if (mFboIds) {
-            glDeleteFramebuffers(mWorkload, mFboIds);
-            delete[] mFboIds;
-        }
-        if (mRboIds) {
-            glDeleteRenderbuffers(mWorkload, mRboIds);
-            delete[] mRboIds;
-        }
-        if (mCboIds) {
-            glDeleteRenderbuffers(mWorkload, mCboIds);
-            delete[] mCboIds;
-        }
-    }
-    if (mTextureIds) {
-        glDeleteTextures(mWorkload, mTextureIds);
-        delete[] mTextureIds;
+    if (mTextureId != 0) {
+        glDeleteTextures(1, &mTextureId);
+        mTextureId = 0;
     }
     if (!Renderer::tearDown()) {
         return false;
@@ -173,46 +141,64 @@
 }
 
 bool ContextSwitchRenderer::draw() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
-    for (int i = 0; i < mWorkload; i++) {
-        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i])
-                || EGL_SUCCESS != eglGetError()) {
-            return false;
-        }
+    SCOPED_TRACE();
 
-        if (mOffscreen) {
-            glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
-            if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-                return false;
-            }
-        }
-
-        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-
-        glUseProgram(mProgramIds[i]);
-        glActiveTexture(GL_TEXTURE0);
-        // Bind the texture to this unit.
-        glBindTexture(GL_TEXTURE_2D, mTextureIds[i]);
-
-        // Tell the texture uniform sampler to use this texture in the shader by binding to texture
-        // unit 0.
-        glUniform1i(mTextureUniformHandles[i], 0);
-
-        glEnableVertexAttribArray(mPositionHandles[i]);
-        glEnableVertexAttribArray(mTexCoordHandles[i]);
-        glVertexAttribPointer(mPositionHandles[i], 3, GL_FLOAT, false, 0, CS_VERTICES);
-        glVertexAttribPointer(mTexCoordHandles[i], 2, GL_FLOAT, false, 0, CS_TEX_COORDS);
-
-        glDrawArrays(GL_TRIANGLES, 0, CS_NUM_VERTICES);
-        glFinish();
-    }
-
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+    if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
+            || EGL_SUCCESS != eglGetError()) {
         return false;
     }
 
-    return (mOffscreen) ? true : eglSwapBuffers(mEglDisplay, mEglSurface);
+    if (mOffscreen) {
+        glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
+    }
+
+    // Set the background clear color to black.
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    // No culling of back faces
+    glDisable(GL_CULL_FACE);
+    // No depth testing
+    glDisable(GL_DEPTH_TEST);
+
+    const int TOTAL_NUM_CONTEXTS = NUM_WORKER_CONTEXTS + 1;
+    const float TRANSLATION = 0.9f - (TOTAL_NUM_CONTEXTS * 0.2f);
+    for (int i = 0; i < TOTAL_NUM_CONTEXTS; i++) {
+        glUseProgram(mProgramId);
+
+        glActiveTexture (GL_TEXTURE0);
+        // Bind the texture to this unit.
+        glBindTexture(GL_TEXTURE_2D, mTextureId);
+
+        // Tell the texture uniform sampler to use this texture in the shader by binding to texture
+        // unit 0.
+        glUniform1i(mTextureUniformHandle, 0);
+
+        // Set the x translate.
+        glUniform1f(mTranslateUniformHandle, (i * 0.2f) + TRANSLATION);
+
+        glEnableVertexAttribArray(mPositionHandle);
+        glEnableVertexAttribArray(mTexCoordHandle);
+        glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, CS_VERTICES);
+        glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, CS_TEX_COORDS);
+
+        glDrawArrays(GL_TRIANGLES, 0, CS_NUM_VERTICES);
+
+        // Switch to next context.
+        if (i < (mWorkload - 1)) {
+            if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i])
+                    || EGL_SUCCESS != eglGetError()) {
+                return false;
+            }
+        }
+    }
+
+    if (mOffscreen) {
+        // Need to switch back to the main context so the renderer can do the read back.
+        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
+                || EGL_SUCCESS != eglGetError()) {
+            return false;
+        }
+    }
+
+    return Renderer::draw();
 }
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
index 24d8df1..d4e7595 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
+++ b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
@@ -24,18 +24,12 @@
     bool tearDown();
     bool draw();
 private:
+    EGLContext* mContexts;
+    GLuint mTextureId;
     GLuint mTextureUniformHandle;
+    GLuint mTranslateUniformHandle;
     GLuint mPositionHandle;
     GLuint mTexCoordHandle;
-    EGLContext* mContexts;
-    GLuint* mTextureIds;
-    GLuint* mFboIds;
-    GLuint* mRboIds;
-    GLuint* mCboIds;
-    GLuint* mProgramIds;
-    GLuint* mTextureUniformHandles;
-    GLuint* mPositionHandles;
-    GLuint* mTexCoordHandles;
 };
 
 #endif
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
index 3db5eea..f178912 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
@@ -11,7 +11,6 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-#include <math.h>
 #include <EGL/egl.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
@@ -27,8 +26,7 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
 static const int FP_NUM_VERTICES = 6;
 
@@ -104,7 +102,7 @@
 }
 
 bool FullPipelineRenderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (!Renderer::setUp()) {
         return false;
     }
@@ -126,12 +124,12 @@
     float centerY = 0.0f;
     float centerZ = 0.0f;
 
-    // Set our up vector. This is where our head would be pointing were we holding the camera.
+    // Set our up vector.
     float upX = 0.0f;
     float upY = 1.0f;
     float upZ = 0.0f;
 
-    // Set the view matrix. This matrix can be said to represent the camera position.
+    // Set the view matrix.
     mViewMatrix = Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
 
     // Create a new perspective projection matrix. The height will stay the same
@@ -152,9 +150,9 @@
         return false;
     }
 
-    float count = pow(2, mWorkload - 1);
+    float count = mWorkload * mWorkload;
     float middle = count / 2.0f;
-    float scale = 1.0f / count;
+    float scale = 2.0f / count;
 
     mMesh = new Mesh(FP_VERTICES, FP_NORMALS, FP_TEX_COORDS, FP_NUM_VERTICES, mTextureId);
     mSceneGraph = new ProgramNode();
@@ -173,7 +171,7 @@
 }
 
 bool FullPipelineRenderer::tearDown() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mTextureId != 0) {
         glDeleteTextures(1, &mTextureId);
         mTextureId = 0;
@@ -197,7 +195,7 @@
 }
 
 bool FullPipelineRenderer::draw() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mOffscreen) {
         glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
     }
@@ -211,16 +209,5 @@
     mModelMatrix->identity();
     mSceneGraph->draw(*mProgram, *mModelMatrix, *mViewMatrix, *mProjectionMatrix);
 
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
-        return false;
-    }
-
-    if (mOffscreen) {
-        glFinish();
-        return true;
-    } else {
-        return eglSwapBuffers(mEglDisplay, mEglSurface);
-    }
+    return Renderer::draw();
 }
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
index d2fd762..2f3d647 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
@@ -18,8 +18,7 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
 static const int PO_NUM_VERTICES = 6;
 
@@ -60,7 +59,7 @@
 }
 
 bool PixelOutputRenderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (!Renderer::setUp()) {
         return false;
     }
@@ -83,7 +82,7 @@
 }
 
 bool PixelOutputRenderer::tearDown() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mTextureId != 0) {
         glDeleteTextures(1, &mTextureId);
         mTextureId = 0;
@@ -95,7 +94,7 @@
 }
 
 bool PixelOutputRenderer::draw() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mOffscreen) {
         glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
     }
@@ -130,16 +129,5 @@
         glDrawArrays(GL_TRIANGLES, 0, PO_NUM_VERTICES);
     }
 
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
-        return false;
-    }
-
-    if (mOffscreen) {
-        glFinish();
-        return true;
-    } else {
-        return eglSwapBuffers(mEglDisplay, mEglSurface);
-    }
+    return Renderer::draw();
 }
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
index 62fe1ac..156f81e 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
@@ -20,10 +20,9 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
-static const float GOLDEN_RATIO = (1.0 + sqrt(5.0)) / 2.0;
+static const float GOLDEN_RATIO = (1.0f + sqrt(5.0f)) / 2.0f;
 
 static const int SP_NUM_VERTICES = 6;
 
@@ -63,7 +62,7 @@
 //Add workload here
 
 static const char* SP_FRAGMENT_2 =
-        " * 5;"//workload * 5 (5 is a balanced number, bigger = more work)
+        " * 4;"//workload * 4 (4 is a tweaking number, bigger = more work)
         "  vec2 z;"
         "  z.x = 3.0 * (v_TexCoord.x - 0.5);"
         "  z.y = 2.0 * (v_TexCoord.y - 0.5);"
@@ -101,7 +100,7 @@
 }
 
 bool ShaderPerfRenderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (!Renderer::setUp()) {
         return false;
     }
@@ -144,7 +143,7 @@
 
     GLuint err = glGetError();
     if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+        ALOGE("GLError %d", err);
         return false;
     }
 
@@ -152,7 +151,7 @@
 }
 
 bool ShaderPerfRenderer::draw() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mOffscreen) {
         glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
     }
@@ -180,16 +179,5 @@
 
     glDrawArrays(GL_TRIANGLES, 0, SP_NUM_VERTICES);
 
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
-        return false;
-    }
-
-    if (mOffscreen) {
-        glFinish();
-        return true;
-    } else {
-        return eglSwapBuffers(mEglDisplay, mEglSurface);
-    }
+    return Renderer::draw();
 }
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLBenchmark.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLBenchmark.java
index 0eab7cd..66405cb 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLBenchmark.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLBenchmark.java
@@ -20,7 +20,6 @@
 import android.content.Intent;
 import android.cts.util.TimeoutReq;
 import android.opengl.Matrix;
-import android.util.Log;
 
 import java.util.Arrays;
 
@@ -29,6 +28,10 @@
  */
 public class GLBenchmark extends PtsActivityInstrumentationTestCase2<GLActivity> {
 
+    private static final int NUM_FRAMES = 100;
+    private static final int NUM_ITERATIONS = 8;
+    private static final int TIME_OUT = 1000000;
+
     public GLBenchmark() {
         super(GLActivity.class);
     }
@@ -36,59 +39,65 @@
     /**
      * Runs the full OpenGL ES 2.0 pipeline test offscreen.
      */
-    @TimeoutReq(minutes = 20)
+    @TimeoutReq(minutes = 100)
     public void testFullPipelineOffscreen() throws Exception {
-        runBenchmark(Benchmark.FullPipeline, true, 500, 8, 1000000);
+        runBenchmark(Benchmark.FullPipeline, true, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the full OpenGL ES 2.0 pipeline test onscreen.
      */
-    @TimeoutReq(minutes = 20)
+    @TimeoutReq(minutes = 100)
     public void testFullPipelineOnscreen() throws Exception {
-        runBenchmark(Benchmark.FullPipeline, false, 500, 8, 1000000);
+        runBenchmark(Benchmark.FullPipeline, false, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the pixel output test offscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testPixelOutputOffscreen() throws Exception {
-        runBenchmark(Benchmark.PixelOutput, true, 500, 8, 1000000);
+        runBenchmark(Benchmark.PixelOutput, true, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the pixel output test onscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testPixelOutputOnscreen() throws Exception {
-        runBenchmark(Benchmark.PixelOutput, false, 500, 8, 1000000);
+        runBenchmark(Benchmark.PixelOutput, false, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the shader performance test offscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testShaderPerfOffscreen() throws Exception {
-        runBenchmark(Benchmark.ShaderPerf, true, 500, 8, 1000000);
+        runBenchmark(Benchmark.ShaderPerf, true, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the shader performance test onscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testShaderPerfOnscreen() throws Exception {
-        runBenchmark(Benchmark.ShaderPerf, false, 500, 8, 1000000);
+        runBenchmark(Benchmark.ShaderPerf, false, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the context switch overhead test offscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testContextSwitchOffscreen() throws Exception {
-        runBenchmark(Benchmark.ContextSwitch, true, 500, 8, 1000000);
+        runBenchmark(Benchmark.ContextSwitch, true, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the context switch overhead test onscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testContextSwitchOnscreen() throws Exception {
-        runBenchmark(Benchmark.ContextSwitch, false, 500, 8, 1000000);
+        runBenchmark(Benchmark.ContextSwitch, false, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
@@ -124,6 +133,8 @@
                 for (double d : fpsValues) {
                     score += d;
                 }
+                score /= numIterations;// Average.
+
                 getReportLog().printArray(
                         "Fps Values", fpsValues, ResultType.HIGHER_BETTER, ResultUnit.FPS);
                 getReportLog()
diff --git a/suite/pts/utils/grapher.py b/suite/pts/utils/grapher.py
index 94bf25e..e6dfe05 100755
--- a/suite/pts/utils/grapher.py
+++ b/suite/pts/utils/grapher.py
@@ -26,6 +26,13 @@
   sudo apt-get install python-matplotlib
 """
 
+colors = {
+  'maguro':'#FF0000',
+  'mako':'#00FF00',
+  'manta':'#0000FF',
+  'tilapia':'#00FFFF'
+}
+
 def main(argv):
   if len(argv) != 2:
     print "grapher.py pts_report_dir"
@@ -44,7 +51,7 @@
       plt.title(benchmark[benchmark.index('#') + 1:])
       # For each result in the data set
       for r in results:
-        score = r['result']
+        score = r.get('result', 'no results')
         x = []
         y = []
         if score == 'pass':
@@ -56,8 +63,12 @@
         if score != 'no results':
           # Create a plot
           ax = fig.add_subplot(111)
+          name = r['device']
+          lbl = name + ' (%s)'%score
+          clr = colors.get(name, "#%06X" % (hash(name) % 0xFFFFFF))
+          print clr
           # Plot the workload vs the values
-          ax.plot(x, y, 'o-', label=r['device'] + ' (%s)'%score)
+          ax.plot(x, y, 'o-', label=lbl, color=clr)
           # Add a legend
           ax.legend(loc='upper right').get_frame().set_fill(False)
       (ymin, ymax) = plt.ylim()