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