diff options
| author | 2011-10-19 15:19:19 -0700 | |
|---|---|---|
| committer | 2011-10-19 15:19:19 -0700 | |
| commit | 79e3125d56cca5aba88097b5ccd4f1e128bc8141 (patch) | |
| tree | bc2f01e8b3500ed5d73884714788dbe700664b6f | |
| parent | 1ecfabbe5a31e607bf9e3396627aafd2096c297a (diff) | |
SurfaceTexture: add tests for buffer leaks
This change adds two tests to ensure that eglDestroySurface does not
cause Gralloc buffers to be leaked.
Bug: 5472838
Change-Id: Id675d74e34b6479f2d68314d40de94aede69f142
| -rw-r--r-- | libs/gui/tests/SurfaceTexture_test.cpp | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp index b8bc454782..5daafd5581 100644 --- a/libs/gui/tests/SurfaceTexture_test.cpp +++ b/libs/gui/tests/SurfaceTexture_test.cpp @@ -334,7 +334,7 @@ protected: class SurfaceTextureGLTest : public GLTest { protected: - static const GLint TEX_ID = 123; + enum { TEX_ID = 123 }; virtual void SetUp() { GLTest::SetUp(); @@ -1438,4 +1438,86 @@ TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedSwapBuffersWhileDequeueStalled } } +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()); +} + } // namespace android |