Merge "Fix AtraceHostTest to not rely on parsing tgid" into mnc-dev
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp
index b8e2acf..16504fd 100644
--- a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp
@@ -22,6 +22,14 @@
 
 // Used to center the grid on the screen.
 #define CENTER_GRID(x) ((((x) * 2.0 + 1) - OFFSCREEN_GRID_SIZE) / OFFSCREEN_GRID_SIZE)
+// Leave a good error message if something fails.
+#define EGL_RESULT_CHECK(X) do { \
+                                   EGLint error = eglGetError(); \
+                                   if (!(X) || error != EGL_SUCCESS) { \
+                                       ALOGE("EGL error '%d' at %s:%d", error, __FILE__, __LINE__);\
+                                       return false; \
+                                    } \
+                            } while (0)
 
 static const int FBO_NUM_VERTICES = 6;
 
@@ -66,7 +74,7 @@
         EGL_NONE };
 
 static const EGLint configAttribs[] = {
-        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
         EGL_RED_SIZE, 8,
         EGL_GREEN_SIZE, 8,
@@ -78,53 +86,60 @@
 
 static const int FBO_SIZE = 128;
 
-Renderer::Renderer(ANativeWindow* window, bool offscreen, int workload) :
-        mOffscreen(offscreen), mWindow(window), mEglDisplay(EGL_NO_DISPLAY),
-        mEglSurface(EGL_NO_SURFACE), mEglContext(EGL_NO_CONTEXT), mWorkload(workload) {
+Renderer::Renderer(EGLNativeWindowType window, bool offscreen) :
+        mOffscreen(offscreen), mEglDisplay(EGL_NO_DISPLAY), mEglSurface(EGL_NO_SURFACE),
+        mEglContext(EGL_NO_CONTEXT), mWindow(window)  {
 }
 
-bool Renderer::setUp() {
+bool Renderer::eglSetUp() {
     SCOPED_TRACE();
     mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    if (EGL_NO_DISPLAY == mEglDisplay || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+    EGL_RESULT_CHECK(mEglDisplay != EGL_NO_DISPLAY);
 
     EGLint major;
     EGLint minor;
-    if (!eglInitialize(mEglDisplay, &major, &minor) || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+    EGL_RESULT_CHECK(eglInitialize(mEglDisplay, &major, &minor));
 
     EGLint numConfigs = 0;
-    if (!eglChooseConfig(mEglDisplay, configAttribs, &mGlConfig, 1, &numConfigs)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+    EGL_RESULT_CHECK(eglChooseConfig(mEglDisplay, configAttribs, &mGlConfig, 1, &numConfigs)
+                     && (numConfigs > 0));
 
     mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig, mWindow, NULL);
-    if (EGL_NO_SURFACE == mEglSurface || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+    EGL_RESULT_CHECK(mEglSurface != EGL_NO_SURFACE);
 
     mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, contextAttribs);
-    if (EGL_NO_CONTEXT == mEglContext || EGL_SUCCESS != eglGetError()) {
-        return false;
+    EGL_RESULT_CHECK(mEglContext != EGL_NO_CONTEXT);
+
+    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
+    EGL_RESULT_CHECK(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mWidth));
+    EGL_RESULT_CHECK(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mHeight));
+
+    return true;
+}
+
+void Renderer::eglTearDown() {
+    SCOPED_TRACE();
+    eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+    if (mEglContext != EGL_NO_CONTEXT) {
+        eglDestroyContext(mEglDisplay, mEglContext);
+        mEglContext = EGL_NO_CONTEXT;
     }
 
-    if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
+    if (mEglSurface != EGL_NO_SURFACE) {
+        mEglSurface = EGL_NO_SURFACE;
     }
 
-    if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mWidth)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
+    if (mEglDisplay != EGL_NO_DISPLAY) {
+        eglTerminate(mEglDisplay);
+        mEglDisplay = EGL_NO_DISPLAY;
     }
-    if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mHeight)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+}
+
+bool Renderer::setUp(int /*workload*/) {
+    SCOPED_TRACE();
+
+    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
 
     if (mOffscreen) {
         mFboWidth = FBO_SIZE;
@@ -178,6 +193,7 @@
         ALOGE("GLError %d in setUp", err);
         return false;
     }
+
     return true;
 }
 
@@ -202,29 +218,14 @@
         ALOGE("GLError %d in tearDown", err);
         return false;
     }
-    if (mEglContext != EGL_NO_CONTEXT) {
-        eglDestroyContext(mEglDisplay, mEglContext);
-        mEglContext = EGL_NO_CONTEXT;
-    }
-    if (mEglSurface != EGL_NO_SURFACE) {
-        eglDestroySurface(mEglDisplay, mEglSurface);
-        mEglSurface = EGL_NO_SURFACE;
-    }
-    if (mEglDisplay != EGL_NO_DISPLAY) {
-        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-        eglTerminate(mEglDisplay);
-        mEglDisplay = EGL_NO_DISPLAY;
-    }
 
-    return EGL_SUCCESS == eglGetError();
+    return true;
 }
 
 bool Renderer::draw() {
     SCOPED_TRACE();
-    if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+
+    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
 
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     glViewport(0, 0, mWidth, mHeight);
@@ -287,5 +288,6 @@
         return false;
     }
 
