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:
parent
1259e9d6ac
commit
6e50219aee
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user