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