am c2597295: am 53cf2020: Merge changes I37fd43b5,I91eb29db,I0491ce35 into ics-mr1

* commit 'c25972950c2ea62fb085524dbe737c2bf0f08f4a':
  SurfaceTexture: fix a couple tests
  EGL: default to swap interval 1
  SurfaceTexture: clean up some tests
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 27d863d..15c2bab 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -202,6 +202,10 @@
     // getCurrentScalingMode returns the scaling mode of the current buffer
     uint32_t getCurrentScalingMode() const;
 
+    // isSynchronousMode returns whether the SurfaceTexture is currently in
+    // synchronous mode.
+    bool isSynchronousMode() const;
+
     // abandon frees all the buffers and puts the SurfaceTexture into the
     // 'abandoned' state.  Once put in this state the SurfaceTexture can never
     // leave it.  When in the 'abandoned' state, all methods of the
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 175de69..29e86a3 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -1005,6 +1005,11 @@
     return mCurrentScalingMode;
 }
 
+bool SurfaceTexture::isSynchronousMode() const {
+    Mutex::Autolock lock(mMutex);
+    return mSynchronousMode;
+}
+
 int SurfaceTexture::query(int what, int* outValue)
 {
     Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 4268782..c79e69a 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -396,7 +396,8 @@
             1.0f, 1.0f,
         };
 
-        glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices);
+        glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
+                triangleVertices);
         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
         glEnableVertexAttribArray(mPositionHandle);
         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
@@ -410,13 +411,17 @@
         // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
         // they're setting the defautls for that target, but when hacking things
         // to use GL_TEXTURE_2D they are needed to achieve the same behavior.
-        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
+                GL_LINEAR);
         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
+                GL_LINEAR);
         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
+                GL_CLAMP_TO_EDGE);
         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
+                GL_CLAMP_TO_EDGE);
         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
 
         GLfloat texMatrix[16];
@@ -640,8 +645,8 @@
 
     for (int i = 0; i < 5; i++) {
         const android_native_rect_t& crop(crops[i]);
-        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", crop.left,
-                crop.top, crop.right, crop.bottom).string());
+        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
+                crop.left, crop.top, crop.right, crop.bottom).string());
 
         ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
 
@@ -650,13 +655,15 @@
         ASSERT_TRUE(anb != NULL);
 
         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-        ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+        ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
+                buf->getNativeBuffer()));
 
         uint8_t* img = NULL;
         buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
         fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
         buf->unlock();
-        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
+                buf->getNativeBuffer()));
 
         mST->updateTexImage();
 
@@ -708,7 +715,8 @@
 
     class ProducerThread : public Thread {
     public:
-        ProducerThread(const sp<ANativeWindow>& anw, const TestPixel* testPixels):
+        ProducerThread(const sp<ANativeWindow>& anw,
+                const TestPixel* testPixels):
                 mANW(anw),
                 mTestPixels(testPixels) {
         }
@@ -940,82 +948,6 @@
     EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
 }
 
