1 /*
2  * Copyright 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "SurfaceTextureGLThreadToGL_test"
18 //#define LOG_NDEBUG 0
19 
20 #include "SurfaceTextureGLThreadToGL.h"
21 
22 namespace android {
23 
TEST_F(SurfaceTextureGLThreadToGLTest,UpdateTexImageBeforeFrameFinishedCompletes)24 TEST_F(SurfaceTextureGLThreadToGLTest,
25         UpdateTexImageBeforeFrameFinishedCompletes) {
26     class PT : public ProducerThread {
27         virtual void render() {
28             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
29             glClear(GL_COLOR_BUFFER_BIT);
30             swapBuffers();
31         }
32     };
33 
34     runProducerThread(new PT());
35 
36     mFC->waitForFrame();
37     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
38     mFC->finishFrame();
39 
40     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
41 }
42 
TEST_F(SurfaceTextureGLThreadToGLTest,UpdateTexImageAfterFrameFinishedCompletes)43 TEST_F(SurfaceTextureGLThreadToGLTest,
44         UpdateTexImageAfterFrameFinishedCompletes) {
45     class PT : public ProducerThread {
46         virtual void render() {
47             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
48             glClear(GL_COLOR_BUFFER_BIT);
49             swapBuffers();
50         }
51     };
52 
53     runProducerThread(new PT());
54 
55     mFC->waitForFrame();
56     mFC->finishFrame();
57     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
58 
59     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
60 }
61 
TEST_F(SurfaceTextureGLThreadToGLTest,RepeatedUpdateTexImageBeforeFrameFinishedCompletes)62 TEST_F(SurfaceTextureGLThreadToGLTest,
63         RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
64     enum { NUM_ITERATIONS = 1024 };
65 
66     class PT : public ProducerThread {
67         virtual void render() {
68             for (int i = 0; i < NUM_ITERATIONS; i++) {
69                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
70                 glClear(GL_COLOR_BUFFER_BIT);
71                 ALOGV("+swapBuffers");
72                 swapBuffers();
73                 ALOGV("-swapBuffers");
74             }
75         }
76     };
77 
78     runProducerThread(new PT());
79 
80     for (int i = 0; i < NUM_ITERATIONS; i++) {
81         mFC->waitForFrame();
82         ALOGV("+updateTexImage");
83         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
84         ALOGV("-updateTexImage");
85         mFC->finishFrame();
86 
87         // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
88     }
89 }
90 
TEST_F(SurfaceTextureGLThreadToGLTest,RepeatedUpdateTexImageAfterFrameFinishedCompletes)91 TEST_F(SurfaceTextureGLThreadToGLTest,
92         RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
93     enum { NUM_ITERATIONS = 1024 };
94 
95     class PT : public ProducerThread {
96         virtual void render() {
97             for (int i = 0; i < NUM_ITERATIONS; i++) {
98                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
99                 glClear(GL_COLOR_BUFFER_BIT);
100                 ALOGV("+swapBuffers");
101                 swapBuffers();
102                 ALOGV("-swapBuffers");
103             }
104         }
105     };
106 
107     runProducerThread(new PT());
108 
109     for (int i = 0; i < NUM_ITERATIONS; i++) {
110         mFC->waitForFrame();
111         mFC->finishFrame();
112         ALOGV("+updateTexImage");
113         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
114         ALOGV("-updateTexImage");
115 
116         // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
117     }
118 }
119 
120 // XXX: This test is disabled because it is currently hanging on some devices.
TEST_F(SurfaceTextureGLThreadToGLTest,DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes)121 TEST_F(SurfaceTextureGLThreadToGLTest,
122         DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
123     enum { NUM_ITERATIONS = 64 };
124 
125     class PT : public ProducerThread {
126         virtual void render() {
127             for (int i = 0; i < NUM_ITERATIONS; i++) {
128                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
129                 glClear(GL_COLOR_BUFFER_BIT);
130                 ALOGV("+swapBuffers");
131                 swapBuffers();
132                 ALOGV("-swapBuffers");
133             }
134         }
135     };
136 
137     ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
138 
139     runProducerThread(new PT());
140 
141     // Allow three frames to be rendered and queued before starting the
142     // rendering in this thread.  For the latter two frames we don't call
143     // updateTexImage so the next dequeue from the producer thread will block
144     // waiting for a frame to become available.
145     mFC->waitForFrame();
146     mFC->finishFrame();
147 
148     // We must call updateTexImage to consume the first frame so that the
149     // SurfaceTexture is able to reduce the buffer count to 2.  This is because
150     // the GL driver may dequeue a buffer when the EGLSurface is created, and
151     // that happens before we call setDefaultMaxBufferCount.  It's possible that the
152     // driver does not dequeue a buffer at EGLSurface creation time, so we
153     // cannot rely on this to cause the second dequeueBuffer call to block.
154     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
155 
156     mFC->waitForFrame();
157     mFC->finishFrame();
158     mFC->waitForFrame();
159     mFC->finishFrame();
160 
161     // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
162     // block waiting for a buffer to become available.
163     usleep(100000);
164 
165     // Render and present a number of images.  This thread should not be blocked
166     // by the fact that the producer thread is blocking in dequeue.
167     for (int i = 0; i < NUM_ITERATIONS; i++) {
168         glClear(GL_COLOR_BUFFER_BIT);
169         eglSwapBuffers(mEglDisplay, mEglSurface);
170     }
171 
172     // Consume the two pending buffers to unblock the producer thread.
173     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
174     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
175 
176     // Consume the remaining buffers from the producer thread.
177     for (int i = 0; i < NUM_ITERATIONS-3; i++) {
178         mFC->waitForFrame();
179         mFC->finishFrame();
180         ALOGV("+updateTexImage");
181         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
182         ALOGV("-updateTexImage");
183     }
184 }
185 
186 } // namespace android
187