SurfaceTexture: add a deadlock scenario test

This change adds a test to ensure that a GL driver that's blocking on a
call to dequeueBuffer does not block other GL threads from rendering and
queueing buffers.

Change-Id: Ifdd234effc534b6a9cf8522ca87f64da5bb0bbd6
This commit is contained in:
Jamie Gennis 2011-07-21 14:31:31 -07:00
parent 1259e9d6ac
commit 6e50219aee

View File

@ -1205,7 +1205,7 @@ protected:
sp<FrameCondition> mFC;
};
TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedWorks) {
TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedCompletes) {
class PT : public ProducerThread {
virtual void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@ -1223,7 +1223,7 @@ TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedWorks) {
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedWorks) {
TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedCompletes) {
class PT : public ProducerThread {
virtual void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@ -1241,7 +1241,7 @@ TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedWorks) {
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedWorks) {
TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
enum { NUM_ITERATIONS = 1024 };
class PT : public ProducerThread {
@ -1269,7 +1269,7 @@ TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedWorks)
}
}
TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedWorks) {
TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
enum { NUM_ITERATIONS = 1024 };
class PT : public ProducerThread {
@ -1297,4 +1297,70 @@ TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedWorks)
}
}
// XXX: This test is disabled because it is currently hanging on some devices.
TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
enum { NUM_ITERATIONS = 64 };
class PT : public ProducerThread {
virtual void render() {
for (int i = 0; i < NUM_ITERATIONS; i++) {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
LOGV("+swapBuffers");
swapBuffers();
LOGV("-swapBuffers");
}
}
};
ASSERT_EQ(OK, mST->setSynchronousMode(true));
ASSERT_EQ(OK, mST->setBufferCountServer(2));
runProducerThread(new PT());
// Allow three frames to be rendered and queued before starting the
// rendering in this thread. For the latter two frames we don't call
// updateTexImage so the next dequeue from the producer thread will block
// waiting for a frame to become available.
mFC->waitForFrame();
mFC->finishFrame();
// We must call updateTexImage to consume the first frame so that the
// SurfaceTexture is able to reduce the buffer count to 2. This is because
// the GL driver may dequeue a buffer when the EGLSurface is created, and
// that happens before we call setBufferCountServer. It's possible that the
// driver does not dequeue a buffer at EGLSurface creation time, so we
// cannot rely on this to cause the second dequeueBuffer call to block.
mST->updateTexImage();
mFC->waitForFrame();
mFC->finishFrame();
mFC->waitForFrame();
mFC->finishFrame();
// Sleep for 100ms to allow the producer thread's dequeueBuffer call to
// block waiting for a buffer to become available.
usleep(100000);
// Render and present a number of images. This thread should not be blocked
// by the fact that the producer thread is blocking in dequeue.
for (int i = 0; i < NUM_ITERATIONS; i++) {
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(mEglDisplay, mEglSurface);
}
// Consume the two pending buffers to unblock the producer thread.
mST->updateTexImage();
mST->updateTexImage();
// Consume the remaining buffers from the producer thread.
for (int i = 0; i < NUM_ITERATIONS-3; i++) {
mFC->waitForFrame();
mFC->finishFrame();
LOGV("+updateTexImage");
mST->updateTexImage();
LOGV("-updateTexImage");
}
}
} // namespace android