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     SetUpWindowAndContext();
35 
36     runProducerThread(new PT());
37 
38     mFC->waitForFrame();
39     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
40     mFC->finishFrame();
41 
42     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
43 }
44 
TEST_F(SurfaceTextureGLThreadToGLTest,UpdateTexImageAfterFrameFinishedCompletes)45 TEST_F(SurfaceTextureGLThreadToGLTest,
46         UpdateTexImageAfterFrameFinishedCompletes) {
47     class PT : public ProducerThread {
48         virtual void render() {
49             glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
50             glClear(GL_COLOR_BUFFER_BIT);
51             swapBuffers();
52         }
53     };
54 
55     SetUpWindowAndContext();
56 
57     runProducerThread(new PT());
58 
59     mFC->waitForFrame();
60     mFC->finishFrame();
61     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
62 
63     // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
64 }
65 
TEST_F(SurfaceTextureGLThreadToGLTest,RepeatedUpdateTexImageBeforeFrameFinishedCompletes)66 TEST_F(SurfaceTextureGLThreadToGLTest,
67         RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
68     enum { NUM_ITERATIONS = 1024 };
69 
70     class PT : public ProducerThread {
71         virtual void render() {
72             for (int i = 0; i < NUM_ITERATIONS; i++) {
73                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
74                 glClear(GL_COLOR_BUFFER_BIT);
75                 ALOGV("+swapBuffers");
76                 swapBuffers();
77                 ALOGV("-swapBuffers");
78             }
79         }
80     };
81 
82     SetUpWindowAndContext();
83 
84     runProducerThread(new PT());
85 
86     for (int i = 0; i < NUM_ITERATIONS; i++) {
87         mFC->waitForFrame();
88         ALOGV("+updateTexImage");
89         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
90         ALOGV("-updateTexImage");
91         mFC->finishFrame();
92 
93         // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
94     }
95 }
96 
TEST_F(SurfaceTextureGLThreadToGLTest,RepeatedUpdateTexImageAfterFrameFinishedCompletes)97 TEST_F(SurfaceTextureGLThreadToGLTest,
98         RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
99     enum { NUM_ITERATIONS = 1024 };
100 
101     class PT : public ProducerThread {
102         virtual void render() {
103             for (int i = 0; i < NUM_ITERATIONS; i++) {
104                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
105                 glClear(GL_COLOR_BUFFER_BIT);
106                 ALOGV("+swapBuffers");
107                 swapBuffers();
108                 ALOGV("-swapBuffers");
109             }
110         }
111     };
112 
113     SetUpWindowAndContext();
114 
115     runProducerThread(new PT());
116 
117     for (int i = 0; i < NUM_ITERATIONS; i++) {
118         mFC->waitForFrame();
119         mFC->finishFrame();
120         ALOGV("+updateTexImage");
121         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
122         ALOGV("-updateTexImage");
123 
124         // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
125     }
126 }
127 
128 // XXX: This test is disabled because it is currently hanging on some devices.
TEST_F(SurfaceTextureGLThreadToGLTest,DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes)129 TEST_F(SurfaceTextureGLThreadToGLTest,
130         DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
131     enum { NUM_ITERATIONS = 64 };
132 
133     class PT : public ProducerThread {
134         virtual void render() {
135             for (int i = 0; i < NUM_ITERATIONS; i++) {
136                 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
137                 glClear(GL_COLOR_BUFFER_BIT);
138                 ALOGV("+swapBuffers");
139                 swapBuffers();
140                 ALOGV("-swapBuffers");
141             }
142         }
143     };
144 
145     SetUpWindowAndContext();
146 
147     runProducerThread(new PT());
148 
149     // Allow three frames to be rendered and queued before starting the
150     // rendering in this thread.  For the latter two frames we don't call
151     // updateTexImage so the next dequeue from the producer thread will block
152     // waiting for a frame to become available.
153     mFC->waitForFrame();
154     mFC->finishFrame();
155 
156     // We must call updateTexImage to consume the first frame so that the
157     // SurfaceTexture is able to reduce the buffer count to 2.  This is because
158     // the GL driver may dequeue a buffer when the EGLSurface is created, and
159     // that happens before we call setDefaultMaxBufferCount.  It's possible that the
160     // driver does not dequeue a buffer at EGLSurface creation time, so we
161     // cannot rely on this to cause the second dequeueBuffer call to block.
162     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
163 
164     mFC->waitForFrame();
165     mFC->finishFrame();
166     mFC->waitForFrame();
167     mFC->finishFrame();
168 
169     // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
170     // block waiting for a buffer to become available.
171     usleep(100000);
172 
173     // Render and present a number of images.  This thread should not be blocked
174     // by the fact that the producer thread is blocking in dequeue.
175     for (int i = 0; i < NUM_ITERATIONS; i++) {
176         glClear(GL_COLOR_BUFFER_BIT);
177         eglSwapBuffers(mEglDisplay, mEglSurface);
178     }
179 
180     // Consume the two pending buffers to unblock the producer thread.
181     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
182     ASSERT_EQ(NO_ERROR, mST->updateTexImage());
183 
184     // Consume the remaining buffers from the producer thread.
185     for (int i = 0; i < NUM_ITERATIONS-3; i++) {
186         mFC->waitForFrame();
187         mFC->finishFrame();
188         ALOGV("+updateTexImage");
189         ASSERT_EQ(NO_ERROR, mST->updateTexImage());
190         ALOGV("-updateTexImage");
191     }
192 }
193 
194 } // namespace android
195