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 "BufferQueue_test" 18 //#define LOG_NDEBUG 0 19 20 #include "DummyConsumer.h" 21 22 #include <gui/BufferItem.h> 23 #include <gui/BufferQueue.h> 24 #include <gui/IProducerListener.h> 25 26 #include <ui/GraphicBuffer.h> 27 28 #include <binder/IPCThreadState.h> 29 #include <binder/IServiceManager.h> 30 #include <binder/ProcessState.h> 31 32 #include <utils/String8.h> 33 #include <utils/threads.h> 34 35 #include <gtest/gtest.h> 36 37 namespace android { 38 39 class BufferQueueTest : public ::testing::Test { 40 41 public: 42 protected: 43 BufferQueueTest() { 44 const ::testing::TestInfo* const testInfo = 45 ::testing::UnitTest::GetInstance()->current_test_info(); 46 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), 47 testInfo->name()); 48 } 49 50 ~BufferQueueTest() { 51 const ::testing::TestInfo* const testInfo = 52 ::testing::UnitTest::GetInstance()->current_test_info(); 53 ALOGV("End test: %s.%s", testInfo->test_case_name(), 54 testInfo->name()); 55 } 56 57 void GetMinUndequeuedBufferCount(int* bufferCount) { 58 ASSERT_TRUE(bufferCount != NULL); 59 ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 60 bufferCount)); 61 ASSERT_GE(*bufferCount, 0); 62 } 63 64 void createBufferQueue() { 65 BufferQueue::createBufferQueue(&mProducer, &mConsumer); 66 } 67 68 void testBufferItem(const IGraphicBufferProducer::QueueBufferInput& input, 69 const BufferItem& item) { 70 int64_t timestamp; 71 bool isAutoTimestamp; 72 android_dataspace dataSpace; 73 Rect crop; 74 int scalingMode; 75 uint32_t transform; 76 sp<Fence> fence; 77 78 input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, 79 &scalingMode, &transform, &fence, NULL); 80 ASSERT_EQ(timestamp, item.mTimestamp); 81 ASSERT_EQ(isAutoTimestamp, item.mIsAutoTimestamp); 82 ASSERT_EQ(dataSpace, item.mDataSpace); 83 ASSERT_EQ(crop, item.mCrop); 84 ASSERT_EQ(static_cast<uint32_t>(scalingMode), item.mScalingMode); 85 ASSERT_EQ(transform, item.mTransform); 86 ASSERT_EQ(fence, item.mFence); 87 } 88 89 sp<IGraphicBufferProducer> mProducer; 90 sp<IGraphicBufferConsumer> mConsumer; 91 }; 92 93 static const uint32_t TEST_DATA = 0x12345678u; 94 95 // XXX: Tests that fork a process to hold the BufferQueue must run before tests 96 // that use a local BufferQueue, or else Binder will get unhappy 97 TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { 98 const String16 PRODUCER_NAME = String16("BQTestProducer"); 99 const String16 CONSUMER_NAME = String16("BQTestConsumer"); 100 101 pid_t forkPid = fork(); 102 ASSERT_NE(forkPid, -1); 103 104 if (forkPid == 0) { 105 // Child process 106 sp<IGraphicBufferProducer> producer; 107 sp<IGraphicBufferConsumer> consumer; 108 BufferQueue::createBufferQueue(&producer, &consumer); 109 sp<IServiceManager> serviceManager = defaultServiceManager(); 110 serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer)); 111 serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer)); 112 ProcessState::self()->startThreadPool(); 113 IPCThreadState::self()->joinThreadPool(); 114 LOG_ALWAYS_FATAL("Shouldn't be here"); 115 } 116 117 sp<IServiceManager> serviceManager = defaultServiceManager(); 118 sp<IBinder> binderProducer = 119 serviceManager->getService(PRODUCER_NAME); 120 mProducer = interface_cast<IGraphicBufferProducer>(binderProducer); 121 EXPECT_TRUE(mProducer != NULL); 122 sp<IBinder> binderConsumer = 123 serviceManager->getService(CONSUMER_NAME); 124 mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer); 125 EXPECT_TRUE(mConsumer != NULL); 126 127 sp<DummyConsumer> dc(new DummyConsumer); 128 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 129 IGraphicBufferProducer::QueueBufferOutput output; 130 ASSERT_EQ(OK, 131 mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); 132 133 int slot; 134 sp<Fence> fence; 135 sp<GraphicBuffer> buffer; 136 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 137 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 138 GRALLOC_USAGE_SW_WRITE_OFTEN)); 139 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 140 141 uint32_t* dataIn; 142 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 143 reinterpret_cast<void**>(&dataIn))); 144 *dataIn = TEST_DATA; 145 ASSERT_EQ(OK, buffer->unlock()); 146 147 IGraphicBufferProducer::QueueBufferInput input(0, false, 148 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 149 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 150 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 151 152 BufferItem item; 153 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 154 155 uint32_t* dataOut; 156 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 157 reinterpret_cast<void**>(&dataOut))); 158 ASSERT_EQ(*dataOut, TEST_DATA); 159 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 160 } 161 162 TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { 163 createBufferQueue(); 164 sp<DummyConsumer> dc(new DummyConsumer); 165 mConsumer->consumerConnect(dc, false); 166 IGraphicBufferProducer::QueueBufferOutput qbo; 167 mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, 168 &qbo); 169 mProducer->setMaxDequeuedBufferCount(3); 170 171 int slot; 172 sp<Fence> fence; 173 sp<GraphicBuffer> buf; 174 IGraphicBufferProducer::QueueBufferInput qbi(0, false, 175 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 176 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 177 BufferItem item; 178 179 for (int i = 0; i < 2; i++) { 180 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 181 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, 182 GRALLOC_USAGE_SW_READ_OFTEN)); 183 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 184 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 185 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 186 } 187 188 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 189 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, 190 GRALLOC_USAGE_SW_READ_OFTEN)); 191 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 192 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 193 194 // Acquire the third buffer, which should fail. 195 ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0)); 196 } 197 198 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) { 199 createBufferQueue(); 200 sp<DummyConsumer> dc(new DummyConsumer); 201 mConsumer->consumerConnect(dc, false); 202 203 EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10)); 204 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10)); 205 206 IGraphicBufferProducer::QueueBufferOutput qbo; 207 mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, 208 &qbo); 209 mProducer->setMaxDequeuedBufferCount(3); 210 211 int minBufferCount; 212 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount)); 213 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount( 214 minBufferCount - 1)); 215 216 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0)); 217 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3)); 218 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount( 219 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1)); 220 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100)); 221 222 int slot; 223 sp<Fence> fence; 224 sp<GraphicBuffer> buf; 225 IGraphicBufferProducer::QueueBufferInput qbi(0, false, 226 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 227 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 228 BufferItem item; 229 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3)); 230 for (int i = 0; i < 3; i++) { 231 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 232 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, 233 GRALLOC_USAGE_SW_READ_OFTEN)); 234 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 235 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 236 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 237 } 238 239 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(2)); 240 } 241 242 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { 243 createBufferQueue(); 244 sp<DummyConsumer> dc(new DummyConsumer); 245 mConsumer->consumerConnect(dc, false); 246 247 IGraphicBufferProducer::QueueBufferOutput qbo; 248 mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, 249 &qbo); 250 mProducer->setMaxDequeuedBufferCount(2); 251 252 int minBufferCount; 253 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount)); 254 255 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1)); 256 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2)); 257 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount)); 258 259 int slot; 260 sp<Fence> fence; 261 sp<GraphicBuffer> buf; 262 IGraphicBufferProducer::QueueBufferInput qbi(0, false, 263 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 264 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 265 BufferItem item; 266 267 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 268 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, 269 GRALLOC_USAGE_SW_READ_OFTEN)); 270 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 271 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 272 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 273 274 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3)); 275 276 for (int i = 0; i < 2; i++) { 277 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 278 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, 279 GRALLOC_USAGE_SW_READ_OFTEN)); 280 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 281 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 282 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 283 } 284 285 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount( 286 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS)); 287 } 288 289 TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) { 290 createBufferQueue(); 291 sp<DummyConsumer> dc(new DummyConsumer); 292 mConsumer->consumerConnect(dc, false); 293 294 // Test shared buffer mode 295 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1)); 296 } 297 298 TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) { 299 createBufferQueue(); 300 sp<DummyConsumer> dc(new DummyConsumer); 301 mConsumer->consumerConnect(dc, false); 302 303 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0)); 304 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount( 305 BufferQueue::NUM_BUFFER_SLOTS + 1)); 306 307 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5)); 308 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3)); 309 } 310 311 TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { 312 createBufferQueue(); 313 sp<DummyConsumer> dc(new DummyConsumer); 314 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 315 IGraphicBufferProducer::QueueBufferOutput output; 316 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 317 NATIVE_WINDOW_API_CPU, false, &output)); 318 319 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low 320 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer( 321 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high 322 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued 323 324 int slot; 325 sp<Fence> fence; 326 sp<GraphicBuffer> buffer; 327 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 328 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 329 GRALLOC_USAGE_SW_WRITE_OFTEN)); 330 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested 331 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 332 ASSERT_EQ(OK, mProducer->detachBuffer(slot)); 333 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued 334 335 sp<GraphicBuffer> safeToClobberBuffer; 336 // Can no longer request buffer from this slot 337 ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer)); 338 339 uint32_t* dataIn; 340 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 341 reinterpret_cast<void**>(&dataIn))); 342 *dataIn = TEST_DATA; 343 ASSERT_EQ(OK, buffer->unlock()); 344 345 int newSlot; 346 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer)); 347 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL)); 348 349 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer)); 350 IGraphicBufferProducer::QueueBufferInput input(0, false, 351 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 352 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 353 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output)); 354 355 BufferItem item; 356 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 357 358 uint32_t* dataOut; 359 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 360 reinterpret_cast<void**>(&dataOut))); 361 ASSERT_EQ(*dataOut, TEST_DATA); 362 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 363 } 364 365 TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { 366 createBufferQueue(); 367 sp<DummyConsumer> dc(new DummyConsumer); 368 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 369 IGraphicBufferProducer::QueueBufferOutput output; 370 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 371 NATIVE_WINDOW_API_CPU, false, &output)); 372 373 int slot; 374 sp<Fence> fence; 375 sp<GraphicBuffer> buffer; 376 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 377 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 378 GRALLOC_USAGE_SW_WRITE_OFTEN)); 379 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 380 IGraphicBufferProducer::QueueBufferInput input(0, false, 381 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 382 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 383 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 384 385 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low 386 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer( 387 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high 388 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired 389 390 BufferItem item; 391 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 392 393 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot)); 394 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired 395 396 uint32_t* dataIn; 397 ASSERT_EQ(OK, item.mGraphicBuffer->lock( 398 GraphicBuffer::USAGE_SW_WRITE_OFTEN, 399 reinterpret_cast<void**>(&dataIn))); 400 *dataIn = TEST_DATA; 401 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 402 403 int newSlot; 404 sp<GraphicBuffer> safeToClobberBuffer; 405 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer)); 406 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL)); 407 ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer)); 408 409 ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY, 410 EGL_NO_SYNC_KHR, Fence::NO_FENCE)); 411 412 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 413 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 414 GRALLOC_USAGE_SW_WRITE_OFTEN)); 415 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 416 417 uint32_t* dataOut; 418 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 419 reinterpret_cast<void**>(&dataOut))); 420 ASSERT_EQ(*dataOut, TEST_DATA); 421 ASSERT_EQ(OK, buffer->unlock()); 422 } 423 424 TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { 425 createBufferQueue(); 426 sp<DummyConsumer> dc(new DummyConsumer); 427 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 428 IGraphicBufferProducer::QueueBufferOutput output; 429 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 430 NATIVE_WINDOW_API_CPU, false, &output)); 431 432 int slot; 433 sp<Fence> fence; 434 sp<GraphicBuffer> buffer; 435 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 436 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 437 GRALLOC_USAGE_SW_WRITE_OFTEN)); 438 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 439 440 uint32_t* dataIn; 441 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 442 reinterpret_cast<void**>(&dataIn))); 443 *dataIn = TEST_DATA; 444 ASSERT_EQ(OK, buffer->unlock()); 445 446 IGraphicBufferProducer::QueueBufferInput input(0, false, 447 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 448 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 449 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 450 451 BufferItem item; 452 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 453 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot)); 454 455 int newSlot; 456 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer)); 457 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output)); 458 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 459 460 uint32_t* dataOut; 461 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 462 reinterpret_cast<void**>(&dataOut))); 463 ASSERT_EQ(*dataOut, TEST_DATA); 464 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 465 } 466 467 TEST_F(BufferQueueTest, TestDisallowingAllocation) { 468 createBufferQueue(); 469 sp<DummyConsumer> dc(new DummyConsumer); 470 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 471 IGraphicBufferProducer::QueueBufferOutput output; 472 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 473 NATIVE_WINDOW_API_CPU, true, &output)); 474 475 static const uint32_t WIDTH = 320; 476 static const uint32_t HEIGHT = 240; 477 478 ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT)); 479 480 int slot; 481 sp<Fence> fence; 482 sp<GraphicBuffer> buffer; 483 // This should return an error since it would require an allocation 484 ASSERT_EQ(OK, mProducer->allowAllocation(false)); 485 ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 486 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); 487 488 // This should succeed, now that we've lifted the prohibition 489 ASSERT_EQ(OK, mProducer->allowAllocation(true)); 490 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 491 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 492 GRALLOC_USAGE_SW_WRITE_OFTEN)); 493 494 // Release the previous buffer back to the BufferQueue 495 mProducer->cancelBuffer(slot, fence); 496 497 // This should fail since we're requesting a different size 498 ASSERT_EQ(OK, mProducer->allowAllocation(false)); 499 ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, 500 WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); 501 } 502 503 TEST_F(BufferQueueTest, TestGenerationNumbers) { 504 createBufferQueue(); 505 sp<DummyConsumer> dc(new DummyConsumer); 506 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 507 IGraphicBufferProducer::QueueBufferOutput output; 508 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 509 NATIVE_WINDOW_API_CPU, true, &output)); 510 511 ASSERT_EQ(OK, mProducer->setGenerationNumber(1)); 512 513 // Get one buffer to play with 514 int slot; 515 sp<Fence> fence; 516 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 517 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0)); 518 519 sp<GraphicBuffer> buffer; 520 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 521 522 // Ensure that the generation number we set propagates to allocated buffers 523 ASSERT_EQ(1U, buffer->getGenerationNumber()); 524 525 ASSERT_EQ(OK, mProducer->detachBuffer(slot)); 526 527 ASSERT_EQ(OK, mProducer->setGenerationNumber(2)); 528 529 // These should fail, since we've changed the generation number on the queue 530 int outSlot; 531 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer)); 532 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer)); 533 534 buffer->setGenerationNumber(2); 535 536 // This should succeed now that we've changed the buffer's generation number 537 ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer)); 538 539 ASSERT_EQ(OK, mProducer->detachBuffer(outSlot)); 540 541 // This should also succeed with the new generation number 542 ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer)); 543 } 544 545 TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) { 546 createBufferQueue(); 547 sp<DummyConsumer> dc(new DummyConsumer); 548 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 549 IGraphicBufferProducer::QueueBufferOutput output; 550 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 551 NATIVE_WINDOW_API_CPU, true, &output)); 552 553 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true)); 554 555 // Get a buffer 556 int sharedSlot; 557 sp<Fence> fence; 558 sp<GraphicBuffer> buffer; 559 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 560 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0)); 561 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer)); 562 563 // Queue the buffer 564 IGraphicBufferProducer::QueueBufferInput input(0, false, 565 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 566 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 567 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); 568 569 // Repeatedly queue and dequeue a buffer from the producer side, it should 570 // always return the same one. And we won't run out of buffers because it's 571 // always the same one and because async mode gets enabled. 572 int slot; 573 for (int i = 0; i < 5; i++) { 574 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0)); 575 ASSERT_EQ(sharedSlot, slot); 576 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); 577 } 578 579 // acquire the buffer 580 BufferItem item; 581 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 582 ASSERT_EQ(sharedSlot, item.mSlot); 583 testBufferItem(input, item); 584 ASSERT_EQ(true, item.mQueuedBuffer); 585 ASSERT_EQ(false, item.mAutoRefresh); 586 587 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, 588 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); 589 590 // attempt to acquire a second time should return no buffer available 591 ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE, 592 mConsumer->acquireBuffer(&item, 0)); 593 } 594 595 TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) { 596 createBufferQueue(); 597 sp<DummyConsumer> dc(new DummyConsumer); 598 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 599 IGraphicBufferProducer::QueueBufferOutput output; 600 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 601 NATIVE_WINDOW_API_CPU, true, &output)); 602 603 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true)); 604 ASSERT_EQ(OK, mProducer->setAutoRefresh(true)); 605 606 // Get a buffer 607 int sharedSlot; 608 sp<Fence> fence; 609 sp<GraphicBuffer> buffer; 610 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 611 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0)); 612 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer)); 613 614 // Queue the buffer 615 IGraphicBufferProducer::QueueBufferInput input(0, false, 616 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 617 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 618 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); 619 620 // Repeatedly acquire and release a buffer from the consumer side, it should 621 // always return the same one. 622 BufferItem item; 623 for (int i = 0; i < 5; i++) { 624 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 625 ASSERT_EQ(sharedSlot, item.mSlot); 626 testBufferItem(input, item); 627 ASSERT_EQ(i == 0, item.mQueuedBuffer); 628 ASSERT_EQ(true, item.mAutoRefresh); 629 630 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, 631 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); 632 } 633 634 // Repeatedly queue and dequeue a buffer from the producer side, it should 635 // always return the same one. 636 int slot; 637 for (int i = 0; i < 5; i++) { 638 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0)); 639 ASSERT_EQ(sharedSlot, slot); 640 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); 641 } 642 643 // Repeatedly acquire and release a buffer from the consumer side, it should 644 // always return the same one. First grabbing them from the queue and then 645 // when the queue is empty, returning the shared buffer. 646 for (int i = 0; i < 10; i++) { 647 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 648 ASSERT_EQ(sharedSlot, item.mSlot); 649 ASSERT_EQ(0, item.mTimestamp); 650 ASSERT_EQ(false, item.mIsAutoTimestamp); 651 ASSERT_EQ(HAL_DATASPACE_UNKNOWN, item.mDataSpace); 652 ASSERT_EQ(Rect(0, 0, 1, 1), item.mCrop); 653 ASSERT_EQ(NATIVE_WINDOW_SCALING_MODE_FREEZE, item.mScalingMode); 654 ASSERT_EQ(0u, item.mTransform); 655 ASSERT_EQ(Fence::NO_FENCE, item.mFence); 656 ASSERT_EQ(i == 0, item.mQueuedBuffer); 657 ASSERT_EQ(true, item.mAutoRefresh); 658 659 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, 660 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); 661 } 662 } 663 664 TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) { 665 createBufferQueue(); 666 sp<DummyConsumer> dc(new DummyConsumer); 667 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 668 IGraphicBufferProducer::QueueBufferOutput output; 669 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 670 NATIVE_WINDOW_API_CPU, true, &output)); 671 672 // Dequeue a buffer 673 int sharedSlot; 674 sp<Fence> fence; 675 sp<GraphicBuffer> buffer; 676 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 677 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0)); 678 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer)); 679 680 // Enable shared buffer mode 681 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true)); 682 683 // Queue the buffer 684 IGraphicBufferProducer::QueueBufferInput input(0, false, 685 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 686 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 687 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); 688 689 // Repeatedly queue and dequeue a buffer from the producer side, it should 690 // always return the same one. And we won't run out of buffers because it's 691 // always the same one and because async mode gets enabled. 692 int slot; 693 for (int i = 0; i < 5; i++) { 694 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0)); 695 ASSERT_EQ(sharedSlot, slot); 696 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output)); 697 } 698 699 // acquire the buffer 700 BufferItem item; 701 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 702 ASSERT_EQ(sharedSlot, item.mSlot); 703 testBufferItem(input, item); 704 ASSERT_EQ(true, item.mQueuedBuffer); 705 ASSERT_EQ(false, item.mAutoRefresh); 706 707 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, 708 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); 709 710 // attempt to acquire a second time should return no buffer available 711 ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE, 712 mConsumer->acquireBuffer(&item, 0)); 713 } 714 715 TEST_F(BufferQueueTest, TestTimeouts) { 716 createBufferQueue(); 717 sp<DummyConsumer> dc(new DummyConsumer); 718 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 719 IGraphicBufferProducer::QueueBufferOutput output; 720 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 721 NATIVE_WINDOW_API_CPU, true, &output)); 722 723 // Fill up the queue. Since the controlledByApp flags are set to true, this 724 // queue should be in non-blocking mode, and we should be recycling the same 725 // two buffers 726 for (int i = 0; i < 5; ++i) { 727 int slot = BufferQueue::INVALID_BUFFER_SLOT; 728 sp<Fence> fence = Fence::NO_FENCE; 729 auto result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0); 730 if (i < 2) { 731 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 732 result); 733 } else { 734 ASSERT_EQ(OK, result); 735 } 736 sp<GraphicBuffer> buffer; 737 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 738 IGraphicBufferProducer::QueueBufferInput input(0ull, true, 739 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT, 740 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 741 IGraphicBufferProducer::QueueBufferOutput output{}; 742 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 743 } 744 745 const auto TIMEOUT = ms2ns(250); 746 mProducer->setDequeueTimeout(TIMEOUT); 747 748 // Setting a timeout will change the BufferQueue into blocking mode (with 749 // one droppable buffer in the queue and one free from the previous 750 // dequeue/queues), so dequeue and queue two more buffers: one to replace 751 // the current droppable buffer, and a second to max out the buffer count 752 sp<GraphicBuffer> buffer; // Save a buffer to attach later 753 for (int i = 0; i < 2; ++i) { 754 int slot = BufferQueue::INVALID_BUFFER_SLOT; 755 sp<Fence> fence = Fence::NO_FENCE; 756 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0)); 757 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 758 IGraphicBufferProducer::QueueBufferInput input(0ull, true, 759 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT, 760 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 761 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 762 } 763 764 int slot = BufferQueue::INVALID_BUFFER_SLOT; 765 sp<Fence> fence = Fence::NO_FENCE; 766 auto startTime = systemTime(); 767 ASSERT_EQ(TIMED_OUT, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0)); 768 ASSERT_GE(systemTime() - startTime, TIMEOUT); 769 770 // We're technically attaching the same buffer multiple times (since we 771 // queued it previously), but that doesn't matter for this test 772 startTime = systemTime(); 773 ASSERT_EQ(TIMED_OUT, mProducer->attachBuffer(&slot, buffer)); 774 ASSERT_GE(systemTime() - startTime, TIMEOUT); 775 } 776 777 TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) { 778 createBufferQueue(); 779 sp<DummyConsumer> dc(new DummyConsumer); 780 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 781 IGraphicBufferProducer::QueueBufferOutput output; 782 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 783 NATIVE_WINDOW_API_CPU, true, &output)); 784 785 int slot = BufferQueue::INVALID_BUFFER_SLOT; 786 sp<Fence> sourceFence; 787 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 788 mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, 0)); 789 sp<GraphicBuffer> buffer; 790 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 791 ASSERT_EQ(OK, mProducer->detachBuffer(slot)); 792 793 ASSERT_EQ(OK, mProducer->allowAllocation(false)); 794 795 slot = BufferQueue::INVALID_BUFFER_SLOT; 796 ASSERT_EQ(OK, mProducer->attachBuffer(&slot, buffer)); 797 } 798 799 TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) { 800 createBufferQueue(); 801 sp<DummyConsumer> dc(new DummyConsumer); 802 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 803 IGraphicBufferProducer::QueueBufferOutput output; 804 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 805 NATIVE_WINDOW_API_CPU, false, &output)); 806 807 // Dequeue and queue the first buffer, storing the handle 808 int slot = BufferQueue::INVALID_BUFFER_SLOT; 809 sp<Fence> fence; 810 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 811 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0)); 812 sp<GraphicBuffer> firstBuffer; 813 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer)); 814 815 IGraphicBufferProducer::QueueBufferInput input(0ull, true, 816 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT, 817 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); 818 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 819 820 // Dequeue a second buffer 821 slot = BufferQueue::INVALID_BUFFER_SLOT; 822 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 823 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0)); 824 sp<GraphicBuffer> secondBuffer; 825 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer)); 826 827 // Ensure it's a new buffer 828 ASSERT_NE(firstBuffer->getNativeBuffer()->handle, 829 secondBuffer->getNativeBuffer()->handle); 830 831 // Queue the second buffer 832 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 833 834 // Acquire and release both buffers 835 for (size_t i = 0; i < 2; ++i) { 836 BufferItem item; 837 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 838 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, 839 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); 840 } 841 842 // Make sure we got the second buffer back 843 sp<GraphicBuffer> returnedBuffer; 844 sp<Fence> returnedFence; 845 float transform[16]; 846 ASSERT_EQ(OK, 847 mProducer->getLastQueuedBuffer(&returnedBuffer, &returnedFence, 848 transform)); 849 ASSERT_EQ(secondBuffer->getNativeBuffer()->handle, 850 returnedBuffer->getNativeBuffer()->handle); 851 } 852 853 } // namespace android 854