SurfaceTextureClient_test.cpp revision 8cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09ef
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, native_window_set_buffer_count(anw.get(), 4));
263    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
264    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
265    EXPECT_NE(buf[0], buf[1]);
266    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
267    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
268    EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
269    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
270    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
271    EXPECT_NE(buf[0], buf[1]);
272    EXPECT_EQ(16, buf[0]->width);
273    EXPECT_EQ(16, buf[1]->width);
274    EXPECT_EQ(8, buf[0]->height);
275    EXPECT_EQ(8, buf[1]->height);
276    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
277    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
278}
279
280TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
281    sp<ANativeWindow> anw(mSTC);
282    sp<SurfaceTexture> st(mST);
283    ANativeWindowBuffer* buf[2];
284    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
285    EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
286    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
287    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
288    EXPECT_NE(buf[0], buf[1]);
289    EXPECT_EQ(16, buf[0]->width);
290    EXPECT_EQ(16, buf[1]->width);
291    EXPECT_EQ(8, buf[0]->height);
292    EXPECT_EQ(8, buf[1]->height);
293    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
294    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
295    EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 12, 24, 0));
296    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
297    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
298    EXPECT_NE(buf[0], buf[1]);
299    EXPECT_EQ(12, buf[0]->width);
300    EXPECT_EQ(12, buf[1]->width);
301    EXPECT_EQ(24, buf[0]->height);
302    EXPECT_EQ(24, buf[1]->height);
303    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
304    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[1]));
305}
306
307TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
308    sp<ANativeWindow> anw(mSTC);
309    sp<SurfaceTexture> st(mST);
310    android_native_buffer_t* buf[3];
311    ASSERT_EQ(OK, st->setSynchronousMode(false));
312    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
313
314    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
315    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
316    EXPECT_EQ(OK, st->updateTexImage());
317    EXPECT_EQ(OK, st->updateTexImage());
318
319    ASSERT_EQ(OK, st->setSynchronousMode(true));
320    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
321
322    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
323    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
324    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
325    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
326
327    EXPECT_EQ(OK, st->updateTexImage());
328    EXPECT_EQ(OK, st->updateTexImage());
329    EXPECT_EQ(OK, st->updateTexImage());
330}
331
332TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
333    sp<ANativeWindow> anw(mSTC);
334    sp<SurfaceTexture> st(mST);
335    android_native_buffer_t* buf[3];
336    ASSERT_EQ(OK, st->setSynchronousMode(true));
337    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
338    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
339    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
340    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
341    EXPECT_NE(buf[0], buf[1]);
342    EXPECT_NE(buf[1], buf[2]);
343    EXPECT_NE(buf[2], buf[0]);
344    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
345    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
346    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
347    EXPECT_EQ(OK, st->updateTexImage());
348    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
349    EXPECT_EQ(OK, st->updateTexImage());
350    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
351    EXPECT_EQ(OK, st->updateTexImage());
352    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
353}
354
355TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
356    sp<ANativeWindow> anw(mSTC);
357    sp<SurfaceTexture> st(mST);
358    android_native_buffer_t* buf[3];
359    ASSERT_EQ(OK, st->setSynchronousMode(true));
360    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 4));
361    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
362    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
363    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
364    EXPECT_NE(buf[0], buf[1]);
365    EXPECT_NE(buf[1], buf[2]);
366    EXPECT_NE(buf[2], buf[0]);
367    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
368    EXPECT_EQ(OK, st->updateTexImage());
369    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
370    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
371    EXPECT_EQ(OK, st->updateTexImage());
372    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
373    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
374    EXPECT_EQ(OK, st->updateTexImage());
375    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
376}
377
378TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
379    sp<ANativeWindow> anw(mSTC);
380    sp<SurfaceTexture> st(mST);
381    android_native_buffer_t* buf[3];
382    ASSERT_EQ(OK, st->setSynchronousMode(true));
383    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
384
385    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
386    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
387    EXPECT_EQ(OK, st->updateTexImage());
388    EXPECT_EQ(st->getCurrentBuffer().get(), buf[0]);
389
390    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
391    EXPECT_NE(buf[0], buf[1]);
392    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
393    EXPECT_EQ(OK, st->updateTexImage());
394    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
395
396    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
397    EXPECT_NE(buf[1], buf[2]);
398    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
399    EXPECT_EQ(OK, st->updateTexImage());
400    EXPECT_EQ(st->getCurrentBuffer().get(), buf[2]);
401}
402
403// XXX: We currently have no hardware that properly handles dequeuing the
404// buffer that is currently bound to the texture.
405TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
406    sp<ANativeWindow> anw(mSTC);
407    sp<SurfaceTexture> st(mST);
408    android_native_buffer_t* buf[3];
409    android_native_buffer_t* firstBuf;
410    ASSERT_EQ(OK, st->setSynchronousMode(true));
411    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
412    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &firstBuf));
413    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), firstBuf));
414    EXPECT_EQ(OK, st->updateTexImage());
415    EXPECT_EQ(st->getCurrentBuffer().get(), firstBuf);
416    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
417    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
418    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
419    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
420    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
421    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
422    EXPECT_NE(buf[0], buf[1]);
423    EXPECT_NE(buf[1], buf[2]);
424    EXPECT_NE(buf[2], buf[0]);
425    EXPECT_EQ(firstBuf, buf[2]);
426}
427
428TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
429    sp<ANativeWindow> anw(mSTC);
430    sp<SurfaceTexture> st(mST);
431    android_native_buffer_t* buf[3];
432    ASSERT_EQ(OK, st->setSynchronousMode(true));
433    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
434    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
435    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
436    EXPECT_EQ(-EBUSY, anw->dequeueBuffer(anw.get(), &buf[2]));
437
438    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
439
440    EXPECT_EQ(OK, st->updateTexImage());
441    EXPECT_EQ(st->getCurrentBuffer().get(), buf[1]);
442
443    EXPECT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
444
445    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[0]));
446    ASSERT_EQ(OK, anw->cancelBuffer(anw.get(), buf[2]));
447}
448
449TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeWaitRetire) {
450    sp<ANativeWindow> anw(mSTC);
451    sp<SurfaceTexture> st(mST);
452
453    class MyThread : public Thread {
454        sp<SurfaceTexture> st;
455        EGLContext ctx;
456        EGLSurface sur;
457        EGLDisplay dpy;
458        bool mBufferRetired;
459        Mutex mLock;
460        virtual bool threadLoop() {
461            eglMakeCurrent(dpy, sur, sur, ctx);
462            usleep(20000);
463            Mutex::Autolock _l(mLock);
464            st->updateTexImage();
465            mBufferRetired = true;
466            eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
467            return false;
468        }
469    public:
470        MyThread(const sp<SurfaceTexture>& st)
471            : st(st), mBufferRetired(false) {
472            ctx = eglGetCurrentContext();
473            sur = eglGetCurrentSurface(EGL_DRAW);
474            dpy = eglGetCurrentDisplay();
475            eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
476        }
477        ~MyThread() {
478            eglMakeCurrent(dpy, sur, sur, ctx);
479        }
480        void bufferDequeued() {
481            Mutex::Autolock _l(mLock);
482            EXPECT_EQ(true, mBufferRetired);
483        }
484    };
485
486    android_native_buffer_t* buf[3];
487    ASSERT_EQ(OK, st->setSynchronousMode(true));
488    ASSERT_EQ(OK, native_window_set_buffer_count(anw.get(), 3));
489    // dequeue/queue/update so we have a current buffer
490    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
491    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
492    st->updateTexImage();
493
494    MyThread* thread = new MyThread(st);
495    sp<Thread> threadBase(thread);
496
497    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
498    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[0]));
499    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
500    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[1]));
501    thread->run();
502    ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[2]));
503    ASSERT_EQ(OK, anw->queueBuffer(anw.get(), buf[2]));
504    thread->bufferDequeued();
505    thread->requestExitAndWait();
506}
507
508}
509