-TEST_F(SurfaceTextureGLTest, TexturingFromGLFilledRGBABufferPow2) {
-    const int texWidth = 64;
-    const int texHeight = 64;
-
-    mST->setDefaultBufferSize(texWidth, texHeight);
-
-    // Do the producer side of things
-    EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
-            mANW.get(), NULL);
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    ASSERT_NE(EGL_NO_SURFACE, stcEglSurface);
-
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
-            mEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    glClearColor(0.6, 0.6, 0.6, 0.6);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glEnable(GL_SCISSOR_TEST);
-    glScissor(4, 4, 4, 4);
-    glClearColor(1.0, 0.0, 0.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glScissor(24, 48, 4, 4);
-    glClearColor(0.0, 1.0, 0.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glScissor(37, 17, 4, 4);
-    glClearColor(0.0, 0.0, 1.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    eglSwapBuffers(mEglDisplay, stcEglSurface);
-
-    // Do the consumer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    glDisable(GL_SCISSOR_TEST);
-
-    mST->updateTexImage();
-
-    // We must wait until updateTexImage has been called to destroy the
-    // EGLSurface because we're in synchronous mode.
-    eglDestroySurface(mEglDisplay, stcEglSurface);
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
-
-    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
-    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
-    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
-    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
-}
-
 TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
     class ProducerThread : public Thread {
     public:
@@ -1093,13 +1025,284 @@
             reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
 }
 
+TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
+    int texHeight = 16;
+    ANativeWindowBuffer* anb;
+
+    GLint maxTextureSize;
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+
+    // make sure it works with small textures
+    mST->setDefaultBufferSize(16, texHeight);
+    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    EXPECT_EQ(16, anb->width);
+    EXPECT_EQ(texHeight, anb->height);
+    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
+    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
+
+    // make sure it works with GL_MAX_TEXTURE_SIZE
+    mST->setDefaultBufferSize(maxTextureSize, texHeight);
+    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    EXPECT_EQ(maxTextureSize, anb->width);
+    EXPECT_EQ(texHeight, anb->height);
+    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
+    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
+
+    // make sure it fails with GL_MAX_TEXTURE_SIZE+1
+    mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
+    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    EXPECT_EQ(maxTextureSize+1, anb->width);
+    EXPECT_EQ(texHeight, anb->height);
+    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
+    ASSERT_NE(NO_ERROR, mST->updateTexImage());
+}
+
 /*
- * This test is for testing GL -> GL texture streaming via SurfaceTexture.  It
- * contains functionality to create a producer thread that will perform GL
- * rendering to an ANativeWindow that feeds frames to a SurfaceTexture.
- * Additionally it supports interlocking the producer and consumer threads so
- * that a specific sequence of calls can be deterministically created by the
- * test.
+ * This test fixture is for testing GL -> GL texture streaming.  It creates an
+ * EGLSurface and an EGLContext for the image producer to use.
+ */
+class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
+protected:
+    SurfaceTextureGLToGLTest():
+            mProducerEglSurface(EGL_NO_SURFACE),
+            mProducerEglContext(EGL_NO_CONTEXT) {
+    }
+
+    virtual void SetUp() {
+        SurfaceTextureGLTest::SetUp();
+
+        EGLConfig myConfig = {0};
+        EGLint numConfigs = 0;
+        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
+                1, &numConfigs));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
+                mANW.get(), NULL);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
+
+        mProducerEglContext = eglCreateContext(mEglDisplay, myConfig,
+                EGL_NO_CONTEXT, getContextAttribs());
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
+    }
+
+    virtual void TearDown() {
+        if (mProducerEglContext != EGL_NO_CONTEXT) {
+            eglDestroyContext(mEglDisplay, mProducerEglContext);
+        }
+        if (mProducerEglSurface != EGL_NO_SURFACE) {
+            eglDestroySurface(mEglDisplay, mProducerEglSurface);
+        }
+        SurfaceTextureGLTest::TearDown();
+    }
+
+    EGLSurface mProducerEglSurface;
+    EGLContext mProducerEglContext;
+};
+
+TEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
+    const int texWidth = 64;
+    const int texHeight = 64;
+
+    mST->setDefaultBufferSize(texWidth, texHeight);
+
+    // Do the producer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // This is needed to ensure we pick up a buffer of the correct size.
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    glClearColor(0.6, 0.6, 0.6, 0.6);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(4, 4, 4, 4);
+    glClearColor(1.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScissor(24, 48, 4, 4);
+    glClearColor(0.0, 1.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScissor(37, 17, 4, 4);
+    glClearColor(0.0, 0.0, 1.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    // Do the consumer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    glDisable(GL_SCISSOR_TEST);
+
+    mST->updateTexImage(); // Skip the first frame, which was empty
+    mST->updateTexImage();
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
+
+    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
+    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
+    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
+    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
+    sp<GraphicBuffer> buffers[3];
+
+    // This test requires async mode to run on a single thread.
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    for (int i = 0; i < 3; i++) {
+        // Produce a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+                mProducerEglSurface, mProducerEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        glClear(GL_COLOR_BUFFER_BIT);
+        eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+        // Consume a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        mST->updateTexImage();
+        buffers[i] = mST->getCurrentBuffer();
+    }
+
+    // Destroy the GL texture object to release its ref on buffers[2].
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // Destroy the EGLSurface
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Release the ref that the SurfaceTexture has on buffers[2].
+    mST->abandon();
+
+    EXPECT_EQ(1, buffers[0]->getStrongCount());
+    EXPECT_EQ(1, buffers[1]->getStrongCount());
+
+    // Depending on how lazily the GL driver dequeues buffers, we may end up
+    // with either two or three total buffers.  If there are three, make sure
+    // the last one was properly down-ref'd.
+    if (buffers[2] != buffers[0]) {
+        EXPECT_EQ(1, buffers[2]->getStrongCount());
+    }
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
+    sp<GraphicBuffer> buffers[3];
+
+    // This test requires async mode to run on a single thread.
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    for (int i = 0; i < 3; i++) {
+        // Produce a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+                mProducerEglSurface, mProducerEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        glClear(GL_COLOR_BUFFER_BIT);
+        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        // Consume a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+        buffers[i] = mST->getCurrentBuffer();
+    }
+
+    // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has
+    // on buffers[2].
+    mST->abandon();
+
+    // Destroy the GL texture object to release its ref on buffers[2].
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // Destroy the EGLSurface.
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    EXPECT_EQ(1, buffers[0]->getStrongCount());
+    EXPECT_EQ(1, buffers[1]->getStrongCount());
+
+    // Depending on how lazily the GL driver dequeues buffers, we may end up
+    // with either two or three total buffers.  If there are three, make sure
+    // the last one was properly down-ref'd.
+    if (buffers[2] != buffers[0]) {
+        EXPECT_EQ(1, buffers[2]->getStrongCount());
+    }
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) {
+    // This test requires 3 buffers to run on a single thread.
+    mST->setBufferCountServer(3);
+
+    ASSERT_TRUE(mST->isSynchronousMode());
+
+    for (int i = 0; i < 10; i++) {
+        // Produce a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+                mProducerEglSurface, mProducerEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        glClear(GL_COLOR_BUFFER_BIT);
+        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        // Consume a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    }
+
+    ASSERT_TRUE(mST->isSynchronousMode());
+}
+
+/*
+ * This test fixture is for testing GL -> GL texture streaming from one thread
+ * to another.  It contains functionality to create a producer thread that will
+ * perform GL rendering to an ANativeWindow that feeds frames to a
+ * SurfaceTexture.  Additionally it supports interlocking the producer and
+ * consumer threads so that a specific sequence of calls can be
+ * deterministically created by the test.
  *
  * The intended usage is as follows:
  *
@@ -1122,7 +1325,7 @@
  * }
  *
  */
-class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
+class SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
 protected:
 
     // ProducerThread is an abstract base class to simplify the creation of
@@ -1223,30 +1426,8 @@
         Condition mFrameFinishCondition;
     };
 
-    SurfaceTextureGLToGLTest():
-            mProducerEglSurface(EGL_NO_SURFACE),
-            mProducerEglContext(EGL_NO_CONTEXT) {
-    }
-
     virtual void SetUp() {
-        SurfaceTextureGLTest::SetUp();
-
-        EGLConfig myConfig = {0};
-        EGLint numConfigs = 0;
-        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
-                1, &numConfigs));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
-                mANW.get(), NULL);
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
-
-        mProducerEglContext = eglCreateContext(mEglDisplay, myConfig,
-                EGL_NO_CONTEXT, getContextAttribs());
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
-
+        SurfaceTextureGLToGLTest::SetUp();
         mFC = new FrameCondition();
         mST->setFrameAvailableListener(mFC);
     }
