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