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 "SurfaceTextureGL_test" 18 //#define LOG_NDEBUG 0 19 20 #include "SurfaceTextureGL.h" 21 22 #include "DisconnectWaiter.h" 23 #include "FillBuffer.h" 24 25 namespace android { 26 27 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) { 28 const int texWidth = 64; 29 const int texHeight = 66; 30 31 ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), 32 NATIVE_WINDOW_API_CPU)); 33 ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), 34 texWidth, texHeight)); 35 ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), 36 HAL_PIXEL_FORMAT_YV12)); 37 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 38 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 39 40 ANativeWindowBuffer* anb; 41 ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 42 &anb)); 43 ASSERT_TRUE(anb != NULL); 44 45 sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); 46 47 // Fill the buffer with the a checkerboard pattern 48 uint8_t* img = NULL; 49 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 50 fillYV12Buffer(img, texWidth, texHeight, buf->getStride()); 51 buf->unlock(); 52 ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), 53 -1)); 54 55 ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 56 57 glClearColor(0.2, 0.2, 0.2, 0.2); 58 glClear(GL_COLOR_BUFFER_BIT); 59 60 glViewport(0, 0, texWidth, texHeight); 61 drawTexture(); 62 63 EXPECT_TRUE(checkPixel( 0, 0, 255, 127, 255, 255, 3)); 64 EXPECT_TRUE(checkPixel(63, 0, 0, 133, 0, 255, 3)); 65 EXPECT_TRUE(checkPixel(63, 65, 0, 133, 0, 255, 3)); 66 EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255, 3)); 67 68 EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255, 3)); 69 EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255, 3)); 70 EXPECT_TRUE(checkPixel(52, 51, 98, 255, 73, 255, 3)); 71 EXPECT_TRUE(checkPixel( 7, 31, 155, 0, 118, 255, 3)); 72 EXPECT_TRUE(checkPixel(31, 9, 107, 24, 87, 255, 3)); 73 EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255, 3)); 74 EXPECT_TRUE(checkPixel(36, 22, 155, 29, 0, 255, 3)); 75 } 76 77 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) { 78 const int texWidth = 64; 79 const int texHeight = 64; 80 81 ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), 82 NATIVE_WINDOW_API_CPU)); 83 ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), 84 texWidth, texHeight)); 85 ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), 86 HAL_PIXEL_FORMAT_YV12)); 87 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 88 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 89 90 ANativeWindowBuffer* anb; 91 ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 92 &anb)); 93 ASSERT_TRUE(anb != NULL); 94 95 sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); 96 97 // Fill the buffer with the a checkerboard pattern 98 uint8_t* img = NULL; 99 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 100 fillYV12Buffer(img, texWidth, texHeight, buf->getStride()); 101 buf->unlock(); 102 ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), 103 -1)); 104 105 ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 106 107 glClearColor(0.2, 0.2, 0.2, 0.2); 108 glClear(GL_COLOR_BUFFER_BIT); 109 110 glViewport(0, 0, texWidth, texHeight); 111 drawTexture(); 112 113 EXPECT_TRUE(checkPixel( 0, 0, 0, 133, 0, 255)); 114 EXPECT_TRUE(checkPixel(63, 0, 255, 127, 255, 255)); 115 EXPECT_TRUE(checkPixel(63, 63, 0, 133, 0, 255)); 116 EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255)); 117 118 EXPECT_TRUE(checkPixel(22, 19, 100, 255, 74, 255, 3)); 119 EXPECT_TRUE(checkPixel(45, 11, 100, 255, 74, 255, 3)); 120 EXPECT_TRUE(checkPixel(52, 12, 155, 0, 181, 255, 3)); 121 EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255, 3)); 122 EXPECT_TRUE(checkPixel(31, 54, 0, 71, 117, 255, 3)); 123 EXPECT_TRUE(checkPixel(29, 28, 0, 133, 0, 255, 3)); 124 EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255, 3)); 125 } 126 127 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) { 128 const int texWidth = 64; 129 const int texHeight = 66; 130 131 ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), 132 NATIVE_WINDOW_API_CPU)); 133 ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), 134 texWidth, texHeight)); 135 ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), 136 HAL_PIXEL_FORMAT_YV12)); 137 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 138 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 139 140 android_native_rect_t crops[] = { 141 {4, 6, 22, 36}, 142 {0, 6, 22, 36}, 143 {4, 0, 22, 36}, 144 {4, 6, texWidth, 36}, 145 {4, 6, 22, texHeight}, 146 }; 147 148 for (int i = 0; i < 5; i++) { 149 const android_native_rect_t& crop(crops[i]); 150 SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", 151 crop.left, crop.top, crop.right, crop.bottom).string()); 152 153 ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop)); 154 155 ANativeWindowBuffer* anb; 156 ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 157 &anb)); 158 ASSERT_TRUE(anb != NULL); 159 160 sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); 161 162 uint8_t* img = NULL; 163 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 164 fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop); 165 buf->unlock(); 166 ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), 167 buf->getNativeBuffer(), -1)); 168 169 ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 170 171 glClearColor(0.2, 0.2, 0.2, 0.2); 172 glClear(GL_COLOR_BUFFER_BIT); 173 174 glViewport(0, 0, 64, 64); 175 drawTexture(); 176 177 EXPECT_TRUE(checkPixel( 0, 0, 82, 255, 35, 255)); 178 EXPECT_TRUE(checkPixel(63, 0, 82, 255, 35, 255)); 179 EXPECT_TRUE(checkPixel(63, 63, 82, 255, 35, 255)); 180 EXPECT_TRUE(checkPixel( 0, 63, 82, 255, 35, 255)); 181 182 EXPECT_TRUE(checkPixel(25, 14, 82, 255, 35, 255)); 183 EXPECT_TRUE(checkPixel(35, 31, 82, 255, 35, 255)); 184 EXPECT_TRUE(checkPixel(57, 6, 82, 255, 35, 255)); 185 EXPECT_TRUE(checkPixel( 5, 42, 82, 255, 35, 255)); 186 EXPECT_TRUE(checkPixel(32, 33, 82, 255, 35, 255)); 187 EXPECT_TRUE(checkPixel(16, 26, 82, 255, 35, 255)); 188 EXPECT_TRUE(checkPixel(46, 51, 82, 255, 35, 255)); 189 } 190 } 191 192 // This test is intended to catch synchronization bugs between the CPU-written 193 // and GPU-read buffers. 194 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) { 195 enum { texWidth = 16 }; 196 enum { texHeight = 16 }; 197 enum { numFrames = 1024 }; 198 199 ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), 200 NATIVE_WINDOW_API_CPU)); 201 ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), 202 texWidth, texHeight)); 203 ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), 204 HAL_PIXEL_FORMAT_YV12)); 205 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 206 GRALLOC_USAGE_SW_WRITE_OFTEN)); 207 208 struct TestPixel { 209 int x; 210 int y; 211 }; 212 const TestPixel testPixels[] = { 213 { 4, 11 }, 214 { 12, 14 }, 215 { 7, 2 }, 216 }; 217 enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])}; 218 219 class ProducerThread : public Thread { 220 public: 221 ProducerThread(const sp<ANativeWindow>& anw, 222 const TestPixel* testPixels): 223 mANW(anw), 224 mTestPixels(testPixels) { 225 } 226 227 virtual ~ProducerThread() { 228 } 229 230 virtual bool threadLoop() { 231 for (int i = 0; i < numFrames; i++) { 232 ANativeWindowBuffer* anb; 233 if (native_window_dequeue_buffer_and_wait(mANW.get(), 234 &anb) != NO_ERROR) { 235 return false; 236 } 237 if (anb == NULL) { 238 return false; 239 } 240 241 sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); 242 243 const int yuvTexOffsetY = 0; 244 int stride = buf->getStride(); 245 int yuvTexStrideY = stride; 246 int yuvTexOffsetV = yuvTexStrideY * texHeight; 247 int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 248 int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2; 249 int yuvTexStrideU = yuvTexStrideV; 250 251 uint8_t* img = NULL; 252 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 253 254 // Gray out all the test pixels first, so we're more likely to 255 // see a failure if GL is still texturing from the buffer we 256 // just dequeued. 257 for (int j = 0; j < numTestPixels; j++) { 258 int x = mTestPixels[j].x; 259 int y = mTestPixels[j].y; 260 uint8_t value = 128; 261 img[y*stride + x] = value; 262 } 263 264 // Fill the buffer with gray. 265 for (int y = 0; y < texHeight; y++) { 266 for (int x = 0; x < texWidth; x++) { 267 img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128; 268 img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128; 269 img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128; 270 } 271 } 272 273 // Set the test pixels to either white or black. 274 for (int j = 0; j < numTestPixels; j++) { 275 int x = mTestPixels[j].x; 276 int y = mTestPixels[j].y; 277 uint8_t value = 0; 278 if (j == (i % numTestPixels)) { 279 value = 255; 280 } 281 img[y*stride + x] = value; 282 } 283 284 buf->unlock(); 285 if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), -1) 286 != NO_ERROR) { 287 return false; 288 } 289 } 290 return false; 291 } 292 293 sp<ANativeWindow> mANW; 294 const TestPixel* mTestPixels; 295 }; 296 297 sp<Thread> pt(new ProducerThread(mANW, testPixels)); 298 pt->run("ProducerThread"); 299 300 glViewport(0, 0, texWidth, texHeight); 301 302 glClearColor(0.2, 0.2, 0.2, 0.2); 303 glClear(GL_COLOR_BUFFER_BIT); 304 305 // We wait for the first two frames up front so that the producer will be 306 // likely to dequeue the buffer that's currently being textured from. 307 mFW->waitForFrame(); 308 mFW->waitForFrame(); 309 310 for (int i = 0; i < numFrames; i++) { 311 SCOPED_TRACE(String8::format("frame %d", i).string()); 312 313 // We must wait for each frame to come in because if we ever do an 314 // updateTexImage call that doesn't consume a newly available buffer 315 // then the producer and consumer will get out of sync, which will cause 316 // a deadlock. 317 if (i > 1) { 318 mFW->waitForFrame(); 319 } 320 ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 321 drawTexture(); 322 323 for (int j = 0; j < numTestPixels; j++) { 324 int x = testPixels[j].x; 325 int y = testPixels[j].y; 326 uint8_t value = 0; 327 if (j == (i % numTestPixels)) { 328 // We must y-invert the texture coords 329 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255)); 330 } else { 331 // We must y-invert the texture coords 332 EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255)); 333 } 334 } 335 } 336 337 pt->requestExitAndWait(); 338 } 339 340 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) { 341 const int texWidth = 64; 342 const int texHeight = 66; 343 344 ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), 345 NATIVE_WINDOW_API_CPU)); 346 ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), 347 texWidth, texHeight)); 348 ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), 349 HAL_PIXEL_FORMAT_RGBA_8888)); 350 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 351 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 352 353 ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 354 355 ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 356 357 glClearColor(0.2, 0.2, 0.2, 0.2); 358 glClear(GL_COLOR_BUFFER_BIT); 359 360 glViewport(0, 0, texWidth, texHeight); 361 drawTexture(); 362 363 EXPECT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35)); 364 EXPECT_TRUE(checkPixel(63, 0, 231, 231, 231, 231)); 365 EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231)); 366 EXPECT_TRUE(checkPixel( 0, 65, 35, 35, 35, 35)); 367 368 EXPECT_TRUE(checkPixel(15, 10, 35, 231, 231, 231)); 369 EXPECT_TRUE(checkPixel(23, 65, 231, 35, 231, 35)); 370 EXPECT_TRUE(checkPixel(19, 40, 35, 231, 35, 35)); 371 EXPECT_TRUE(checkPixel(38, 30, 231, 35, 35, 35)); 372 EXPECT_TRUE(checkPixel(42, 54, 35, 35, 35, 231)); 373 EXPECT_TRUE(checkPixel(37, 34, 35, 231, 231, 231)); 374 EXPECT_TRUE(checkPixel(31, 8, 231, 35, 35, 231)); 375 EXPECT_TRUE(checkPixel(37, 47, 231, 35, 231, 231)); 376 EXPECT_TRUE(checkPixel(25, 38, 35, 35, 35, 35)); 377 EXPECT_TRUE(checkPixel(49, 6, 35, 231, 35, 35)); 378 EXPECT_TRUE(checkPixel(54, 50, 35, 231, 231, 231)); 379 EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231)); 380 EXPECT_TRUE(checkPixel(10, 6, 35, 35, 231, 231)); 381 EXPECT_TRUE(checkPixel(29, 4, 35, 35, 35, 231)); 382 EXPECT_TRUE(checkPixel(55, 28, 35, 35, 231, 35)); 383 EXPECT_TRUE(checkPixel(58, 55, 35, 35, 231, 231)); 384 } 385 386 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) { 387 const int texWidth = 64; 388 const int texHeight = 64; 389 390 ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), 391 NATIVE_WINDOW_API_CPU)); 392 ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(), 393 texWidth, texHeight)); 394 ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(), 395 HAL_PIXEL_FORMAT_RGBA_8888)); 396 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 397 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 398 399 ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 400 401 ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 402 403 glClearColor(0.2, 0.2, 0.2, 0.2); 404 glClear(GL_COLOR_BUFFER_BIT); 405 406 glViewport(0, 0, texWidth, texHeight); 407 drawTexture(); 408 409 EXPECT_TRUE(checkPixel( 0, 0, 231, 231, 231, 231)); 410 EXPECT_TRUE(checkPixel(63, 0, 35, 35, 35, 35)); 411 EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231)); 412 EXPECT_TRUE(checkPixel( 0, 63, 35, 35, 35, 35)); 413 414 EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231, 35)); 415 EXPECT_TRUE(checkPixel(16, 1, 231, 231, 35, 231)); 416 EXPECT_TRUE(checkPixel(21, 12, 231, 35, 35, 231)); 417 EXPECT_TRUE(checkPixel(26, 51, 231, 35, 231, 35)); 418 EXPECT_TRUE(checkPixel( 5, 32, 35, 231, 231, 35)); 419 EXPECT_TRUE(checkPixel(13, 8, 35, 231, 231, 231)); 420 EXPECT_TRUE(checkPixel(46, 3, 35, 35, 231, 35)); 421 EXPECT_TRUE(checkPixel(30, 33, 35, 35, 35, 35)); 422 EXPECT_TRUE(checkPixel( 6, 52, 231, 231, 35, 35)); 423 EXPECT_TRUE(checkPixel(55, 33, 35, 231, 35, 231)); 424 EXPECT_TRUE(checkPixel(16, 29, 35, 35, 231, 231)); 425 EXPECT_TRUE(checkPixel( 1, 30, 35, 35, 35, 231)); 426 EXPECT_TRUE(checkPixel(41, 37, 35, 35, 231, 231)); 427 EXPECT_TRUE(checkPixel(46, 29, 231, 231, 35, 35)); 428 EXPECT_TRUE(checkPixel(15, 25, 35, 231, 35, 231)); 429 EXPECT_TRUE(checkPixel( 3, 52, 35, 231, 35, 35)); 430 } 431 432 // Tests if GLConsumer and BufferQueue are robust enough 433 // to handle a special case where updateTexImage is called 434 // in the middle of disconnect. This ordering is enforced 435 // by blocking in the disconnect callback. 436 TEST_F(SurfaceTextureGLTest, DisconnectStressTest) { 437 438 class ProducerThread : public Thread { 439 public: 440 explicit ProducerThread(const sp<ANativeWindow>& anw): 441 mANW(anw) { 442 } 443 444 virtual ~ProducerThread() { 445 } 446 447 virtual bool threadLoop() { 448 ANativeWindowBuffer* anb; 449 450 if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) != 451 NO_ERROR) { 452 return false; 453 } 454 455 for (int numFrames =0 ; numFrames < 2; numFrames ++) { 456 457 if (native_window_dequeue_buffer_and_wait(mANW.get(), 458 &anb) != NO_ERROR) { 459 return false; 460 } 461 if (anb == NULL) { 462 return false; 463 } 464 if (mANW->queueBuffer(mANW.get(), anb, -1) 465 != NO_ERROR) { 466 return false; 467 } 468 } 469 470 if (native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU) 471 != NO_ERROR) { 472 return false; 473 } 474 475 return false; 476 } 477 478 private: 479 sp<ANativeWindow> mANW; 480 }; 481 482 sp<DisconnectWaiter> dw(new DisconnectWaiter()); 483 mConsumer->consumerConnect(dw, false); 484 485 486 sp<Thread> pt(new ProducerThread(mANW)); 487 pt->run("ProducerThread"); 488 489 // eat a frame so GLConsumer will own an at least one slot 490 dw->waitForFrame(); 491 EXPECT_EQ(OK,mST->updateTexImage()); 492 493 dw->waitForFrame(); 494 // Could fail here as GLConsumer thinks it still owns the slot 495 // but bufferQueue has released all slots 496 EXPECT_EQ(OK,mST->updateTexImage()); 497 498 dw->finishDisconnect(); 499 } 500 501 502 // This test ensures that the GLConsumer clears the mCurrentTexture 503 // when it is disconnected and reconnected. Otherwise it will 504 // attempt to release a buffer that it does not owned 505 TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) { 506 ASSERT_EQ(OK, native_window_api_connect(mANW.get(), 507 NATIVE_WINDOW_API_CPU)); 508 509 ANativeWindowBuffer *anb; 510 511 EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 512 EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 513 514 EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 515 EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 516 517 EXPECT_EQ(OK,mST->updateTexImage()); 518 EXPECT_EQ(OK,mST->updateTexImage()); 519 520 ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(), 521 NATIVE_WINDOW_API_CPU)); 522 ASSERT_EQ(OK, native_window_api_connect(mANW.get(), 523 NATIVE_WINDOW_API_CPU)); 524 525 EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 526 EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 527 528 // Will fail here if mCurrentTexture is not cleared properly 529 mFW->waitForFrame(); 530 EXPECT_EQ(OK,mST->updateTexImage()); 531 532 ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(), 533 NATIVE_WINDOW_API_CPU)); 534 } 535 536 TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) { 537 ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(), 538 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)); 539 540 // The producer image size 541 ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512)); 542 543 // The consumer image size (16 x 9) ratio 544 mST->setDefaultBufferSize(1280, 720); 545 546 ASSERT_EQ(OK, native_window_api_connect(mANW.get(), 547 NATIVE_WINDOW_API_CPU)); 548 549 ANativeWindowBuffer *anb; 550 551 android_native_rect_t odd = {23, 78, 123, 477}; 552 ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &odd)); 553 EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 554 EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 555 mFW->waitForFrame(); 556 EXPECT_EQ(OK, mST->updateTexImage()); 557 Rect r = mST->getCurrentCrop(); 558 assertRectEq(Rect(23, 78, 123, 477), r); 559 560 ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(), 561 NATIVE_WINDOW_API_CPU)); 562 } 563 564 // This test ensures the scaling mode does the right thing 565 // ie NATIVE_WINDOW_SCALING_MODE_CROP should crop 566 // the image such that it has the same aspect ratio as the 567 // default buffer size 568 TEST_F(SurfaceTextureGLTest, CroppedScalingMode) { 569 ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(), 570 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP)); 571 572 // The producer image size 573 ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512)); 574 575 // The consumer image size (16 x 9) ratio 576 mST->setDefaultBufferSize(1280, 720); 577 578 native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU); 579 580 ANativeWindowBuffer *anb; 581 582 // The crop is in the shape of (320, 180) === 16 x 9 583 android_native_rect_t standard = {10, 20, 330, 200}; 584 ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &standard)); 585 EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 586 EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 587 mFW->waitForFrame(); 588 EXPECT_EQ(OK, mST->updateTexImage()); 589 Rect r = mST->getCurrentCrop(); 590 // crop should be the same as crop (same aspect ratio) 591 assertRectEq(Rect(10, 20, 330, 200), r); 592 593 // make this wider then desired aspect 239 x 100 (2.39:1) 594 android_native_rect_t wide = {20, 30, 259, 130}; 595 ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &wide)); 596 EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 597 EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 598 mFW->waitForFrame(); 599 EXPECT_EQ(OK, mST->updateTexImage()); 600 r = mST->getCurrentCrop(); 601 // crop should be the same height, but have cropped left and right borders 602 // offset is 30.6 px L+, R- 603 assertRectEq(Rect(51, 30, 228, 130), r); 604 605 // This image is taller then desired aspect 400 x 300 (4:3) 606 android_native_rect_t narrow = {0, 0, 400, 300}; 607 ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &narrow)); 608 EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 609 EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 610 mFW->waitForFrame(); 611 EXPECT_EQ(OK, mST->updateTexImage()); 612 r = mST->getCurrentCrop(); 613 // crop should be the same width, but have cropped top and bottom borders 614 // offset is 37.5 px 615 assertRectEq(Rect(0, 37, 400, 262), r); 616 617 native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU); 618 } 619 620 TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) { 621 class ProducerThread : public Thread { 622 public: 623 explicit ProducerThread(const sp<ANativeWindow>& anw): 624 mANW(anw), 625 mDequeueError(NO_ERROR) { 626 } 627 628 virtual ~ProducerThread() { 629 } 630 631 virtual bool threadLoop() { 632 Mutex::Autolock lock(mMutex); 633 ANativeWindowBuffer* anb; 634 635 if (native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU) != 636 NO_ERROR) { 637 return false; 638 } 639 640 // Frame 1 641 if (native_window_dequeue_buffer_and_wait(mANW.get(), 642 &anb) != NO_ERROR) { 643 return false; 644 } 645 if (anb == NULL) { 646 return false; 647 } 648 if (mANW->queueBuffer(mANW.get(), anb, -1) 649 != NO_ERROR) { 650 return false; 651 } 652 653 // Frame 2 654 if (native_window_dequeue_buffer_and_wait(mANW.get(), 655 &anb) != NO_ERROR) { 656 return false; 657 } 658 if (anb == NULL) { 659 return false; 660 } 661 if (mANW->queueBuffer(mANW.get(), anb, -1) 662 != NO_ERROR) { 663 return false; 664 } 665 666 // Frame 3 - error expected 667 mDequeueError = native_window_dequeue_buffer_and_wait(mANW.get(), 668 &anb); 669 return false; 670 } 671 672 status_t getDequeueError() { 673 Mutex::Autolock lock(mMutex); 674 return mDequeueError; 675 } 676 677 private: 678 sp<ANativeWindow> mANW; 679 status_t mDequeueError; 680 Mutex mMutex; 681 }; 682 683 sp<Thread> pt(new ProducerThread(mANW)); 684 pt->run("ProducerThread"); 685 686 mFW->waitForFrame(); 687 mFW->waitForFrame(); 688 689 // Sleep for 100ms to allow the producer thread's dequeueBuffer call to 690 // block waiting for a buffer to become available. 691 usleep(100000); 692 693 mST->abandon(); 694 695 pt->requestExitAndWait(); 696 ASSERT_EQ(NO_INIT, 697 reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError()); 698 } 699 700 TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) { 701 int texHeight = 16; 702 ANativeWindowBuffer* anb; 703 704 ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), 705 NATIVE_WINDOW_API_CPU)); 706 707 GLint maxTextureSize; 708 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); 709 710 // make sure it works with small textures 711 mST->setDefaultBufferSize(16, texHeight); 712 EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 713 &anb)); 714 EXPECT_EQ(16, anb->width); 715 EXPECT_EQ(texHeight, anb->height); 716 EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1)); 717 EXPECT_EQ(NO_ERROR, mST->updateTexImage()); 718 719 // make sure it works with GL_MAX_TEXTURE_SIZE 720 mST->setDefaultBufferSize(maxTextureSize, texHeight); 721 EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 722 &anb)); 723 EXPECT_EQ(maxTextureSize, anb->width); 724 EXPECT_EQ(texHeight, anb->height); 725 EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1)); 726 EXPECT_EQ(NO_ERROR, mST->updateTexImage()); 727 728 // make sure it fails with GL_MAX_TEXTURE_SIZE+1 729 mST->setDefaultBufferSize(maxTextureSize+1, texHeight); 730 EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 731 &anb)); 732 EXPECT_EQ(maxTextureSize+1, anb->width); 733 EXPECT_EQ(texHeight, anb->height); 734 EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1)); 735 ASSERT_NE(NO_ERROR, mST->updateTexImage()); 736 } 737 738 } // namespace android 739