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