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