-    return eglSwapBuffers(mEglDisplay, mEglSurface);
+    EGL_RESULT_CHECK(eglSwapBuffers(mEglDisplay, mEglSurface)); 
+    return true;
 }
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h
index caa1634..3c62a26 100644
--- a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h
+++ b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h
@@ -14,17 +14,18 @@
 #ifndef RENDERER_H
 #define RENDERER_H
 
-#include <android/native_window.h>
-
 #include <EGL/egl.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
 class Renderer {
 public:
-    Renderer(ANativeWindow* window, bool offscreen, int workload);
-    virtual bool setUp();
+    Renderer(EGLNativeWindowType window, bool offscreen);
+    virtual bool setUp(int workload);
     virtual bool tearDown();
+    bool eglSetUp();
+    void eglTearDown();
+
     bool draw();
     virtual void drawWorkload() = 0;
     virtual ~Renderer() {};
@@ -32,7 +33,6 @@
     static const int OFFSCREEN_GRID_SIZE = 10;
     bool mOffscreen;
 protected:
-    ANativeWindow* mWindow;
     EGLDisplay mEglDisplay;
     EGLSurface mEglSurface;
     EGLContext mEglContext;
@@ -40,7 +40,6 @@
     GLuint mProgramId;
     EGLint mWidth;
     EGLint mHeight;
-    int mWorkload;
     int mFboWidth;// Frame buffer width
     int mFboHeight;// Frame buffer height
     GLuint mFboId;// Frame buffer id
@@ -52,5 +51,7 @@
     GLuint mFboYOffsetUniformHandle;// Frame buffer y offset uniform handle
     GLuint mFboPositionHandle;// Frame buffer position handle
     GLuint mFboTexCoordHandle;// Frame buffer texture coordinate handle
+private:
+    EGLNativeWindowType mWindow;
 };
 #endif
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp b/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
index 9d39af9..856da1e 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
@@ -28,16 +28,24 @@
 
 // Holds the current benchmark's renderer.
 Renderer* gRenderer = NULL;
