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