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