SurfaceTextureClient_test.cpp revision c10d9d90b2088a3304076e0dc4bf05cdbb5d45ab
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        mANW = mSTC;
36
37        // We need a valid GL context so we can test updateTexImage()
38        // This initializes EGL and create a dummy GL context with a
39        // pbuffer render target.
40        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
41        ASSERT_EQ(EGL_SUCCESS, eglGetError());
42        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
43
44        EGLint majorVersion, minorVersion;
45        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
46        ASSERT_EQ(EGL_SUCCESS, eglGetError());
47
48        EGLConfig myConfig;
49        EGLint numConfigs = 0;
50        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(),
51                &myConfig, 1, &numConfigs));
52        ASSERT_EQ(EGL_SUCCESS, eglGetError());
53
54        EGLint pbufferAttribs[] = {
55            EGL_WIDTH, 16,
56            EGL_HEIGHT, 16,
57            EGL_NONE };
58        mEglSurface = eglCreatePbufferSurface(mEglDisplay, myConfig, pbufferAttribs);
59        ASSERT_EQ(EGL_SUCCESS, eglGetError());
60        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
61
62        mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT, 0);
63        ASSERT_EQ(EGL_SUCCESS, eglGetError());
64        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
65
66        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
67        ASSERT_EQ(EGL_SUCCESS, eglGetError());
68    }
69
70    virtual void TearDown() {
71        mST.clear();
72        mSTC.clear();
73        mANW.clear();
74
75        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
76        eglDestroyContext(mEglDisplay, mEglContext);
77        eglDestroySurface(mEglDisplay, mEglSurface);
78        eglTerminate(mEglDisplay);
79    }
80
81    virtual EGLint const* getConfigAttribs() {
82        static EGLint sDefaultConfigAttribs[] = {
83            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
84            EGL_NONE
85        };
86
87        return sDefaultConfigAttribs;
88    }
89
90    sp<SurfaceTexture> mST;
91    sp<SurfaceTextureClient> mSTC;
92    sp<ANativeWindow> mANW;
93
94    EGLDisplay mEglDisplay;
95    EGLSurface mEglSurface;
96    EGLContext mEglContext;
97};
98
99TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
100    sp<ISurfaceTexture> ist(mSTC->getISurfaceTexture());
101    ASSERT_TRUE(ist != NULL);
102}
103
104TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) {
105    int result = -123;
106    int err = mANW->query(mANW.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
107            &result);
108    EXPECT_EQ(NO_ERROR, err);
109    EXPECT_EQ(0, result);
110}
111
112TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
113    int result = -123;
114    int err = mANW->query(mANW.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
115    EXPECT_EQ(NO_ERROR, err);
116    EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
117}
118
119TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) {
120    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
121    ASSERT_EQ(EGL_SUCCESS, eglGetError());
122    ASSERT_NE(EGL_NO_DISPLAY, dpy);
123
124    EGLint majorVersion;
125    EGLint minorVersion;
126    EXPECT_TRUE(eglInitialize(dpy, &majorVersion, &minorVersion));
127    ASSERT_EQ(EGL_SUCCESS, eglGetError());
128
129    EGLConfig myConfig = {0};
130    EGLint numConfigs = 0;
131    EGLint configAttribs[] = {
132        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
133        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
134        EGL_RED_SIZE, 8,
135        EGL_GREEN_SIZE, 8,
136        EGL_BLUE_SIZE, 8,
137        EGL_ALPHA_SIZE, 8,
138        EGL_DEPTH_SIZE, 16,
139        EGL_STENCIL_SIZE, 8,
140        EGL_NONE };
141    EXPECT_TRUE(eglChooseConfig(dpy, configAttribs, &myConfig, 1,
142            &numConfigs));
143    ASSERT_EQ(EGL_SUCCESS, eglGetError());
144
145    EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, mANW.get(),
146            NULL);
147    EXPECT_NE(EGL_NO_SURFACE, eglSurface);
148    EXPECT_EQ(EGL_SUCCESS, eglGetError());
149
150    eglTerminate(dpy);
151}
152
153TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) {
154    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1,  0,  0));
155    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0, -1,  0));
156    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0,  0, -1));
157    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, -1,  0));
158    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  0,  8,  0));
159    EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(),  8,  0,  0));
160}
161
162TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
163    ANativeWindowBuffer* buf;
164    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
165    EXPECT_EQ(1, buf->width);
166    EXPECT_EQ(1, buf->height);
167    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
168    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
169}
170
171TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
172    ANativeWindowBuffer* buf;
173    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, PIXEL_FORMAT_RGB_565));
174    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
175    EXPECT_EQ(16, buf->width);
176    EXPECT_EQ(8, buf->height);
177    EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
178    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
179}
180
181TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
182    ANativeWindowBuffer* buf;
183    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
184    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
185    EXPECT_EQ(1, buf->width);
186    EXPECT_EQ(1, buf->height);
187    EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
188    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
189}
190
191TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
192    ANativeWindowBuffer* buf;
193    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
194    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
195    EXPECT_EQ(16, buf->width);
196    EXPECT_EQ(8, buf->height);
197    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
198    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
199}
200
201TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
202    ANativeWindowBuffer* buf;
203    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
204    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
205    EXPECT_EQ(16, buf->width);
206    EXPECT_EQ(8, buf->height);
207    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
208    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
209    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0));
210    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
211    EXPECT_EQ(1, buf->width);
212    EXPECT_EQ(1, buf->height);
213    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
214    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
215}
216
217TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
218    ANativeWindowBuffer* buf;
219    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
220    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
221    EXPECT_EQ(1, buf->width);
222    EXPECT_EQ(1, buf->height);
223    EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
224    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
225    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
226    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
227    EXPECT_EQ(16, buf->width);
228    EXPECT_EQ(8, buf->height);
229    EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format);
230    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
231}
232
233TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSize) {
234    sp<SurfaceTexture> st(mST);
235    ANativeWindowBuffer* buf;
236    EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
237    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf));
238    EXPECT_EQ(16, buf->width);
239    EXPECT_EQ(8, buf->height);
240    EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
241    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf));
242}
243
244TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeAfterDequeue) {
245    ANativeWindowBuffer* buf[2];
246    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
247    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
248    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
249    EXPECT_NE(buf[0], buf[1]);
250    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
251    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
252    EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
253    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
254    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
255    EXPECT_NE(buf[0], buf[1]);
256    EXPECT_EQ(16, buf[0]->width);
257    EXPECT_EQ(16, buf[1]->width);
258    EXPECT_EQ(8, buf[0]->height);
259    EXPECT_EQ(8, buf[1]->height);
260    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
261    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
262}
263
264TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
265    ANativeWindowBuffer* buf[2];
266    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
267    EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8));
268    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
269    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.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, mANW->cancelBuffer(mANW.get(), buf[0]));
276    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
277    EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0));
278    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
279    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
280    EXPECT_NE(buf[0], buf[1]);
281    EXPECT_EQ(12, buf[0]->width);
282    EXPECT_EQ(12, buf[1]->width);
283    EXPECT_EQ(24, buf[0]->height);
284    EXPECT_EQ(24, buf[1]->height);
285    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
286    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1]));
287}
288
289TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
290    android_native_buffer_t* buf[3];
291    ASSERT_EQ(OK, mST->setSynchronousMode(false));
292    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
293
294    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
295    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
296    EXPECT_EQ(OK, mST->updateTexImage());
297    EXPECT_EQ(OK, mST->updateTexImage());
298
299    ASSERT_EQ(OK, mST->setSynchronousMode(true));
300    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
301
302    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
303    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
304    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
305    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
306
307    EXPECT_EQ(OK, mST->updateTexImage());
308    EXPECT_EQ(OK, mST->updateTexImage());
309    EXPECT_EQ(OK, mST->updateTexImage());
310}
311
312TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
313    android_native_buffer_t* buf[3];
314    ASSERT_EQ(OK, mST->setSynchronousMode(true));
315    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
316    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
317    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
318    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
319    EXPECT_NE(buf[0], buf[1]);
320    EXPECT_NE(buf[1], buf[2]);
321    EXPECT_NE(buf[2], buf[0]);
322    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
323    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
324    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
325    EXPECT_EQ(OK, mST->updateTexImage());
326    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
327    EXPECT_EQ(OK, mST->updateTexImage());
328    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
329    EXPECT_EQ(OK, mST->updateTexImage());
330    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
331}
332
333TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
334    android_native_buffer_t* buf[3];
335    ASSERT_EQ(OK, mST->setSynchronousMode(true));
336    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
337    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
338    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
339    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
340    EXPECT_NE(buf[0], buf[1]);
341    EXPECT_NE(buf[1], buf[2]);
342    EXPECT_NE(buf[2], buf[0]);
343    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
344    EXPECT_EQ(OK, mST->updateTexImage());
345    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
346    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
347    EXPECT_EQ(OK, mST->updateTexImage());
348    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
349    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
350    EXPECT_EQ(OK, mST->updateTexImage());
351    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
352}
353
354TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
355    android_native_buffer_t* buf[3];
356    ASSERT_EQ(OK, mST->setSynchronousMode(true));
357    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
358
359    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
360    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
361    EXPECT_EQ(OK, mST->updateTexImage());
362    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
363
364    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
365    EXPECT_NE(buf[0], buf[1]);
366    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
367    EXPECT_EQ(OK, mST->updateTexImage());
368    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
369
370    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
371    EXPECT_NE(buf[1], buf[2]);
372    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
373    EXPECT_EQ(OK, mST->updateTexImage());
374    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
375}
376
377// XXX: We currently have no hardware that properly handles dequeuing the
378// buffer that is currently bound to the texture.
379TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
380    android_native_buffer_t* buf[3];
381    android_native_buffer_t* firstBuf;
382    ASSERT_EQ(OK, mST->setSynchronousMode(true));
383    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
384    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &firstBuf));
385    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf));
386    EXPECT_EQ(OK, mST->updateTexImage());
387    EXPECT_EQ(mST->getCurrentBuffer().get(), firstBuf);
388    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
389    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
390    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
391    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
392    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
393    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
394    EXPECT_NE(buf[0], buf[1]);
395    EXPECT_NE(buf[1], buf[2]);
396    EXPECT_NE(buf[2], buf[0]);
397    EXPECT_EQ(firstBuf, buf[2]);
398}
399
400TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
401    android_native_buffer_t* buf[3];
402    ASSERT_EQ(OK, mST->setSynchronousMode(true));
403    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
404
405    // We should be able to dequeue all the buffers before we've queued mANWy.
406    EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
407    EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
408    EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
409
410    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2]));
411    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
412
413    EXPECT_EQ(OK, mST->updateTexImage());
414    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
415
416    EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
417
418    // Once we've queued a buffer, however we should not be able to dequeue more
419    // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case.
420    EXPECT_EQ(-EBUSY, mANW->dequeueBuffer(mANW.get(), &buf[1]));
421
422    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0]));
423    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2]));
424}
425
426// XXX: This is not expected to pass until the synchronization hacks are removed
427// from the SurfaceTexture class.
428TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {
429    class MyThread : public Thread {
430        sp<SurfaceTexture> mST;
431        EGLContext ctx;
432        EGLSurface sur;
433        EGLDisplay dpy;
434        bool mBufferRetired;
435        Mutex mLock;
436        virtual bool threadLoop() {
437            eglMakeCurrent(dpy, sur, sur, ctx);
438            usleep(20000);
439            Mutex::Autolock _l(mLock);
440            mST->updateTexImage();
441            mBufferRetired = true;
442            eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
443            return false;
444        }
445    public:
446        MyThread(const sp<SurfaceTexture>& mST)
447            : mST(mST), mBufferRetired(false) {
448            ctx = eglGetCurrentContext();
449            sur = eglGetCurrentSurface(EGL_DRAW);
450            dpy = eglGetCurrentDisplay();
451            eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
452        }
453        ~MyThread() {
454            eglMakeCurrent(dpy, sur, sur, ctx);
455        }
456        void bufferDequeued() {
457            Mutex::Autolock _l(mLock);
458            EXPECT_EQ(true, mBufferRetired);
459        }
460    };
461
462    android_native_buffer_t* buf[3];
463    ASSERT_EQ(OK, mST->setSynchronousMode(true));
464    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
465    // dequeue/queue/update so we have a current buffer
466    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
467    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
468    mST->updateTexImage();
469
470    MyThread* thread = new MyThread(mST);
471    sp<Thread> threadBase(thread);
472
473    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
474    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
475    thread->run();
476    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1]));
477    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1]));
478    //ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2]));
479    //ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2]));
480    thread->bufferDequeued();
481    thread->requestExitAndWait();
482}
483
484TEST_F(SurfaceTextureClientTest, GetTransformMatrixReturnsVerticalFlip) {
485    android_native_buffer_t* buf[3];
486    float mtx[16] = {};
487    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
488    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
489    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
490    ASSERT_EQ(OK, mST->updateTexImage());
491    mST->getTransformMatrix(mtx);
492
493    EXPECT_EQ(1.f, mtx[0]);
494    EXPECT_EQ(0.f, mtx[1]);
495    EXPECT_EQ(0.f, mtx[2]);
496    EXPECT_EQ(0.f, mtx[3]);
497
498    EXPECT_EQ(0.f, mtx[4]);
499    EXPECT_EQ(-1.f, mtx[5]);
500    EXPECT_EQ(0.f, mtx[6]);
501    EXPECT_EQ(0.f, mtx[7]);
502
503    EXPECT_EQ(0.f, mtx[8]);
504    EXPECT_EQ(0.f, mtx[9]);
505    EXPECT_EQ(1.f, mtx[10]);
506    EXPECT_EQ(0.f, mtx[11]);
507
508    EXPECT_EQ(0.f, mtx[12]);
509    EXPECT_EQ(1.f, mtx[13]);
510    EXPECT_EQ(0.f, mtx[14]);
511    EXPECT_EQ(1.f, mtx[15]);
512}
513
514TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffers) {
515    android_native_buffer_t* buf[3];
516    float mtx[16] = {};
517    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
518    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
519    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
520    ASSERT_EQ(OK, mST->updateTexImage());
521    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
522    mST->getTransformMatrix(mtx);
523
524    EXPECT_EQ(1.f, mtx[0]);
525    EXPECT_EQ(0.f, mtx[1]);
526    EXPECT_EQ(0.f, mtx[2]);
527    EXPECT_EQ(0.f, mtx[3]);
528
529    EXPECT_EQ(0.f, mtx[4]);
530    EXPECT_EQ(-1.f, mtx[5]);
531    EXPECT_EQ(0.f, mtx[6]);
532    EXPECT_EQ(0.f, mtx[7]);
533
534    EXPECT_EQ(0.f, mtx[8]);
535    EXPECT_EQ(0.f, mtx[9]);
536    EXPECT_EQ(1.f, mtx[10]);
537    EXPECT_EQ(0.f, mtx[11]);
538
539    EXPECT_EQ(0.f, mtx[12]);
540    EXPECT_EQ(1.f, mtx[13]);
541    EXPECT_EQ(0.f, mtx[14]);
542    EXPECT_EQ(1.f, mtx[15]);
543}
544
545TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) {
546    android_native_buffer_t* buf[3];
547    float mtx[16] = {};
548    android_native_rect_t crop;
549    crop.left = 0;
550    crop.top = 0;
551    crop.right = 5;
552    crop.bottom = 5;
553
554    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
555    ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0));
556    ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0]));
557    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop));
558    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0]));
559    ASSERT_EQ(OK, mST->updateTexImage());
560    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
561    mST->getTransformMatrix(mtx);
562
563    // This accounts for the 1 texel shrink for each edge that's included in the
564    // transform matrix to avoid texturing outside the crop region.
565    EXPECT_EQ(.5f, mtx[0]);
566    EXPECT_EQ(0.f, mtx[1]);
567    EXPECT_EQ(0.f, mtx[2]);
568    EXPECT_EQ(0.f, mtx[3]);
569
570    EXPECT_EQ(0.f, mtx[4]);
571    EXPECT_EQ(-.5f, mtx[5]);
572    EXPECT_EQ(0.f, mtx[6]);
573    EXPECT_EQ(0.f, mtx[7]);
574
575    EXPECT_EQ(0.f, mtx[8]);
576    EXPECT_EQ(0.f, mtx[9]);
577    EXPECT_EQ(1.f, mtx[10]);
578    EXPECT_EQ(0.f, mtx[11]);
579
580    EXPECT_EQ(0.f, mtx[12]);
581    EXPECT_EQ(.5f, mtx[13]);
582    EXPECT_EQ(0.f, mtx[14]);
583    EXPECT_EQ(1.f, mtx[15]);
584}
585
586// This test verifies that the buffer format can be queried immediately after
587// it is set.
588TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) {
589    sp<ANativeWindow> anw(mSTC);
590    int fmts[] = {
591        // RGBA_8888 should not come first, as it's the default
592        HAL_PIXEL_FORMAT_RGBX_8888,
593        HAL_PIXEL_FORMAT_RGBA_8888,
594        HAL_PIXEL_FORMAT_RGB_888,
595        HAL_PIXEL_FORMAT_RGB_565,
596        HAL_PIXEL_FORMAT_BGRA_8888,
597        HAL_PIXEL_FORMAT_RGBA_5551,
598        HAL_PIXEL_FORMAT_RGBA_4444,
599        HAL_PIXEL_FORMAT_YV12,
600    };
601
602    const int numFmts = (sizeof(fmts) / sizeof(fmts[0]));
603    for (int i = 0; i < numFmts; i++) {
604      int fmt = -1;
605      ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i]));
606      ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt));
607      EXPECT_EQ(fmts[i], fmt);
608    }
609}
610
611class MultiSurfaceTextureClientTest : public ::testing::Test {
612
613public:
614    MultiSurfaceTextureClientTest() :
615            mEglDisplay(EGL_NO_DISPLAY),
616            mEglContext(EGL_NO_CONTEXT) {
617        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
618            mEglSurfaces[i] = EGL_NO_CONTEXT;
619        }
620    }
621
622protected:
623
624    enum { NUM_SURFACE_TEXTURES = 32 };
625
626    virtual void SetUp() {
627        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
628        ASSERT_EQ(EGL_SUCCESS, eglGetError());
629        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
630
631        EGLint majorVersion, minorVersion;
632        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
633        ASSERT_EQ(EGL_SUCCESS, eglGetError());
634
635        EGLConfig myConfig;
636        EGLint numConfigs = 0;
637        EGLint configAttribs[] = {
638            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
639            EGL_NONE
640        };
641        EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1,
642                &numConfigs));
643        ASSERT_EQ(EGL_SUCCESS, eglGetError());
644
645        mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
646                0);
647        ASSERT_EQ(EGL_SUCCESS, eglGetError());
648        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
649
650        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
651            sp<SurfaceTexture> st(new SurfaceTexture(i));
652            sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st));
653            mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
654                    static_cast<ANativeWindow*>(stc.get()), NULL);
655            ASSERT_EQ(EGL_SUCCESS, eglGetError());
656            ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]);
657        }
658    }
659
660    virtual void TearDown() {
661        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
662                EGL_NO_CONTEXT);
663
664        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
665            if (mEglSurfaces[i] != EGL_NO_SURFACE) {
666                eglDestroySurface(mEglDisplay, mEglSurfaces[i]);
667            }
668        }
669
670        if (mEglContext != EGL_NO_CONTEXT) {
671            eglDestroyContext(mEglDisplay, mEglContext);
672        }
673
674        if (mEglDisplay != EGL_NO_DISPLAY) {
675            eglTerminate(mEglDisplay);
676        }
677    }
678
679    EGLDisplay mEglDisplay;
680    EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES];
681    EGLContext mEglContext;
682};
683
684// XXX: This test is disabled because it causes a hang on some devices.  See bug
685// 5015672.
686TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) {
687    for (int iter = 0; iter < 8; iter++) {
688        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
689            eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i],
690                    mEglContext);
691            glClear(GL_COLOR_BUFFER_BIT);
692            eglSwapBuffers(mEglDisplay, mEglSurfaces[i]);
693        }
694    }
695}
696
697} // namespace android
698