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