@@ -1255,15 +1436,9 @@
         if (mProducerThread != NULL) {
             mProducerThread->requestExitAndWait();
         }
-        if (mProducerEglContext != EGL_NO_CONTEXT) {
-            eglDestroyContext(mEglDisplay, mProducerEglContext);
-        }
-        if (mProducerEglSurface != EGL_NO_SURFACE) {
-            eglDestroySurface(mEglDisplay, mProducerEglSurface);
-        }
         mProducerThread.clear();
         mFC.clear();
-        SurfaceTextureGLTest::TearDown();
+        SurfaceTextureGLToGLTest::TearDown();
     }
 
     void runProducerThread(const sp<ProducerThread> producerThread) {
@@ -1274,13 +1449,12 @@
         producerThread->run();
     }
 
-    EGLSurface mProducerEglSurface;
-    EGLContext mProducerEglContext;
     sp<ProducerThread> mProducerThread;
     sp<FrameCondition> mFC;
 };
 
-TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        UpdateTexImageBeforeFrameFinishedCompletes) {
     class PT : public ProducerThread {
         virtual void render() {
             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1298,7 +1472,8 @@
     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
 }
 
-TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        UpdateTexImageAfterFrameFinishedCompletes) {
     class PT : public ProducerThread {
         virtual void render() {
             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1316,7 +1491,8 @@
     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
 }
 
-TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
     enum { NUM_ITERATIONS = 1024 };
 
     class PT : public ProducerThread {
@@ -1344,7 +1520,8 @@
     }
 }
 
-TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
     enum { NUM_ITERATIONS = 1024 };
 
     class PT : public ProducerThread {
@@ -1373,7 +1550,8 @@
 }
 
 // XXX: This test is disabled because it is currently hanging on some devices.
-TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
     enum { NUM_ITERATIONS = 64 };
 
     class PT : public ProducerThread {
@@ -1438,118 +1616,4 @@
     }
 }
 
-TEST_F(SurfaceTextureGLTest, EglDestroySurfaceUnrefsBuffers) {
-    EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
-            mANW.get(), NULL);
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    ASSERT_NE(EGL_NO_SURFACE, stcEglSurface);
-
-    sp<GraphicBuffer> buffers[3];
-
-    for (int i = 0; i < 3; i++) {
-        // Produce a frame
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
-                mEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        glClear(GL_COLOR_BUFFER_BIT);
-        eglSwapBuffers(mEglDisplay, stcEglSurface);
-
-        // Consume a frame
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        mST->updateTexImage();
-        buffers[i] = mST->getCurrentBuffer();
-    }
-
-    // Destroy the GL texture object to release its ref on buffers[2].
-    GLuint texID = TEX_ID;
-    glDeleteTextures(1, &texID);
-
-    // Destroy the EGLSurface
-    EXPECT_TRUE(eglDestroySurface(mEglDisplay, stcEglSurface));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // Release the ref that the SurfaceTexture has on buffers[2].
-    mST->abandon();
-
-    EXPECT_EQ(1, buffers[0]->getStrongCount());
-    EXPECT_EQ(1, buffers[1]->getStrongCount());
-    EXPECT_EQ(1, buffers[2]->getStrongCount());
-}
-
-TEST_F(SurfaceTextureGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
-    EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
-            mANW.get(), NULL);
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    ASSERT_NE(EGL_NO_SURFACE, stcEglSurface);
-
-    sp<GraphicBuffer> buffers[3];
-
-    for (int i = 0; i < 3; i++) {
-        // Produce a frame
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
-                mEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        glClear(GL_COLOR_BUFFER_BIT);
-        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, stcEglSurface));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        // Consume a frame
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-        buffers[i] = mST->getCurrentBuffer();
-    }
-
-    // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has
-    // on buffers[2].
-    mST->abandon();
-
-    // Destroy the GL texture object to release its ref on buffers[2].
-    GLuint texID = TEX_ID;
-    glDeleteTextures(1, &texID);
-
-    // Destroy the EGLSurface.
-    EXPECT_TRUE(eglDestroySurface(mEglDisplay, stcEglSurface));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    EXPECT_EQ(1, buffers[0]->getStrongCount());
-    EXPECT_EQ(1, buffers[1]->getStrongCount());
-    EXPECT_EQ(1, buffers[2]->getStrongCount());
-}
-
-TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
-    int texHeight = 16;
-    ANativeWindowBuffer* anb;
-
-    GLint maxTextureSize;
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
-
-    // make sure it works with small textures
-    mST->setDefaultBufferSize(16, texHeight);
-    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
-    EXPECT_EQ(16, anb->width);
-    EXPECT_EQ(texHeight, anb->height);
-    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
-    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
-
-    // make sure it works with GL_MAX_TEXTURE_SIZE
-    mST->setDefaultBufferSize(maxTextureSize, texHeight);
-    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
-    EXPECT_EQ(maxTextureSize, anb->width);
-    EXPECT_EQ(texHeight, anb->height);
-    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
-    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
-
-    // make sure it fails with GL_MAX_TEXTURE_SIZE+1
-    mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
-    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
-    EXPECT_EQ(maxTextureSize+1, anb->width);
-    EXPECT_EQ(texHeight, anb->height);
-    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
-    ASSERT_NE(NO_ERROR, mST->updateTexImage());
-}
-
 } // namespace android
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 2237eb6..a63d5b0 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -370,6 +370,11 @@
             }
         }
 
+        // the EGL spec requires that a new EGLSurface default to swap interval
+        // 1, so explicitly set that on the window here.
+        ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
+        anw->setSwapInterval(anw, 1);
+
         EGLSurface surface = cnx->egl.eglCreateWindowSurface(
                 iDpy, iConfig, window, attrib_list);
         if (surface != EGL_NO_SURFACE) {