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