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