1/* 2 * Copyright (C) 2012 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 "CpuConsumer_test" 18//#define LOG_NDEBUG 0 19//#define LOG_NNDEBUG 0 20 21#ifdef LOG_NNDEBUG 22#define ALOGVV(...) ALOGV(__VA_ARGS__) 23#else 24#define ALOGVV(...) ((void)0) 25#endif 26 27#include <gtest/gtest.h> 28#include <gui/CpuConsumer.h> 29#include <gui/Surface.h> 30#include <ui/GraphicBuffer.h> 31#include <utils/String8.h> 32#include <utils/Thread.h> 33#include <utils/Mutex.h> 34#include <utils/Condition.h> 35 36#include <thread> 37#include <vector> 38#define CPU_CONSUMER_TEST_FORMAT_RAW 0 39#define CPU_CONSUMER_TEST_FORMAT_Y8 0 40#define CPU_CONSUMER_TEST_FORMAT_Y16 0 41#define CPU_CONSUMER_TEST_FORMAT_RGBA_8888 1 42 43namespace android { 44 45struct CpuConsumerTestParams { 46 uint32_t width; 47 uint32_t height; 48 int maxLockedBuffers; 49 PixelFormat format; 50}; 51 52::std::ostream& operator<<(::std::ostream& os, const CpuConsumerTestParams& p) { 53 return os << "[ (" << p.width << ", " << p.height << "), B:" 54 << p.maxLockedBuffers << ", F:0x" 55 << ::std::hex << p.format << "]"; 56} 57 58class CpuConsumerTest : public ::testing::TestWithParam<CpuConsumerTestParams> { 59protected: 60 61 virtual void SetUp() { 62 const ::testing::TestInfo* const test_info = 63 ::testing::UnitTest::GetInstance()->current_test_info(); 64 CpuConsumerTestParams params = GetParam(); 65 ALOGV("** Starting test %s (%d x %d, %d, 0x%x)", 66 test_info->name(), 67 params.width, params.height, 68 params.maxLockedBuffers, params.format); 69 sp<IGraphicBufferProducer> producer; 70 sp<IGraphicBufferConsumer> consumer; 71 BufferQueue::createBufferQueue(&producer, &consumer); 72 mCC = new CpuConsumer(consumer, params.maxLockedBuffers); 73 String8 name("CpuConsumer_Under_Test"); 74 mCC->setName(name); 75 mSTC = new Surface(producer); 76 mANW = mSTC; 77 } 78 79 virtual void TearDown() { 80 mANW.clear(); 81 mSTC.clear(); 82 mCC.clear(); 83 } 84 85 class FrameWaiter : public CpuConsumer::FrameAvailableListener { 86 public: 87 FrameWaiter(): 88 mPendingFrames(0) { 89 } 90 91 void waitForFrame() { 92 Mutex::Autolock lock(mMutex); 93 while (mPendingFrames == 0) { 94 mCondition.wait(mMutex); 95 } 96 mPendingFrames--; 97 } 98 99 virtual void onFrameAvailable(const BufferItem&) { 100 Mutex::Autolock lock(mMutex); 101 mPendingFrames++; 102 mCondition.signal(); 103 } 104 105 int mPendingFrames; 106 Mutex mMutex; 107 Condition mCondition; 108 }; 109 110 // Note that SurfaceTexture will lose the notifications 111 // onBuffersReleased and onFrameAvailable as there is currently 112 // no way to forward the events. This DisconnectWaiter will not let the 113 // disconnect finish until finishDisconnect() is called. It will 114 // also block until a disconnect is called 115 class DisconnectWaiter : public BufferQueue::ConsumerListener { 116 public: 117 DisconnectWaiter () : 118 mWaitForDisconnect(false), 119 mPendingFrames(0) { 120 } 121 122 void waitForFrame() { 123 Mutex::Autolock lock(mMutex); 124 while (mPendingFrames == 0) { 125 mFrameCondition.wait(mMutex); 126 } 127 mPendingFrames--; 128 } 129 130 virtual void onFrameAvailable(const BufferItem&) { 131 Mutex::Autolock lock(mMutex); 132 mPendingFrames++; 133 mFrameCondition.signal(); 134 } 135 136 virtual void onBuffersReleased() { 137 Mutex::Autolock lock(mMutex); 138 while (!mWaitForDisconnect) { 139 mDisconnectCondition.wait(mMutex); 140 } 141 } 142 143 void finishDisconnect() { 144 Mutex::Autolock lock(mMutex); 145 mWaitForDisconnect = true; 146 mDisconnectCondition.signal(); 147 } 148 149 private: 150 Mutex mMutex; 151 152 bool mWaitForDisconnect; 153 Condition mDisconnectCondition; 154 155 int mPendingFrames; 156 Condition mFrameCondition; 157 }; 158 159 sp<CpuConsumer> mCC; 160 sp<Surface> mSTC; 161 sp<ANativeWindow> mANW; 162}; 163 164#define ASSERT_NO_ERROR(err, msg) \ 165 ASSERT_EQ(NO_ERROR, err) << (msg) << strerror(-(err)) 166 167void checkPixel(const CpuConsumer::LockedBuffer &buf, 168 uint32_t x, uint32_t y, uint32_t r, uint32_t g=0, uint32_t b=0) { 169 // Ignores components that don't exist for given pixel 170 switch(buf.format) { 171 case HAL_PIXEL_FORMAT_RAW16: { 172 String8 msg; 173 uint16_t *bPtr = (uint16_t*)buf.data; 174 bPtr += y * buf.stride + x; 175 // GRBG Bayer mosaic; only check the matching channel 176 switch( ((y & 1) << 1) | (x & 1) ) { 177 case 0: // G 178 case 3: // G 179 EXPECT_EQ(g, *bPtr); 180 break; 181 case 1: // R 182 EXPECT_EQ(r, *bPtr); 183 break; 184 case 2: // B 185 EXPECT_EQ(b, *bPtr); 186 break; 187 } 188 break; 189 } 190 // ignores g,b 191 case HAL_PIXEL_FORMAT_Y8: { 192 uint8_t *bPtr = (uint8_t*)buf.data; 193 bPtr += y * buf.stride + x; 194 EXPECT_EQ(r, *bPtr) << "at x = " << x << " y = " << y; 195 break; 196 } 197 // ignores g,b 198 case HAL_PIXEL_FORMAT_Y16: { 199 // stride is in pixels, not in bytes 200 uint16_t *bPtr = ((uint16_t*)buf.data) + y * buf.stride + x; 201 202 EXPECT_EQ(r, *bPtr) << "at x = " << x << " y = " << y; 203 break; 204 } 205 case HAL_PIXEL_FORMAT_RGBA_8888: { 206 const int bytesPerPixel = 4; 207 uint8_t *bPtr = (uint8_t*)buf.data; 208 bPtr += (y * buf.stride + x) * bytesPerPixel; 209 210 EXPECT_EQ(r, bPtr[0]) << "at x = " << x << " y = " << y; 211 EXPECT_EQ(g, bPtr[1]) << "at x = " << x << " y = " << y; 212 EXPECT_EQ(b, bPtr[2]) << "at x = " << x << " y = " << y; 213 break; 214 } 215 default: { 216 ADD_FAILURE() << "Unknown format for check:" << buf.format; 217 break; 218 } 219 } 220} 221 222// Fill a YV12 buffer with a multi-colored checkerboard pattern 223void fillYV12Buffer(uint8_t* buf, int w, int h, int stride); 224 225// Fill a Y8/Y16 buffer with a multi-colored checkerboard pattern 226template <typename T> // T == uint8_t or uint16_t 227void fillGreyscaleBuffer(T* buf, int w, int h, int stride, int bpp) { 228 const int blockWidth = w > 16 ? w / 16 : 1; 229 const int blockHeight = h > 16 ? h / 16 : 1; 230 const int yuvTexOffsetY = 0; 231 232 ASSERT_TRUE(bpp == 8 || bpp == 16); 233 ASSERT_TRUE(sizeof(T)*8 == bpp); 234 235 // stride is in pixels, not in bytes 236 int yuvTexStrideY = stride; 237 for (int x = 0; x < w; x++) { 238 for (int y = 0; y < h; y++) { 239 int parityX = (x / blockWidth) & 1; 240 int parityY = (y / blockHeight) & 1; 241 T intensity = (parityX ^ parityY) ? 63 : 191; 242 buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity; 243 } 244 } 245} 246 247inline uint8_t chooseColorRgba8888(int blockX, int blockY, uint8_t channel) { 248 const int colorVariations = 3; 249 uint8_t color = ((blockX % colorVariations) + (blockY % colorVariations)) 250 % (colorVariations) == channel ? 191: 63; 251 252 return color; 253} 254 255// Fill a RGBA8888 buffer with a multi-colored checkerboard pattern 256void fillRgba8888Buffer(uint8_t* buf, int w, int h, int stride) 257{ 258 const int blockWidth = w > 16 ? w / 16 : 1; 259 const int blockHeight = h > 16 ? h / 16 : 1; 260 const int bytesPerPixel = 4; 261 262 // stride is in pixels, not in bytes 263 for (int x = 0; x < w; ++x) { 264 for (int y = 0; y < h; ++y) { 265 int blockX = (x / blockWidth); 266 int blockY = (y / blockHeight); 267 268 uint8_t r = chooseColorRgba8888(blockX, blockY, 0); 269 uint8_t g = chooseColorRgba8888(blockX, blockY, 1); 270 uint8_t b = chooseColorRgba8888(blockX, blockY, 2); 271 272 buf[(y*stride + x)*bytesPerPixel + 0] = r; 273 buf[(y*stride + x)*bytesPerPixel + 1] = g; 274 buf[(y*stride + x)*bytesPerPixel + 2] = b; 275 buf[(y*stride + x)*bytesPerPixel + 3] = 255; 276 } 277 } 278} 279 280// Fill a RAW sensor buffer with a multi-colored checkerboard pattern. 281// Assumes GRBG mosaic ordering. Result should be a grid in a 2x2 pattern 282// of [ R, B; G, W] 283void fillBayerRawBuffer(uint8_t* buf, int w, int h, int stride) { 284 ALOGVV("fillBayerRawBuffer: %p with %d x %d, stride %d", buf, w, h ,stride); 285 // Blocks need to be even-width/height, aim for 8-wide otherwise 286 const int blockWidth = (w > 16 ? w / 8 : 2) & ~0x1; 287 const int blockHeight = (h > 16 ? h / 8 : 2) & ~0x1; 288 for (int y = 0; y < h; y+=2) { 289 uint16_t *bPtr1 = ((uint16_t*)buf) + stride*y; 290 uint16_t *bPtr2 = bPtr1 + stride; 291 for (int x = 0; x < w; x+=2) { 292 int blockX = (x / blockWidth ) & 1; 293 int blockY = (y / blockHeight) & 1; 294 unsigned short r = (blockX == blockY) ? 1000 : 200; 295 unsigned short g = blockY ? 1000: 200; 296 unsigned short b = blockX ? 1000: 200; 297 // GR row 298 *bPtr1++ = g; 299 *bPtr1++ = r; 300 // BG row 301 *bPtr2++ = b; 302 *bPtr2++ = g; 303 } 304 } 305 306} 307 308template<typename T> // uint8_t or uint16_t 309void checkGreyscaleBuffer(const CpuConsumer::LockedBuffer &buf) { 310 uint32_t w = buf.width; 311 uint32_t h = buf.height; 312 const int blockWidth = w > 16 ? w / 16 : 1; 313 const int blockHeight = h > 16 ? h / 16 : 1; 314 315 // Top-left square is bright 316 checkPixel(buf, 0, 0, 191); 317 checkPixel(buf, 1, 0, 191); 318 checkPixel(buf, 0, 1, 191); 319 checkPixel(buf, 1, 1, 191); 320 321 // One-right square is dark 322 checkPixel(buf, blockWidth, 0, 63); 323 checkPixel(buf, blockWidth + 1, 0, 63); 324 checkPixel(buf, blockWidth, 1, 63); 325 checkPixel(buf, blockWidth + 1, 1, 63); 326 327 // One-down square is dark 328 checkPixel(buf, 0, blockHeight, 63); 329 checkPixel(buf, 1, blockHeight, 63); 330 checkPixel(buf, 0, blockHeight + 1, 63); 331 checkPixel(buf, 1, blockHeight + 1, 63); 332 333 // One-diag square is bright 334 checkPixel(buf, blockWidth, blockHeight, 191); 335 checkPixel(buf, blockWidth + 1, blockHeight, 191); 336 checkPixel(buf, blockWidth, blockHeight + 1, 191); 337 checkPixel(buf, blockWidth + 1, blockHeight + 1, 191); 338 339 // Test bottom-right pixel 340 const int maxBlockX = ((w-1 + (blockWidth-1)) / blockWidth) & 0x1; 341 const int maxBlockY = ((h-1 + (blockHeight-1)) / blockHeight) & 0x1; 342 uint32_t pixelValue = ((maxBlockX % 2) == (maxBlockY % 2)) ? 191 : 63; 343 checkPixel(buf, w-1, h-1, pixelValue); 344} 345 346void checkRgba8888Buffer(const CpuConsumer::LockedBuffer &buf) { 347 uint32_t w = buf.width; 348 uint32_t h = buf.height; 349 const int blockWidth = w > 16 ? w / 16 : 1; 350 const int blockHeight = h > 16 ? h / 16 : 1; 351 352 // Top-left square is bright red 353 checkPixel(buf, 0, 0, 191, 63, 63); 354 checkPixel(buf, 1, 0, 191, 63, 63); 355 checkPixel(buf, 0, 1, 191, 63, 63); 356 checkPixel(buf, 1, 1, 191, 63, 63); 357 358 // One-right square is bright green 359 checkPixel(buf, blockWidth, 0, 63, 191, 63); 360 checkPixel(buf, blockWidth + 1, 0, 63, 191, 63); 361 checkPixel(buf, blockWidth, 1, 63, 191, 63); 362 checkPixel(buf, blockWidth + 1, 1, 63, 191, 63); 363 364 // One-down square is bright green 365 checkPixel(buf, 0, blockHeight, 63, 191, 63); 366 checkPixel(buf, 1, blockHeight, 63, 191, 63); 367 checkPixel(buf, 0, blockHeight + 1, 63, 191, 63); 368 checkPixel(buf, 1, blockHeight + 1, 63, 191, 63); 369 370 // One-diag square is bright blue 371 checkPixel(buf, blockWidth, blockHeight, 63, 63, 191); 372 checkPixel(buf, blockWidth + 1, blockHeight, 63, 63, 191); 373 checkPixel(buf, blockWidth, blockHeight + 1, 63, 63, 191); 374 checkPixel(buf, blockWidth + 1, blockHeight + 1, 63, 63, 191); 375 376 // Test bottom-right pixel 377 { 378 const int maxBlockX = ((w-1) / blockWidth); 379 const int maxBlockY = ((h-1) / blockHeight); 380 uint8_t r = chooseColorRgba8888(maxBlockX, maxBlockY, 0); 381 uint8_t g = chooseColorRgba8888(maxBlockX, maxBlockY, 1); 382 uint8_t b = chooseColorRgba8888(maxBlockX, maxBlockY, 2); 383 checkPixel(buf, w-1, h-1, r, g, b); 384 } 385} 386 387void checkBayerRawBuffer(const CpuConsumer::LockedBuffer &buf) { 388 uint32_t w = buf.width; 389 uint32_t h = buf.height; 390 const int blockWidth = (w > 16 ? w / 8 : 2) & ~0x1; 391 const int blockHeight = (h > 16 ? h / 8 : 2) & ~0x1; 392 393 // Top-left square is red 394 checkPixel(buf, 0, 0, 1000, 200, 200); 395 checkPixel(buf, 1, 0, 1000, 200, 200); 396 checkPixel(buf, 0, 1, 1000, 200, 200); 397 checkPixel(buf, 1, 1, 1000, 200, 200); 398 399 // One-right square is blue 400 checkPixel(buf, blockWidth, 0, 200, 200, 1000); 401 checkPixel(buf, blockWidth + 1, 0, 200, 200, 1000); 402 checkPixel(buf, blockWidth, 1, 200, 200, 1000); 403 checkPixel(buf, blockWidth + 1, 1, 200, 200, 1000); 404 405 // One-down square is green 406 checkPixel(buf, 0, blockHeight, 200, 1000, 200); 407 checkPixel(buf, 1, blockHeight, 200, 1000, 200); 408 checkPixel(buf, 0, blockHeight + 1, 200, 1000, 200); 409 checkPixel(buf, 1, blockHeight + 1, 200, 1000, 200); 410 411 // One-diag square is white 412 checkPixel(buf, blockWidth, blockHeight, 1000, 1000, 1000); 413 checkPixel(buf, blockWidth + 1, blockHeight, 1000, 1000, 1000); 414 checkPixel(buf, blockWidth, blockHeight + 1, 1000, 1000, 1000); 415 checkPixel(buf, blockWidth + 1, blockHeight + 1, 1000, 1000, 1000); 416 417 // Test bottom-right pixel 418 const int maxBlockX = ((w-1) / blockWidth) & 0x1; 419 const int maxBlockY = ((w-1) / blockHeight) & 0x1; 420 unsigned short maxR = (maxBlockX == maxBlockY) ? 1000 : 200; 421 unsigned short maxG = maxBlockY ? 1000: 200; 422 unsigned short maxB = maxBlockX ? 1000: 200; 423 checkPixel(buf, w-1, h-1, maxR, maxG, maxB); 424} 425 426void checkAnyBuffer(const CpuConsumer::LockedBuffer &buf, int format) { 427 switch (format) { 428 case HAL_PIXEL_FORMAT_RAW16: 429 checkBayerRawBuffer(buf); 430 break; 431 case HAL_PIXEL_FORMAT_Y8: 432 checkGreyscaleBuffer<uint8_t>(buf); 433 break; 434 case HAL_PIXEL_FORMAT_Y16: 435 checkGreyscaleBuffer<uint16_t>(buf); 436 break; 437 case HAL_PIXEL_FORMAT_RGBA_8888: 438 checkRgba8888Buffer(buf); 439 break; 440 } 441} 442 443// Configures the ANativeWindow producer-side interface based on test parameters 444void configureANW(const sp<ANativeWindow>& anw, 445 const CpuConsumerTestParams& params, 446 int maxBufferSlack) { 447 status_t err; 448 err = native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU); 449 ASSERT_NO_ERROR(err, "connect error: "); 450 451 err = native_window_set_buffers_dimensions(anw.get(), 452 params.width, params.height); 453 ASSERT_NO_ERROR(err, "set_buffers_dimensions error: "); 454 455 err = native_window_set_buffers_format(anw.get(), params.format); 456 ASSERT_NO_ERROR(err, "set_buffers_format error: "); 457 458 err = native_window_set_usage(anw.get(), 459 GRALLOC_USAGE_SW_WRITE_OFTEN); 460 ASSERT_NO_ERROR(err, "set_usage error: "); 461 462 int minUndequeuedBuffers; 463 err = anw.get()->query(anw.get(), 464 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 465 &minUndequeuedBuffers); 466 ASSERT_NO_ERROR(err, "query error: "); 467 468 ALOGVV("Setting buffer count to %d", 469 maxBufferSlack + 1 + minUndequeuedBuffers); 470 err = native_window_set_buffer_count(anw.get(), 471 maxBufferSlack + 1 + minUndequeuedBuffers); 472 ASSERT_NO_ERROR(err, "set_buffer_count error: "); 473 474} 475 476// Produce one frame of image data; assumes format and resolution configuration 477// is already done. 478void produceOneFrame(const sp<ANativeWindow>& anw, 479 const CpuConsumerTestParams& params, 480 int64_t timestamp, uint32_t *stride) { 481 status_t err; 482 ANativeWindowBuffer* anb; 483 ALOGVV("Dequeue buffer from %p", anw.get()); 484 err = native_window_dequeue_buffer_and_wait(anw.get(), &anb); 485 ASSERT_NO_ERROR(err, "dequeueBuffer error: "); 486 487 ASSERT_TRUE(anb != NULL); 488 489 sp<GraphicBuffer> buf(GraphicBuffer::from(anb)); 490 491 *stride = buf->getStride(); 492 uint8_t* img = NULL; 493 494 ALOGVV("Lock buffer from %p for write", anw.get()); 495 err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 496 ASSERT_NO_ERROR(err, "lock error: "); 497 498 switch (params.format) { 499 case HAL_PIXEL_FORMAT_YV12: 500 fillYV12Buffer(img, params.width, params.height, *stride); 501 break; 502 case HAL_PIXEL_FORMAT_RAW16: 503 fillBayerRawBuffer(img, params.width, params.height, buf->getStride()); 504 break; 505 case HAL_PIXEL_FORMAT_Y8: 506 fillGreyscaleBuffer<uint8_t>(img, params.width, params.height, 507 buf->getStride(), /*bpp*/8); 508 break; 509 case HAL_PIXEL_FORMAT_Y16: 510 fillGreyscaleBuffer<uint16_t>((uint16_t*)img, params.width, 511 params.height, buf->getStride(), 512 /*bpp*/16); 513 break; 514 case HAL_PIXEL_FORMAT_RGBA_8888: 515 fillRgba8888Buffer(img, params.width, params.height, buf->getStride()); 516 break; 517 default: 518 FAIL() << "Unknown pixel format under test!"; 519 break; 520 } 521 ALOGVV("Unlock buffer from %p", anw.get()); 522 err = buf->unlock(); 523 ASSERT_NO_ERROR(err, "unlock error: "); 524 525 ALOGVV("Set timestamp to %p", anw.get()); 526 err = native_window_set_buffers_timestamp(anw.get(), timestamp); 527 ASSERT_NO_ERROR(err, "set_buffers_timestamp error: "); 528 529 ALOGVV("Queue buffer to %p", anw.get()); 530 err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), -1); 531 ASSERT_NO_ERROR(err, "queueBuffer error:"); 532}; 533 534// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not 535// supported on all devices. 536TEST_P(CpuConsumerTest, FromCpuSingle) { 537 status_t err; 538 CpuConsumerTestParams params = GetParam(); 539 540 // Set up 541 542 ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, 1)); 543 544 // Produce 545 546 const int64_t time = 12345678L; 547 uint32_t stride; 548 ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time, 549 &stride)); 550 551 // Consume 552 553 CpuConsumer::LockedBuffer b; 554 err = mCC->lockNextBuffer(&b); 555 ASSERT_NO_ERROR(err, "getNextBuffer error: "); 556 557 ASSERT_TRUE(b.data != NULL); 558 EXPECT_EQ(params.width, b.width); 559 EXPECT_EQ(params.height, b.height); 560 EXPECT_EQ(params.format, b.format); 561 EXPECT_EQ(stride, b.stride); 562 EXPECT_EQ(time, b.timestamp); 563 564 checkAnyBuffer(b, GetParam().format); 565 mCC->unlockBuffer(b); 566} 567 568// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not 569// supported on all devices. 570TEST_P(CpuConsumerTest, FromCpuManyInQueue) { 571 status_t err; 572 CpuConsumerTestParams params = GetParam(); 573 574 const int numInQueue = 5; 575 // Set up 576 577 ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, numInQueue)); 578 579 // Produce 580 581 const int64_t time[numInQueue] = { 1L, 2L, 3L, 4L, 5L}; 582 uint32_t stride[numInQueue]; 583 584 for (int i = 0; i < numInQueue; i++) { 585 ALOGV("Producing frame %d", i); 586 ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time[i], 587 &stride[i])); 588 } 589 590 // Consume 591 592 for (int i = 0; i < numInQueue; i++) { 593 ALOGV("Consuming frame %d", i); 594 CpuConsumer::LockedBuffer b; 595 err = mCC->lockNextBuffer(&b); 596 ASSERT_NO_ERROR(err, "getNextBuffer error: "); 597 598 ASSERT_TRUE(b.data != NULL); 599 EXPECT_EQ(params.width, b.width); 600 EXPECT_EQ(params.height, b.height); 601 EXPECT_EQ(params.format, b.format); 602 EXPECT_EQ(stride[i], b.stride); 603 EXPECT_EQ(time[i], b.timestamp); 604 605 checkAnyBuffer(b, GetParam().format); 606 607 mCC->unlockBuffer(b); 608 } 609} 610 611// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not 612// supported on all devices. 613TEST_P(CpuConsumerTest, FromCpuLockMax) { 614 status_t err; 615 CpuConsumerTestParams params = GetParam(); 616 617 // Set up 618 619 ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, params.maxLockedBuffers + 1)); 620 621 // Produce 622 623 const int64_t time = 1234L; 624 uint32_t stride; 625 626 for (int i = 0; i < params.maxLockedBuffers + 1; i++) { 627 ALOGV("Producing frame %d", i); 628 ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time, 629 &stride)); 630 } 631 632 // Consume 633 634 std::vector<CpuConsumer::LockedBuffer> b(params.maxLockedBuffers); 635 for (int i = 0; i < params.maxLockedBuffers; i++) { 636 ALOGV("Locking frame %d", i); 637 err = mCC->lockNextBuffer(&b[i]); 638 ASSERT_NO_ERROR(err, "getNextBuffer error: "); 639 640 ASSERT_TRUE(b[i].data != NULL); 641 EXPECT_EQ(params.width, b[i].width); 642 EXPECT_EQ(params.height, b[i].height); 643 EXPECT_EQ(params.format, b[i].format); 644 EXPECT_EQ(stride, b[i].stride); 645 EXPECT_EQ(time, b[i].timestamp); 646 647 checkAnyBuffer(b[i], GetParam().format); 648 } 649 650 ALOGV("Locking frame %d (too many)", params.maxLockedBuffers); 651 CpuConsumer::LockedBuffer bTooMuch; 652 err = mCC->lockNextBuffer(&bTooMuch); 653 ASSERT_TRUE(err == NOT_ENOUGH_DATA) << "Allowing too many locks"; 654 655 ALOGV("Unlocking frame 0"); 656 err = mCC->unlockBuffer(b[0]); 657 ASSERT_NO_ERROR(err, "Could not unlock buffer 0: "); 658 659 ALOGV("Locking frame %d (should work now)", params.maxLockedBuffers); 660 err = mCC->lockNextBuffer(&bTooMuch); 661 ASSERT_NO_ERROR(err, "Did not allow new lock after unlock"); 662 663 ASSERT_TRUE(bTooMuch.data != NULL); 664 EXPECT_EQ(params.width, bTooMuch.width); 665 EXPECT_EQ(params.height, bTooMuch.height); 666 EXPECT_EQ(params.format, bTooMuch.format); 667 EXPECT_EQ(stride, bTooMuch.stride); 668 EXPECT_EQ(time, bTooMuch.timestamp); 669 670 checkAnyBuffer(bTooMuch, GetParam().format); 671 672 ALOGV("Unlocking extra buffer"); 673 err = mCC->unlockBuffer(bTooMuch); 674 ASSERT_NO_ERROR(err, "Could not unlock extra buffer: "); 675 676 ALOGV("Locking frame %d (no more available)", params.maxLockedBuffers + 1); 677 err = mCC->lockNextBuffer(&b[0]); 678 ASSERT_EQ(BAD_VALUE, err) << "Not out of buffers somehow"; 679 680 for (int i = 1; i < params.maxLockedBuffers; i++) { 681 mCC->unlockBuffer(b[i]); 682 } 683} 684 685TEST_P(CpuConsumerTest, FromCpuInvalid) { 686 status_t err = mCC->lockNextBuffer(nullptr); 687 ASSERT_EQ(BAD_VALUE, err) << "lockNextBuffer did not fail"; 688 689 CpuConsumer::LockedBuffer b; 690 err = mCC->unlockBuffer(b); 691 ASSERT_EQ(BAD_VALUE, err) << "unlockBuffer did not fail"; 692} 693 694TEST_P(CpuConsumerTest, FromCpuMultiThread) { 695 CpuConsumerTestParams params = GetParam(); 696 ASSERT_NO_FATAL_FAILURE(configureANW(mANW, params, params.maxLockedBuffers + 1)); 697 698 for (int i = 0; i < 10; i++) { 699 std::atomic<int> threadReadyCount(0); 700 auto lockAndUnlock = [&]() { 701 threadReadyCount++; 702 // busy wait 703 while (threadReadyCount < params.maxLockedBuffers + 1); 704 705 CpuConsumer::LockedBuffer b; 706 status_t err = mCC->lockNextBuffer(&b); 707 if (err == NO_ERROR) { 708 usleep(1000); 709 err = mCC->unlockBuffer(b); 710 ASSERT_NO_ERROR(err, "Could not unlock buffer: "); 711 } else if (err == NOT_ENOUGH_DATA) { 712 // there are params.maxLockedBuffers+1 threads so one of the 713 // threads might get this error 714 } else { 715 FAIL() << "Could not lock buffer"; 716 } 717 }; 718 719 // produce buffers 720 for (int j = 0; j < params.maxLockedBuffers + 1; j++) { 721 const int64_t time = 1234L; 722 uint32_t stride; 723 ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time, &stride)); 724 } 725 726 // spawn threads 727 std::vector<std::thread> threads; 728 for (int j = 0; j < params.maxLockedBuffers + 1; j++) { 729 threads.push_back(std::thread(lockAndUnlock)); 730 } 731 732 // join threads 733 for (auto& thread : threads) { 734 thread.join(); 735 } 736 737 // we produced N+1 buffers, but the threads might only consume N 738 CpuConsumer::LockedBuffer b; 739 if (mCC->lockNextBuffer(&b) == NO_ERROR) { 740 mCC->unlockBuffer(b); 741 } 742 743 if (HasFatalFailure()) { 744 break; 745 } 746 } 747} 748 749CpuConsumerTestParams y8TestSets[] = { 750 { 512, 512, 1, HAL_PIXEL_FORMAT_Y8}, 751 { 512, 512, 3, HAL_PIXEL_FORMAT_Y8}, 752 { 2608, 1960, 1, HAL_PIXEL_FORMAT_Y8}, 753 { 2608, 1960, 3, HAL_PIXEL_FORMAT_Y8}, 754 { 100, 100, 1, HAL_PIXEL_FORMAT_Y8}, 755 { 100, 100, 3, HAL_PIXEL_FORMAT_Y8}, 756}; 757 758CpuConsumerTestParams y16TestSets[] = { 759 { 512, 512, 1, HAL_PIXEL_FORMAT_Y16}, 760 { 512, 512, 3, HAL_PIXEL_FORMAT_Y16}, 761 { 2608, 1960, 1, HAL_PIXEL_FORMAT_Y16}, 762 { 2608, 1960, 3, HAL_PIXEL_FORMAT_Y16}, 763 { 100, 100, 1, HAL_PIXEL_FORMAT_Y16}, 764 { 100, 100, 3, HAL_PIXEL_FORMAT_Y16}, 765}; 766 767CpuConsumerTestParams rawTestSets[] = { 768 { 512, 512, 1, HAL_PIXEL_FORMAT_RAW16}, 769 { 512, 512, 3, HAL_PIXEL_FORMAT_RAW16}, 770 { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW16}, 771 { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW16}, 772 { 100, 100, 1, HAL_PIXEL_FORMAT_RAW16}, 773 { 100, 100, 3, HAL_PIXEL_FORMAT_RAW16}, 774}; 775 776CpuConsumerTestParams rgba8888TestSets[] = { 777 { 512, 512, 1, HAL_PIXEL_FORMAT_RGBA_8888}, 778 { 512, 512, 3, HAL_PIXEL_FORMAT_RGBA_8888}, 779 { 2608, 1960, 1, HAL_PIXEL_FORMAT_RGBA_8888}, 780 { 2608, 1960, 3, HAL_PIXEL_FORMAT_RGBA_8888}, 781 { 100, 100, 1, HAL_PIXEL_FORMAT_RGBA_8888}, 782 { 100, 100, 3, HAL_PIXEL_FORMAT_RGBA_8888}, 783}; 784 785#if CPU_CONSUMER_TEST_FORMAT_Y8 786INSTANTIATE_TEST_CASE_P(Y8Tests, 787 CpuConsumerTest, 788 ::testing::ValuesIn(y8TestSets)); 789#endif 790 791#if CPU_CONSUMER_TEST_FORMAT_Y16 792INSTANTIATE_TEST_CASE_P(Y16Tests, 793 CpuConsumerTest, 794 ::testing::ValuesIn(y16TestSets)); 795#endif 796 797#if CPU_CONSUMER_TEST_FORMAT_RAW 798INSTANTIATE_TEST_CASE_P(RawTests, 799 CpuConsumerTest, 800 ::testing::ValuesIn(rawTestSets)); 801#endif 802 803#if CPU_CONSUMER_TEST_FORMAT_RGBA_8888 804INSTANTIATE_TEST_CASE_P(Rgba8888Tests, 805 CpuConsumerTest, 806 ::testing::ValuesIn(rgba8888TestSets)); 807#endif 808 809 810 811} // namespace android 812