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