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