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