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
30 namespace android {
31
32 class SurfaceTextureClientTest : public ::testing::Test {
33 protected:
SurfaceTextureClientTest()34 SurfaceTextureClientTest():
35 mEglDisplay(EGL_NO_DISPLAY),
36 mEglSurface(EGL_NO_SURFACE),
37 mEglContext(EGL_NO_CONTEXT) {
38 }
39
SetUp()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
TearDown()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
getConfigAttribs()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
TEST_F(SurfaceTextureClientTest,GetISurfaceTextureIsNotNull)120 TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
121 sp<IGraphicBufferProducer> ist(mSTC->getIGraphicBufferProducer());
122 ASSERT_TRUE(ist != NULL);
123 }
124
TEST_F(SurfaceTextureClientTest,QueuesToWindowCompositorIsFalse)125 TEST_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
TEST_F(SurfaceTextureClientTest,ConcreteTypeIsSurfaceTextureClient)133 TEST_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
TEST_F(SurfaceTextureClientTest,EglCreateWindowSurfaceSucceeds)140 TEST_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
TEST_F(SurfaceTextureClientTest,EglSwapBuffersAbandonErrorIsEglBadSurface)178 TEST_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
TEST_F(SurfaceTextureClientTest,BufferGeometryInvalidSizesFail)206 TEST_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
TEST_F(SurfaceTextureClientTest,DefaultGeometryValues)215 TEST_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
TEST_F(SurfaceTextureClientTest,BufferGeometryCanBeSet)224 TEST_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
TEST_F(SurfaceTextureClientTest,BufferGeometryDefaultSizeSetFormat)234 TEST_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
TEST_F(SurfaceTextureClientTest,BufferGeometrySetSizeDefaultFormat)244 TEST_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
TEST_F(SurfaceTextureClientTest,BufferGeometrySizeCanBeUnset)254 TEST_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
TEST_F(SurfaceTextureClientTest,BufferGeometrySizeCanBeChangedWithoutFormat)270 TEST_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
TEST_F(SurfaceTextureClientTest,SurfaceTextureSetDefaultSize)286 TEST_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
TEST_F(SurfaceTextureClientTest,SurfaceTextureSetDefaultSizeAfterDequeue)297 TEST_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
TEST_F(SurfaceTextureClientTest,SurfaceTextureSetDefaultSizeVsGeometry)317 TEST_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
TEST_F(SurfaceTextureClientTest,SurfaceTextureTooManyUpdateTexImage)342 TEST_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
TEST_F(SurfaceTextureClientTest,SurfaceTextureSyncModeSlowRetire)365 TEST_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
TEST_F(SurfaceTextureClientTest,SurfaceTextureSyncModeFastRetire)385 TEST_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
TEST_F(SurfaceTextureClientTest,SurfaceTextureSyncModeDQQR)405 TEST_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.
TEST_F(SurfaceTextureClientTest,DISABLED_SurfaceTextureSyncModeDequeueCurrent)429 TEST_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
TEST_F(SurfaceTextureClientTest,SurfaceTextureSyncModeMinUndequeued)449 TEST_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
TEST_F(SurfaceTextureClientTest,SetCropCropsCrop)474 TEST_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.
TEST_F(SurfaceTextureClientTest,DISABLED_SurfaceTextureSyncModeWaitRetire)494 TEST_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
TEST_F(SurfaceTextureClientTest,GetTransformMatrixReturnsVerticalFlip)549 TEST_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
TEST_F(SurfaceTextureClientTest,GetTransformMatrixSucceedsAfterFreeingBuffers)579 TEST_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
TEST_F(SurfaceTextureClientTest,GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop)610 TEST_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.
TEST_F(SurfaceTextureClientTest,QueryFormatAfterSettingWorks)653 TEST_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
674 class MultiSurfaceTextureClientTest : public ::testing::Test {
675
676 public:
MultiSurfaceTextureClientTest()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
685 protected:
686
687 enum { NUM_SURFACE_TEXTURES = 32 };
688
SetUp()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
TearDown()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.
TEST_F(MultiSurfaceTextureClientTest,DISABLED_MakeCurrentBetweenSurfacesWorks)750 TEST_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