OSDN Git Service

8546fb94b5ad94d4370120f7315318fbd9354387
[android-x86/frameworks-native.git] / libs / gui / tests / SurfaceTextureClient_test.cpp
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
27 namespace android {
28
29 class SurfaceTextureClientTest : public ::testing::Test {
30 protected:
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
114 TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
115     sp<ISurfaceTexture> ist(mSTC->getISurfaceTexture());
116     ASSERT_TRUE(ist != NULL);
117 }
118
119 TEST_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
127 TEST_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
134 TEST_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
172 TEST_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
181 TEST_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
190 TEST_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
200 TEST_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
210 TEST_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
220 TEST_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
236 TEST_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
252 TEST_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
263 TEST_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
283 TEST_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
308 TEST_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
331 TEST_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
352 TEST_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
373 TEST_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.
398 TEST_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
419 TEST_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
445 TEST_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
489 TEST_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.
509 TEST_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
565 TEST_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
595 TEST_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
626 TEST_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.
669 TEST_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
692 class MultiSurfaceTextureClientTest : public ::testing::Test {
693
694 public:
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
703 protected:
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.
767 TEST_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