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