SurfaceTextureClient_test.cpp revision 7a5b22c4e33928f81c2e8a3d85050c35bd44b1e0
1/*
2 * Copyright (C) 2011 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#include <EGL/egl.h>
18#include <gtest/gtest.h>
19#include <gui/SurfaceTextureClient.h>
20#include <utils/threads.h>
21
22namespace android {
23
24class SurfaceTextureClientTest : public ::testing::Test {
25protected:
26    SurfaceTextureClientTest():
27            mEglDisplay(EGL_NO_DISPLAY),
28            mEglSurface(EGL_NO_SURFACE),
29            mEglContext(EGL_NO_CONTEXT) {
30    }
31
32    virtual void SetUp() {
33        mST = new SurfaceTexture(123);
34        mSTC = new SurfaceTextureClient(mST);
35
36        // We need a valid GL context so we can test updateTexImage()
37        // This initializes EGL and create a dummy GL context with a
38        // pbuffer render target.
39        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
40        ASSERT_EQ(EGL_SUCCESS, eglGetError());
41        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
42
43        EGLint majorVersion, minorVersion;
44        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
45        ASSERT_EQ(EGL_SUCCESS, eglGetError());
46
47        EGLConfig myConfig;
48        EGLint numConfigs = 0;
49        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(),
50                &myConfig, 1, &numConfigs));
51        ASSERT_EQ(EGL_SUCCESS, eglGetError());
52
53        EGLint pbufferAttribs[] = {
54            EGL_WIDTH, 16,
55            EGL_HEIGHT, 16,
56            EGL_NONE };
57        mEglSurface = eglCreatePbufferSurface(mEglDisplay, myConfig, pbufferAttribs);
58        ASSERT_EQ(EGL_SUCCESS, eglGetError());
59        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
60
61        mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT, 0);
62        ASSERT_EQ(EGL_SUCCESS, eglGetError());
63        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
64
65        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
66        ASSERT_EQ(EGL_SUCCESS, eglGetError());
67    }
68
69    virtual void TearDown() {
70        mST.clear();
71        mSTC.clear();
72        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
73        eglDestroyContext(mEglDisplay, mEglContext);
74        eglDestroySurface(mEglDisplay, mEglSurface);
75        eglTerminate(mEglDisplay);
76    }
77
78    virtual EGLint const* getConfigAttribs() {
79        static EGLint sDefaultConfigAttribs[] = {
80            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
81            EGL_NONE
82        };
83
84        return sDefaultConfigAttribs;
85    }
86
87    sp<SurfaceTexture> mST;
88    sp<SurfaceTextureClient> mSTC;
89    EGLDisplay mEglDisplay;
90    EGLSurface mEglSurface;
91    EGLContext mEglContext;
92};
93
94TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
95    sp<ISurfaceTexture> ist(mSTC->getISurfaceTexture());
96    ASSERT_TRUE(ist != NULL);
97}
98
99TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) {
100    sp<ANativeWindow> anw(mSTC);
101    int result = -123;
102    int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
103            &result);
104    EXPECT_EQ(NO_ERROR, err);
105    EXPECT_EQ(0, result);
106}
107
108TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
109    sp<ANativeWindow> anw(mSTC);
110    int result = -123;
111    int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
112    EXPECT_EQ(NO_ERROR, err);
113    EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
114}
115
116TEST_F(SurfaceTextureClientTest, ANativeWindowLockFails) {
117    sp<ANativeWindow> anw(mSTC);
118    ANativeWindow_Buffer buf;
119    ASSERT_EQ(BAD_VALUE, ANativeWindow_lock(anw.get(), &buf, NULL));
120}
121
122TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) {
123    sp<ANativeWindow> anw(mSTC);
124
125    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
126    ASSERT_EQ(EGL_SUCCESS, eglGetError());
127    ASSERT_NE(EGL_NO_DISPLAY, dpy);
128
129    EGLint majorVersion;
130    EGLint minorVersion;
131    EXPECT_TRUE(eglInitialize(dpy, &majorVersion, &minorVersion));
132    ASSERT_EQ(EGL_SUCCESS, eglGetError());
133
134    EGLConfig myConfig = {0};
135    EGLint numConfigs = 0;
136    EGLint configAttribs[] = {
137        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
138        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
139        EGL_RED_SIZE, 8,
140        EGL_GREEN_SIZE, 8,
141        EGL_BLUE_SIZE, 8,
142        EGL_ALPHA_SIZE, 8,
143        EGL_DEPTH_SIZE, 16,
144        EGL_STENCIL_SIZE, 8,
145        EGL_NONE };
146    EXPECT_TRUE(eglChooseConfig(dpy, configAttribs, &myConfig, 1,
147            &numConfigs));
148    ASSERT_EQ(EGL_SUCCESS, eglGetError());
149
150    EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, anw.get(),
151            NULL);
152    EXPECT_NE(EGL_NO_SURFACE, eglSurface);
153    EXPECT_EQ(EGL_SUCCESS, eglGetError());
154
155    eglTerminate(dpy);
156}
157
158TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) {
159    sp<ANativeWindow> anw(mSTC);
160
161    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(), -1,  0,  0));
162    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(),  0, -1,  0));
163    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(),  0,  0, -1));
164    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(), -1, -1,  0));
165    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(),  0,  8,  0));
166    EXPECT_GT(OK, native_window_set_buffers_geometry(anw.get(),  8,  0,  0));
167}
168
169TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
170    sp<ANativeWindow> anw(mSTC);
171    ANativeWindowBuffer* buf;
172    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
173    EXPECT_EQ(1, buf->width);
174    EXPECT_EQ(1, buf->height);
175    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
176    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
177}
178
179TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
180    sp<ANativeWindow> anw(mSTC);
181    ANativeWindowBuffer* buf;
182    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, PIXEL_FORMAT_RGB_565));
183    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
184    EXPECT_EQ(16, buf->width);
185    EXPECT_EQ(8, buf->height);
186    EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
187    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
188}
189
190TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
191    sp<ANativeWindow> anw(mSTC);
192    ANativeWindowBuffer* buf;
193    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, PIXEL_FORMAT_RGB_565));
194    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
195    EXPECT_EQ(1, buf->width);
196    EXPECT_EQ(1, buf->height);
197    EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
198    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
199}
200
201TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
202    sp<ANativeWindow> anw(mSTC);
203    ANativeWindowBuffer* buf;
204    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, 0));
205    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
206    EXPECT_EQ(16, buf->width);
207    EXPECT_EQ(8, buf->height);
208    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
209    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
210}
211
212TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
213    sp<ANativeWindow> anw(mSTC);
214    ANativeWindowBuffer* buf;
215    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, 0));
216    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
217    EXPECT_EQ(16, buf->width);
218    EXPECT_EQ(8, buf->height);
219    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
220    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
221    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, 0));
222    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
223    EXPECT_EQ(1, buf->width);
224    EXPECT_EQ(1, buf->height);
225    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
226    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
227}
228
229TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
230    sp<ANativeWindow> anw(mSTC);
231    ANativeWindowBuffer* buf;
232    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, PIXEL_FORMAT_RGB_565));
233    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
234    EXPECT_EQ(1, buf->width);
235    EXPECT_EQ(1, buf->height);
236    EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
237    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
238    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, 0));
239    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
240    EXPECT_EQ(16, buf->width);
241    EXPECT_EQ(8, buf->height);
242    EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
243    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
244}
245
246TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSize) {
247    sp<ANativeWindow> anw(mSTC);
248    sp<SurfaceTexture> st(mST);
249    ANativeWindowBuffer* buf;
250    EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
251    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
252    EXPECT_EQ(16, buf->width);
253    EXPECT_EQ(8, buf->height);
254    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
255    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf));
256}
257
258TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeAfterDequeue) {
259    sp<ANativeWindow> anw(mSTC);
260    sp<SurfaceTexture> st(mST);
261    ANativeWindowBuffer* buf[2];
262    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
263    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
264    EXPECT_NE(buf[0], buf[1]);
265    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
266    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
267    EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
268    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
269    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
270    EXPECT_NE(buf[0], buf[1]);
271    EXPECT_EQ(16, buf[0]->width);
272    EXPECT_EQ(16, buf[1]->width);
273    EXPECT_EQ(8, buf[0]->height);
274    EXPECT_EQ(8, buf[1]->height);
275    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
276    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
277}
278
279TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
280    sp<ANativeWindow> anw(mSTC);
281    sp<SurfaceTexture> st(mST);
282    ANativeWindowBuffer* buf[2];
283    EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
284    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
285    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
286    EXPECT_NE(buf[0], buf[1]);
287    EXPECT_EQ(16, buf[0]->width);
288    EXPECT_EQ(16, buf[1]->width);
289    EXPECT_EQ(8, buf[0]->height);
290    EXPECT_EQ(8, buf[1]->height);
291    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
292    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
293    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 12, 24, 0));
294    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
295    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
296    EXPECT_NE(buf[0], buf[1]);
297    EXPECT_EQ(12, buf[0]->width);
298    EXPECT_EQ(12, buf[1]->width);
299    EXPECT_EQ(24, buf[0]->height);
300    EXPECT_EQ(24, buf[1]->height);
301    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
302    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
303}
304
305TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
306    sp<ANativeWindow> anw(mSTC);
307    sp<SurfaceTexture> st(mST);
308    android_native_buffer_t* buf[3];
309    ASSERT_EQ(OK, st->setSynchronousMode(false));
310    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
311
312    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
313    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
314    EXPECT_EQ(OK, st->updateTexImage());
315    EXPECT_EQ(OK, st->updateTexImage());
316
317    ASSERT_EQ(OK, st->setSynchronousMode(true));
318    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 2));
319
320    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
321    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
322    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
323    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
324
325    EXPECT_EQ(OK, st->updateTexImage());
326    EXPECT_EQ(OK, st->updateTexImage());
327    EXPECT_EQ(OK, st->updateTexImage());
328}
329
330TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
331    sp<ANativeWindow> anw(mSTC);
332    sp<SurfaceTexture> st(mST);
333    android_native_buffer_t* buf[3];
334    ASSERT_EQ(OK, st->setSynchronousMode(true));
335    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
336    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
337    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
338    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
339    EXPECT_NE(buf[0], buf[1]);
340    EXPECT_NE(buf[1], buf[2]);
341    EXPECT_NE(buf[2], buf[0]);
342    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
343    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
344    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
345    EXPECT_EQ(OK, st->updateTexImage());
346    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
347    EXPECT_EQ(OK, st->updateTexImage());
348    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
349    EXPECT_EQ(OK, st->updateTexImage());
350    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
351}
352
353TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
354    sp<ANativeWindow> anw(mSTC);
355    sp<SurfaceTexture> st(mST);
356    android_native_buffer_t* buf[3];
357    ASSERT_EQ(OK, st->setSynchronousMode(true));
358    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
359    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
360    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
361    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
362    EXPECT_NE(buf[0], buf[1]);
363    EXPECT_NE(buf[1], buf[2]);
364    EXPECT_NE(buf[2], buf[0]);
365    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
366    EXPECT_EQ(OK, st->updateTexImage());
367    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
368    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
369    EXPECT_EQ(OK, st->updateTexImage());
370    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
371    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
372    EXPECT_EQ(OK, st->updateTexImage());
373    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
374}
375
376TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
377    sp<ANativeWindow> anw(mSTC);
378    sp<SurfaceTexture> st(mST);
379    android_native_buffer_t* buf[3];
380    ASSERT_EQ(OK, st->setSynchronousMode(true));
381    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
382
383    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
384    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
385    EXPECT_EQ(OK, st->updateTexImage());
386    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
387
388    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
389    EXPECT_NE(buf[0], buf[1]);
390    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
391    EXPECT_EQ(OK, st->updateTexImage());
392    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
393
394    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
395    EXPECT_NE(buf[1], buf[2]);
396    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
397    EXPECT_EQ(OK, st->updateTexImage());
398    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
399}
400
401TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDequeueCurrent) {
402    sp<ANativeWindow> anw(mSTC);
403    sp<SurfaceTexture> st(mST);
404    android_native_buffer_t* buf[3];
405    android_native_buffer_t* firstBuf;
406    ASSERT_EQ(OK, st->setSynchronousMode(true));
407    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
408    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &firstBuf));
409    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), firstBuf));
410    EXPECT_EQ(OK, st->updateTexImage());
411    EXPECT_EQ(st->getCurrentBuffer().get(), firstBuf);
412    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
413    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
414    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
415    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
416    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
417    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
418    EXPECT_NE(buf[0], buf[1]);
419    EXPECT_NE(buf[1], buf[2]);
420    EXPECT_NE(buf[2], buf[0]);
421    EXPECT_EQ(firstBuf, buf[2]);
422}
423
424TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeTwoBuffers) {
425    sp<ANativeWindow> anw(mSTC);
426    sp<SurfaceTexture> st(mST);
427    ASSERT_EQ(OK, st->setSynchronousMode(true));
428    EXPECT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
429    EXPECT_EQ(OK, native_window_set_buffer_count(anw.get(), 2));
430    EXPECT_NE(OK, native_window_set_buffer_count(anw.get(), 1));
431}
432
433TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
434    sp<ANativeWindow> anw(mSTC);
435    sp<SurfaceTexture> st(mST);
436    android_native_buffer_t* buf[3];
437    ASSERT_EQ(OK, st->setSynchronousMode(true));
438    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
439    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
440    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
441    EXPECT_EQ(-EBUSY, anw->dequeueBuffer(anw.get(), &buf[2]));
442
443    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
444
445    EXPECT_EQ(OK, st->updateTexImage());
446    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
447
448    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
449
450    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
451    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[2]));
452}
453
454TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeWaitRetire) {
455    sp<ANativeWindow> anw(mSTC);
456    sp<SurfaceTexture> st(mST);
457
458    class MyThread : public Thread {
459        sp<SurfaceTexture> st;
460        EGLContext ctx;
461        EGLSurface sur;
462        EGLDisplay dpy;
463        bool mBufferRetired;
464        Mutex mLock;
465        virtual bool threadLoop() {
466            eglMakeCurrent(dpy, sur, sur, ctx);
467            usleep(20000);
468            Mutex::Autolock _l(mLock);
469            st->updateTexImage();
470            mBufferRetired = true;
471            eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
472            return false;
473        }
474    public:
475        MyThread(const sp<SurfaceTexture>& st)
476            : st(st), mBufferRetired(false) {
477            ctx = eglGetCurrentContext();
478            sur = eglGetCurrentSurface(EGL_DRAW);
479            dpy = eglGetCurrentDisplay();
480            eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
481        }
482        ~MyThread() {
483            eglMakeCurrent(dpy, sur, sur, ctx);
484        }
485        void bufferDequeued() {
486            Mutex::Autolock _l(mLock);
487            EXPECT_EQ(true, mBufferRetired);
488        }
489    };
490
491    android_native_buffer_t* buf[3];
492    ASSERT_EQ(OK, st->setSynchronousMode(true));
493    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 2));
494    // dequeue/queue/update so we have a current buffer
495    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
496    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
497    st->updateTexImage();
498
499    MyThread* thread = new MyThread(st);
500    sp<Thread> threadBase(thread);
501
502    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
503    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
504    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
505    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
506    thread->run();
507    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
508    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
509    thread->bufferDequeued();
510    thread->requestExitAndWait();
511}
512
513}
514