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