| /* |
| * Copyright 2013 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "SurfaceTextureGLThreadToGL_test" |
| //#define LOG_NDEBUG 0 |
| |
| #include "SurfaceTextureGLThreadToGL.h" |
| |
| namespace android { |
| |
| TEST_F(SurfaceTextureGLThreadToGLTest, |
| UpdateTexImageBeforeFrameFinishedCompletes) { |
| class PT : public ProducerThread { |
| virtual void render() { |
| glClearColor(0.0f, 1.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| swapBuffers(); |
| } |
| }; |
| |
| SetUpWindowAndContext(); |
| |
| runProducerThread(new PT()); |
| |
| mFC->waitForFrame(); |
| ASSERT_EQ(NO_ERROR, mST->updateTexImage()); |
| mFC->finishFrame(); |
| |
| // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! |
| } |
| |
| TEST_F(SurfaceTextureGLThreadToGLTest, |
| UpdateTexImageAfterFrameFinishedCompletes) { |
| class PT : public ProducerThread { |
| virtual void render() { |
| glClearColor(0.0f, 1.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| swapBuffers(); |
| } |
| }; |
| |
| SetUpWindowAndContext(); |
| |
| runProducerThread(new PT()); |
| |
| mFC->waitForFrame(); |
| mFC->finishFrame(); |
| ASSERT_EQ(NO_ERROR, mST->updateTexImage()); |
| |
| // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! |
| } |
| |
| TEST_F(SurfaceTextureGLThreadToGLTest, |
| RepeatedUpdateTexImageBeforeFrameFinishedCompletes) { |
| enum { NUM_ITERATIONS = 1024 }; |
| |
| 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); |
| ALOGV("+swapBuffers"); |
| swapBuffers(); |
| ALOGV("-swapBuffers"); |
| } |
| } |
| }; |
| |
| SetUpWindowAndContext(); |
| |
| runProducerThread(new PT()); |
| |
| for (int i = 0; i < NUM_ITERATIONS; i++) { |
| mFC->waitForFrame(); |
| ALOGV("+updateTexImage"); |
| ASSERT_EQ(NO_ERROR, mST->updateTexImage()); |
| ALOGV("-updateTexImage"); |
| mFC->finishFrame(); |
| |
| // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! |
| } |
| } |
| |
| TEST_F(SurfaceTextureGLThreadToGLTest, |
| RepeatedUpdateTexImageAfterFrameFinishedCompletes) { |
| enum { NUM_ITERATIONS = 1024 }; |
| |
| 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); |
| ALOGV("+swapBuffers"); |
| swapBuffers(); |
| ALOGV("-swapBuffers"); |
| } |
| } |
| }; |
| |
| SetUpWindowAndContext(); |
| |
| runProducerThread(new PT()); |
| |
| for (int i = 0; i < NUM_ITERATIONS; i++) { |
| mFC->waitForFrame(); |
| mFC->finishFrame(); |
| ALOGV("+updateTexImage"); |
| ASSERT_EQ(NO_ERROR, mST->updateTexImage()); |
| ALOGV("-updateTexImage"); |
| |
| // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! |
| } |
| } |
| |
| // XXX: This test is disabled because it is currently hanging on some devices. |
| TEST_F(SurfaceTextureGLThreadToGLTest, |
| 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); |
| ALOGV("+swapBuffers"); |
| swapBuffers(); |
| ALOGV("-swapBuffers"); |
| } |
| } |
| }; |
| |
| SetUpWindowAndContext(); |
| |
| 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 setDefaultMaxBufferCount. 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. |
| ASSERT_EQ(NO_ERROR, 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. |
| ASSERT_EQ(NO_ERROR, mST->updateTexImage()); |
| ASSERT_EQ(NO_ERROR, mST->updateTexImage()); |
| |
| // Consume the remaining buffers from the producer thread. |
| for (int i = 0; i < NUM_ITERATIONS-3; i++) { |
| mFC->waitForFrame(); |
| mFC->finishFrame(); |
| ALOGV("+updateTexImage"); |
| ASSERT_EQ(NO_ERROR, mST->updateTexImage()); |
| ALOGV("-updateTexImage"); |
| } |
| } |
| |
| } // namespace android |