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
22namespace android {
23
24TEST_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
45TEST_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
66TEST_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
97TEST_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.
129TEST_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