+ANativeWindow* gNativeWindow = NULL;
+
+enum {
+    FULL_PIPELINE_BENCHMARK = 0,
+    PIXEL_OUTPUT_BENCHMARK = 1,
+    SHADER_PERF_BENCHMARK = 2,
+    CONTEXT_SWITCH_BENCHMARK = 3
+};
 
 extern "C" JNIEXPORT jboolean JNICALL
 Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_startBenchmark(
-        JNIEnv* env, jclass clazz, jint numFrames, jdoubleArray frameTimes) {
+        JNIEnv* env, jclass /*clazz*/, jint workload, jint numFrames, jdoubleArray frameTimes) {
     if (gRenderer == NULL) {
         return false;
     }
 
     // Sets up the renderer.
-    bool success = gRenderer->setUp();
+    bool success = gRenderer->setUp(workload);
 
     // Records the start time.
     double start = GLUtils::currentTimeMillis();
@@ -60,41 +68,56 @@
     double times[] = {start, end};
     env->SetDoubleArrayRegion(frameTimes, 0, 2, times);
 
-    // Tears down and deletes the renderer.
     success = gRenderer->tearDown() && success;
-    delete gRenderer;
-    gRenderer = NULL;
     return success;
 }
 
 // The following functions create the renderers for the various benchmarks.
 extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupFullPipelineBenchmark(
-        JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    gRenderer = new FullPipelineRenderer(
-            ANativeWindow_fromSurface(env, surface), offscreen, workload);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupPixelOutputBenchmark(
-        JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    gRenderer = new PixelOutputRenderer(
-            ANativeWindow_fromSurface(env, surface), offscreen, workload);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupShaderPerfBenchmark(
-        JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    gRenderer = new ShaderPerfRenderer(
-            ANativeWindow_fromSurface(env, surface), offscreen, workload);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupContextSwitchBenchmark(
-        JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint 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);
+Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupBenchmark(
+        JNIEnv* env, jclass /*clazz*/, jobject surface, jint benchmark,
+        jboolean offscreen) {
+    gNativeWindow = ANativeWindow_fromSurface(env, surface);
+    switch (benchmark) {
+        case FULL_PIPELINE_BENCHMARK:
+            gRenderer = new FullPipelineRenderer(gNativeWindow, offscreen);
+            break;
+        case PIXEL_OUTPUT_BENCHMARK:
+            gRenderer = new PixelOutputRenderer(gNativeWindow, offscreen);
+            break;
+        case SHADER_PERF_BENCHMARK:
+            gRenderer = new ShaderPerfRenderer(gNativeWindow, offscreen);
+            break;
+        case CONTEXT_SWITCH_BENCHMARK:
+            gRenderer = new ContextSwitchRenderer(gNativeWindow, offscreen);
+            break;
+        default:
+            ALOGE("Unknown benchmark '%d'", benchmark);
+            ANativeWindow_release(gNativeWindow);
+            gNativeWindow = NULL;
+            return;
     }
+
+    // Set up call will log error conditions
+    if (!gRenderer->eglSetUp()) {
+        delete gRenderer;
+        gRenderer = NULL;
+
+        ANativeWindow_release(gNativeWindow);
+        gNativeWindow = NULL;
+    }
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_tearDownBenchmark(
+        JNIEnv* /*env*/, jclass /*clazz*/) {
+    if (gRenderer == NULL) {
+        return;
+    }
+    gRenderer->eglTearDown();
+    delete gRenderer;
+    gRenderer = NULL;
+
+    ANativeWindow_release(gNativeWindow);
+    gNativeWindow = NULL;
 }
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp b/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
index 7fd4093..1127d88 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
@@ -74,13 +74,14 @@
         "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
         "}";
 
-ContextSwitchRenderer::ContextSwitchRenderer(ANativeWindow* window, bool offscreen, int workload) :
-        Renderer(window, offscreen, workload), mContexts(NULL) {
+ContextSwitchRenderer::ContextSwitchRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen), mContexts(NULL), mWorkload(0) {
 }
 
-bool ContextSwitchRenderer::setUp() {
+bool ContextSwitchRenderer::setUp(int workload) {
     SCOPED_TRACE();
-    if (!Renderer::setUp()) {
+    mWorkload = workload;
+    if (!Renderer::setUp(workload)) {
         return false;
     }
 
@@ -137,7 +138,7 @@
 bool ContextSwitchRenderer::tearDown() {
     SCOPED_TRACE();
     if (mContexts) {
-        // Destroy the contexts, the main one will be handled by Renderer::tearDown().
+        // Destroy the contexts, the main one will be handled by Renderer::eglTearDown().
         for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
             if (mOffscreen) {
                 if (mFboIds[i] != 0) {
@@ -146,6 +147,7 @@
                     mFboIds[i] = 0;
                 }
             }
+            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
             eglDestroyContext(mEglDisplay, mContexts[i]);
         }
         delete[] mContexts;
@@ -163,6 +165,11 @@
 
 void ContextSwitchRenderer::drawWorkload() {
     SCOPED_TRACE();
+
+    if (mWorkload > 8) {
+        return; // This test does not support higher workloads.
+    }
+
     // 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);
@@ -216,6 +223,7 @@
         }
     }
 
+    eglWaitSyncKHR(mEglDisplay, fence, 0);
     eglDestroySyncKHR(mEglDisplay, fence);
 
     // Switch back to the main context.
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h b/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
index 51a4376..ae320ff 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
@@ -18,9 +18,9 @@
 
 class ContextSwitchRenderer: public Renderer {
 public:
-    ContextSwitchRenderer(ANativeWindow* window, bool offscreen, int workload);
+    ContextSwitchRenderer(ANativeWindow* window, bool offscreen);
     virtual ~ContextSwitchRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     bool tearDown();
     void drawWorkload();
 private:
@@ -31,6 +31,7 @@
     GLuint mTranslateUniformHandle;
     GLuint mPositionHandle;
     GLuint mTexCoordHandle;
+    int mWorkload;
 };
 
 #endif
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp b/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
index 97462b5..0f75f81 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
@@ -91,15 +91,15 @@
         "  gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));\n"
         "}";
 
-FullPipelineRenderer::FullPipelineRenderer(ANativeWindow* window, bool offscreen, int workload) :
-        Renderer(window, offscreen, workload), mProgram(NULL), mSceneGraph(NULL),
+FullPipelineRenderer::FullPipelineRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen), mProgram(NULL), mSceneGraph(NULL),
         mModelMatrix(NULL), mViewMatrix(NULL), mProjectionMatrix(NULL), mMesh(NULL),
         mTextureId(0) {
 }
 
-bool FullPipelineRenderer::setUp() {
+bool FullPipelineRenderer::setUp(int workload) {
     SCOPED_TRACE();
-    if (!Renderer::setUp()) {
+    if (!Renderer::setUp(workload)) {
         return false;
     }
 
@@ -147,7 +147,7 @@
         return false;
     }
 
-    float count = mWorkload * mWorkload;
+    float count = workload * workload;
     float middle = count / 2.0f;
     float scale = 2.0f / count;
 
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h b/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h
index 84616b4..ce44760 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h
@@ -22,9 +22,9 @@
 
 class FullPipelineRenderer: public Renderer {
 public:
-    FullPipelineRenderer(ANativeWindow* window, bool offscreen, int workload);
+    FullPipelineRenderer(ANativeWindow* window, bool offscreen);
     virtual ~FullPipelineRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     bool tearDown();
     void drawWorkload();
 private:
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp b/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
index 287ebfb..3a3b9d1 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
@@ -50,13 +50,14 @@
         "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
         "}";
 
-PixelOutputRenderer::PixelOutputRenderer(ANativeWindow* window, bool offscreen, int workload) :
-        Renderer(window, offscreen, workload) {
+PixelOutputRenderer::PixelOutputRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen), mWorkload(0) {
 }
 
-bool PixelOutputRenderer::setUp() {
+bool PixelOutputRenderer::setUp(int workload) {
     SCOPED_TRACE();
-    if (!Renderer::setUp()) {
+    mWorkload = workload;
+    if (!Renderer::setUp(workload)) {
         return false;
     }
 
@@ -80,6 +81,11 @@
 
 bool PixelOutputRenderer::tearDown() {
     SCOPED_TRACE();
+    if (mProgramId != 0)
+    {
+        glDeleteProgram(mProgramId);
+        mProgramId = 0;
+    }
     if (mTextureId != 0) {
         glDeleteTextures(1, &mTextureId);
         mTextureId = 0;
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h b/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h
index e6b5692..816da6a 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h
@@ -18,9 +18,9 @@
 
 class PixelOutputRenderer: public Renderer {
 public:
-    PixelOutputRenderer(ANativeWindow* window, bool offscreen, int workload);
+    PixelOutputRenderer(ANativeWindow* window, bool offscreen);
     virtual ~PixelOutputRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     bool tearDown();
     void drawWorkload();
 private:
@@ -28,6 +28,7 @@
     GLuint mTextureUniformHandle;
     GLuint mPositionHandle;
     GLuint mTexCoordHandle;
+    int mWorkload;
 };
 
 #endif
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp b/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
index 1cbc839..a02f4fe 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
@@ -91,13 +91,13 @@
     return destAddr - destStart;
 }
 
-ShaderPerfRenderer::ShaderPerfRenderer(ANativeWindow* window, bool offscreen, int workload) :
-        Renderer(window, offscreen, workload) {
+ShaderPerfRenderer::ShaderPerfRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen) {
 }
 
-bool ShaderPerfRenderer::setUp() {
+bool ShaderPerfRenderer::setUp(int workload) {
     SCOPED_TRACE();
-    if (!Renderer::setUp()) {
+    if (!Renderer::setUp(workload)) {
         return false;
     }
 
@@ -106,7 +106,7 @@
     // Add the first part.
     int index = charCopy(SP_FRAGMENT_1, spFragment, 0);
     // Add the count, overwriting the '\0' added by charCopy.
-    spFragment[index - 1] = (char) (((int) '0') + mWorkload);
+    spFragment[index - 1] = (char) (((int) '0') + workload);
     // Add the second part.
     index += charCopy(SP_FRAGMENT_2, spFragment, index);
     // Create program.
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h b/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h
index 52fac43..c804202 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h
@@ -18,9 +18,9 @@
 
 class ShaderPerfRenderer: public Renderer {
 public:
-    ShaderPerfRenderer(ANativeWindow* window, bool offscreen, int workload);
+    ShaderPerfRenderer(ANativeWindow* window, bool offscreen);
     virtual ~ShaderPerfRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     void drawWorkload();
 private:
     GLuint mTextureId;
diff --git a/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp b/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp
index 1857848..dc0b4e2 100644
--- a/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp
+++ b/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp
@@ -23,7 +23,7 @@
 
 extern "C" JNIEXPORT jboolean JNICALL
 Java_com_android_cts_opengl_reference_GLGameActivity_startBenchmark(
-        JNIEnv* env, jclass clazz, jobject assetManager, jobject surface, jint numFrames,
+    JNIEnv* env, jclass /*clazz*/, jobject assetManager, jobject surface, jint numFrames,
         jdoubleArray setUpTimes, jdoubleArray updateTimes, jdoubleArray renderTimes) {
 
     GLUtils::setEnvAndAssetManager(env, assetManager);
@@ -32,9 +32,10 @@
         return false;
     }
 
-    ReferenceRenderer* renderer = new ReferenceRenderer(ANativeWindow_fromSurface(env, surface));
-
-    bool success = renderer->setUp();
+    ANativeWindow* nativeWindow = ANativeWindow_fromSurface(env, surface);
+    ReferenceRenderer* renderer = new ReferenceRenderer(nativeWindow);
+    bool success = renderer->eglSetUp();
+    success = renderer->setUp(0) && success;
     env->SetDoubleArrayRegion(
             setUpTimes, 0, ReferenceRenderer::NUM_SETUP_TIMES, renderer->mSetUpTimes);
 
@@ -54,7 +55,11 @@
     env->SetDoubleArrayRegion(renderTimes, 0, numFrames, renders);
 
     success = renderer->tearDown() && success;
+    renderer->eglTearDown();
     delete renderer;
     renderer = NULL;
+
+    ANativeWindow_release(nativeWindow);
+
     return success;
 }
diff --git a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp b/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
index 8f7703e..3b12ee1 100644
--- a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
@@ -22,10 +22,10 @@
 #include <Trace.h>
 
 ReferenceRenderer::ReferenceRenderer(ANativeWindow* window) :
-        Renderer(window, false, 0) {
+        Renderer(window, false) {
 }
 
-bool ReferenceRenderer::setUp() {
+bool ReferenceRenderer::setUp(int workload) {
     SCOPED_TRACE();
     // Reset the times.
     for (int i = 0; i < NUM_SETUP_TIMES; i++) {
@@ -33,7 +33,7 @@
     }
     // Set up OpenGLES.
     double start = GLUtils::currentTimeMillis();
-    if (!Renderer::setUp()) {
+    if (!Renderer::setUp(workload)) {
         return false;
     }
     mSetUpTimes[0] = GLUtils::currentTimeMillis() - start;
diff --git a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h b/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
index d10297a..f5c4b65 100644
--- a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
@@ -23,7 +23,7 @@
 public:
     ReferenceRenderer(ANativeWindow* window);
     virtual ~ReferenceRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     bool tearDown();
     bool update(int frame);
     void drawWorkload();
diff --git a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveActivity.java b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveActivity.java
index 5dc9b88..6defdb7 100644
--- a/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveActivity.java
+++ b/suite/cts/deviceTests/opengl/src/com/android/cts/opengl/primitive/GLPrimitiveActivity.java
@@ -102,19 +102,12 @@
         }
     }
 
-    private static native void setupFullPipelineBenchmark(
-            Surface surface, boolean offscreen, int workload);
+    private static native boolean setupBenchmark(
+            Surface surface, int benchmark, boolean offscreen);
 
-    private static native void setupPixelOutputBenchmark(
-            Surface surface, boolean offscreen, int workload);
+    private static native boolean startBenchmark(int workload, int numFrames, double[] frameTimes);
 
-    private static native void setupShaderPerfBenchmark(
-            Surface surface, boolean offscreen, int workload);
-
-    private static native void setupContextSwitchBenchmark(
-            Surface surface, boolean offscreen, int workload);
-
-    private static native boolean startBenchmark(int numFrames, double[] frameTimes);
+    private static native void tearDownBenchmark();
 
     /**
      * This thread runs the benchmarks, freeing the UI thread.
@@ -138,36 +131,29 @@
             watchDog = new WatchDog(mTimeout, this);
             // Used to record the start and end time of the iteration.
             double[] times = new double[2];
-            for (int i = 0; i < mNumIterations && success; i++) {
-                // The workload to use for this iteration.
-                int workload = i + 1;
+            try {
                 // Setup the benchmark.
-                switch (mBenchmark) {
-                    case FullPipeline:
-                        setupFullPipelineBenchmark(mSurface, mOffscreen, workload);
-                        break;
-                    case PixelOutput:
-                        setupPixelOutputBenchmark(mSurface, mOffscreen, workload);
-                        break;
-                    case ShaderPerf:
-                        setupShaderPerfBenchmark(mSurface, mOffscreen, workload);
-                        break;
-                    case ContextSwitch:
-                        setupContextSwitchBenchmark(mSurface, mOffscreen, workload);
-                        break;
-                }
-                watchDog.start();
-                // Start benchmark.
-                success = startBenchmark(mNumFrames, times);
-                watchDog.stop();
-
-                if (!success) {
-                    setException(new Exception("Benchmark failed to run"));
-                } else {
-                    // Calculate FPS.
-                    mFpsValues[i] = mNumFrames * 1000.0f / (times[1] - times[0]);
+                setupBenchmark(mSurface, mBenchmark.ordinal(), mOffscreen);
+                for (int i = 0; i < mNumIterations && success; i++) {
+                    // The workload to use for this iteration.
+                    int workload = i + 1;
+                    watchDog.start();
+                    // Start benchmark.
+                    success = startBenchmark(workload, mNumFrames, times);
+                    watchDog.stop();
+                    if (!success) {
+                        setException(new Exception("Benchmark failed to run"));
+                    } else {
+                        // Calculate FPS.
+                        mFpsValues[i] = mNumFrames * 1000.0f / (times[1] - times[0]);
+                    }
                 }
             }
+            finally
+            {
+                tearDownBenchmark();
+            }
+
             complete();
             Log.i(TAG, mBenchmark + " Benchmark Completed");
         }