SurfaceTextureClient_test.cpp revision db89edc94bd2a78226b407f9f7261e202e7fa325
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(bq);
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, mANW->setSwapInterval(mANW.get(), 0));
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, mANW->setSwapInterval(mANW.get(), 1));
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, native_window_set_buffer_count(mANW.get(), 4));
365    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
366    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
367    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
368    EXPECT_NE(buf[0], buf[1]);
369    EXPECT_NE(buf[1], buf[2]);
370    EXPECT_NE(buf[2], buf[0]);
371    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
372    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
373    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
374    EXPECT_EQ(OK, mST->updateTexImage());
375    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
376    EXPECT_EQ(OK, mST->updateTexImage());
377    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
378    EXPECT_EQ(OK, mST->updateTexImage());
379    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
380}
381
382TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
383    android_native_buffer_t* buf[3];
384    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
385    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
386    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
387    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
388    EXPECT_NE(buf[0], buf[1]);
389    EXPECT_NE(buf[1], buf[2]);
390    EXPECT_NE(buf[2], buf[0]);
391    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
392    EXPECT_EQ(OK, mST->updateTexImage());
393    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
394    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
395    EXPECT_EQ(OK, mST->updateTexImage());
396    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
397    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
398    EXPECT_EQ(OK, mST->updateTexImage());
399    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
400}
401
402TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
403    android_native_buffer_t* buf[3];
404    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
405
406    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
407    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
408    EXPECT_EQ(OK, mST->updateTexImage());
409    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]);
410
411    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
412    EXPECT_NE(buf[0], buf[1]);
413    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
414    EXPECT_EQ(OK, mST->updateTexImage());
415    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
416
417    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
418    EXPECT_NE(buf[1], buf[2]);
419    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
420    EXPECT_EQ(OK, mST->updateTexImage());
421    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]);
422}
423
424// XXX: We currently have no hardware that properly handles dequeuing the
425// buffer that is currently bound to the texture.
426TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
427    android_native_buffer_t* buf[3];
428    android_native_buffer_t* firstBuf;
429    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
430    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &firstBuf));
431    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf, -1));
432    EXPECT_EQ(OK, mST->updateTexImage());
433    EXPECT_EQ(mST->getCurrentBuffer().get(), firstBuf);
434    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
435    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
436    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
437    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
438    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
439    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
440    EXPECT_NE(buf[0], buf[1]);
441    EXPECT_NE(buf[1], buf[2]);
442    EXPECT_NE(buf[2], buf[0]);
443    EXPECT_EQ(firstBuf, buf[2]);
444}
445
446TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
447    android_native_buffer_t* buf[3];
448    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
449
450    // We should be able to dequeue all the buffers before we've queued mANWy.
451    EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
452    EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
453    EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
454
455    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2], -1));
456    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
457
458    EXPECT_EQ(OK, mST->updateTexImage());
459    EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]);
460
461    EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
462
463    // Once we've queued a buffer, however we should not be able to dequeue more
464    // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case.
465    EXPECT_EQ(-EBUSY, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
466
467    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
468    ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2], -1));
469}
470
471TEST_F(SurfaceTextureClientTest, SetCropCropsCrop) {
472    android_native_rect_t rect = {-2, -13, 40, 18};
473    native_window_set_crop(mANW.get(), &rect);
474
475    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 4, 4));
476
477    android_native_buffer_t* buf;
478    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
479    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf, -1));
480    ASSERT_EQ(OK, mST->updateTexImage());
481
482    Rect crop = mST->getCurrentCrop();
483    EXPECT_EQ(0, crop.left);
484    EXPECT_EQ(0, crop.top);
485    EXPECT_EQ(4, crop.right);
486    EXPECT_EQ(4, crop.bottom);
487}
488
489// XXX: This is not expected to pass until the synchronization hacks are removed
490// from the SurfaceTexture class.
491TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {
492    class MyThread : public Thread {
493        sp<GLConsumer> mST;
494        EGLContext ctx;
495        EGLSurface sur;
496        EGLDisplay dpy;
497        bool mBufferRetired;
498        Mutex mLock;
499        virtual bool threadLoop() {
500            eglMakeCurrent(dpy, sur, sur, ctx);
501            usleep(20000);
502            Mutex::Autolock _l(mLock);
503            mST->updateTexImage();
504            mBufferRetired = true;
505            eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
506            return false;
507        }
508    public:
509        MyThread(const sp<GLConsumer>& mST)
510            : mST(mST), mBufferRetired(false) {
511            ctx = eglGetCurrentContext();
512            sur = eglGetCurrentSurface(EGL_DRAW);
513            dpy = eglGetCurrentDisplay();
514            eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
515        }
516        ~MyThread() {
517            eglMakeCurrent(dpy, sur, sur, ctx);
518        }
519        void bufferDequeued() {
520            Mutex::Autolock _l(mLock);
521            EXPECT_EQ(true, mBufferRetired);
522        }
523    };
524
525    android_native_buffer_t* buf[3];
526    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
527    // dequeue/queue/update so we have a current buffer
528    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
529    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
530    mST->updateTexImage();
531
532    MyThread* thread = new MyThread(mST);
533    sp<Thread> threadBase(thread);
534
535    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
536    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
537    thread->run();
538    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
539    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1], -1));
540    //ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[2]));
541    //ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2], -1));
542    thread->bufferDequeued();
543    thread->requestExitAndWait();
544}
545
546TEST_F(SurfaceTextureClientTest, GetTransformMatrixReturnsVerticalFlip) {
547    android_native_buffer_t* buf[3];
548    float mtx[16] = {};
549    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
550    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
551    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
552    ASSERT_EQ(OK, mST->updateTexImage());
553    mST->getTransformMatrix(mtx);
554
555    EXPECT_EQ(1.f, mtx[0]);
556    EXPECT_EQ(0.f, mtx[1]);
557    EXPECT_EQ(0.f, mtx[2]);
558    EXPECT_EQ(0.f, mtx[3]);
559
560    EXPECT_EQ(0.f, mtx[4]);
561    EXPECT_EQ(-1.f, mtx[5]);
562    EXPECT_EQ(0.f, mtx[6]);
563    EXPECT_EQ(0.f, mtx[7]);
564
565    EXPECT_EQ(0.f, mtx[8]);
566    EXPECT_EQ(0.f, mtx[9]);
567    EXPECT_EQ(1.f, mtx[10]);
568    EXPECT_EQ(0.f, mtx[11]);
569
570    EXPECT_EQ(0.f, mtx[12]);
571    EXPECT_EQ(1.f, mtx[13]);
572    EXPECT_EQ(0.f, mtx[14]);
573    EXPECT_EQ(1.f, mtx[15]);
574}
575
576TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffers) {
577    android_native_buffer_t* buf[3];
578    float mtx[16] = {};
579    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
580    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
581    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
582    ASSERT_EQ(OK, mST->updateTexImage());
583    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
584    mST->getTransformMatrix(mtx);
585
586    EXPECT_EQ(1.f, mtx[0]);
587    EXPECT_EQ(0.f, mtx[1]);
588    EXPECT_EQ(0.f, mtx[2]);
589    EXPECT_EQ(0.f, mtx[3]);
590
591    EXPECT_EQ(0.f, mtx[4]);
592    EXPECT_EQ(-1.f, mtx[5]);
593    EXPECT_EQ(0.f, mtx[6]);
594    EXPECT_EQ(0.f, mtx[7]);
595
596    EXPECT_EQ(0.f, mtx[8]);
597    EXPECT_EQ(0.f, mtx[9]);
598    EXPECT_EQ(1.f, mtx[10]);
599    EXPECT_EQ(0.f, mtx[11]);
600
601    EXPECT_EQ(0.f, mtx[12]);
602    EXPECT_EQ(1.f, mtx[13]);
603    EXPECT_EQ(0.f, mtx[14]);
604    EXPECT_EQ(1.f, mtx[15]);
605}
606
607TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) {
608    android_native_buffer_t* buf[3];
609    float mtx[16] = {};
610    android_native_rect_t crop;
611    crop.left = 0;
612    crop.top = 0;
613    crop.right = 5;
614    crop.bottom = 5;
615
616    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
617    ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0));
618    ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
619    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop));
620    ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
621    ASSERT_EQ(OK, mST->updateTexImage());
622    ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers
623    mST->getTransformMatrix(mtx);
624
625    // This accounts for the .5 texel shrink for each edge that's included in the
626    // transform matrix to avoid texturing outside the crop region.
627    EXPECT_EQ(0.5, mtx[0]);
628    EXPECT_EQ(0.f, mtx[1]);
629    EXPECT_EQ(0.f, mtx[2]);
630    EXPECT_EQ(0.f, mtx[3]);
631
632    EXPECT_EQ(0.f, mtx[4]);
633    EXPECT_EQ(-0.5, mtx[5]);
634    EXPECT_EQ(0.f, mtx[6]);
635    EXPECT_EQ(0.f, mtx[7]);
636
637    EXPECT_EQ(0.f, mtx[8]);
638    EXPECT_EQ(0.f, mtx[9]);
639    EXPECT_EQ(1.f, mtx[10]);
640    EXPECT_EQ(0.f, mtx[11]);
641
642    EXPECT_EQ(0.0625f, mtx[12]);
643    EXPECT_EQ(0.5625f, mtx[13]);
644    EXPECT_EQ(0.f, mtx[14]);
645    EXPECT_EQ(1.f, mtx[15]);
646}
647
648// This test verifies that the buffer format can be queried immediately after
649// it is set.
650TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) {
651    sp<ANativeWindow> anw(mSTC);
652    int fmts[] = {
653        // RGBA_8888 should not come first, as it's the default
654        HAL_PIXEL_FORMAT_RGBX_8888,
655        HAL_PIXEL_FORMAT_RGBA_8888,
656        HAL_PIXEL_FORMAT_RGB_888,
657        HAL_PIXEL_FORMAT_RGB_565,
658        HAL_PIXEL_FORMAT_BGRA_8888,
659        HAL_PIXEL_FORMAT_YV12,
660    };
661
662    const int numFmts = (sizeof(fmts) / sizeof(fmts[0]));
663    for (int i = 0; i < numFmts; i++) {
664      int fmt = -1;
665      ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i]));
666      ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt));
667      EXPECT_EQ(fmts[i], fmt);
668    }
669}
670
671class MultiSurfaceTextureClientTest : public ::testing::Test {
672
673public:
674    MultiSurfaceTextureClientTest() :
675            mEglDisplay(EGL_NO_DISPLAY),
676            mEglContext(EGL_NO_CONTEXT) {
677        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
678            mEglSurfaces[i] = EGL_NO_CONTEXT;
679        }
680    }
681
682protected:
683
684    enum { NUM_SURFACE_TEXTURES = 32 };
685
686    virtual void SetUp() {
687        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
688        ASSERT_EQ(EGL_SUCCESS, eglGetError());
689        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
690
691        EGLint majorVersion, minorVersion;
692        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
693        ASSERT_EQ(EGL_SUCCESS, eglGetError());
694
695        EGLConfig myConfig;
696        EGLint numConfigs = 0;
697        EGLint configAttribs[] = {
698            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
699            EGL_NONE
700        };
701        EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1,
702                &numConfigs));
703        ASSERT_EQ(EGL_SUCCESS, eglGetError());
704
705        mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
706                0);
707        ASSERT_EQ(EGL_SUCCESS, eglGetError());
708        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
709
710        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
711            sp<BufferQueue> bq = new BufferQueue();
712            sp<GLConsumer> st(new GLConsumer(bq, i));
713            sp<Surface> stc(new Surface(bq));
714            mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
715                    static_cast<ANativeWindow*>(stc.get()), NULL);
716            ASSERT_EQ(EGL_SUCCESS, eglGetError());
717            ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]);
718        }
719    }
720
721    virtual void TearDown() {
722        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
723                EGL_NO_CONTEXT);
724
725        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
726            if (mEglSurfaces[i] != EGL_NO_SURFACE) {
727                eglDestroySurface(mEglDisplay, mEglSurfaces[i]);
728            }
729        }
730
731        if (mEglContext != EGL_NO_CONTEXT) {
732            eglDestroyContext(mEglDisplay, mEglContext);
733        }
734
735        if (mEglDisplay != EGL_NO_DISPLAY) {
736            eglTerminate(mEglDisplay);
737        }
738    }
739
740    EGLDisplay mEglDisplay;
741    EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES];
742    EGLContext mEglContext;
743};
744
745// XXX: This test is disabled because it causes a hang on some devices.  See bug
746// 5015672.
747TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) {
748    for (int iter = 0; iter < 8; iter++) {
749        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
750            eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i],
751                    mEglContext);
752            glClear(GL_COLOR_BUFFER_BIT);
753            eglSwapBuffers(mEglDisplay, mEglSurfaces[i]);
754        }
755    }
756}
757
758} // namespace android
759