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 sp<IGraphicBufferProducer> mProducer; 69 sp<IGraphicBufferConsumer> mConsumer; 70 }; 71 72 static const uint32_t TEST_DATA = 0x12345678u; 73 74 // XXX: Tests that fork a process to hold the BufferQueue must run before tests 75 // that use a local BufferQueue, or else Binder will get unhappy 76 TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { 77 const String16 PRODUCER_NAME = String16("BQTestProducer"); 78 const String16 CONSUMER_NAME = String16("BQTestConsumer"); 79 80 pid_t forkPid = fork(); 81 ASSERT_NE(forkPid, -1); 82 83 if (forkPid == 0) { 84 // Child process 85 sp<IGraphicBufferProducer> producer; 86 sp<IGraphicBufferConsumer> consumer; 87 BufferQueue::createBufferQueue(&producer, &consumer); 88 sp<IServiceManager> serviceManager = defaultServiceManager(); 89 serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer)); 90 serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer)); 91 ProcessState::self()->startThreadPool(); 92 IPCThreadState::self()->joinThreadPool(); 93 LOG_ALWAYS_FATAL("Shouldn't be here"); 94 } 95 96 sp<IServiceManager> serviceManager = defaultServiceManager(); 97 sp<IBinder> binderProducer = 98 serviceManager->getService(PRODUCER_NAME); 99 mProducer = interface_cast<IGraphicBufferProducer>(binderProducer); 100 EXPECT_TRUE(mProducer != NULL); 101 sp<IBinder> binderConsumer = 102 serviceManager->getService(CONSUMER_NAME); 103 mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer); 104 EXPECT_TRUE(mConsumer != NULL); 105 106 sp<DummyConsumer> dc(new DummyConsumer); 107 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 108 IGraphicBufferProducer::QueueBufferOutput output; 109 ASSERT_EQ(OK, 110 mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); 111 112 int slot; 113 sp<Fence> fence; 114 sp<GraphicBuffer> buffer; 115 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 116 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 117 GRALLOC_USAGE_SW_WRITE_OFTEN)); 118 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 119 120 uint32_t* dataIn; 121 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 122 reinterpret_cast<void**>(&dataIn))); 123 *dataIn = TEST_DATA; 124 ASSERT_EQ(OK, buffer->unlock()); 125 126 IGraphicBufferProducer::QueueBufferInput input(0, false, 127 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 128 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 129 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 130 131 BufferItem item; 132 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 133 134 uint32_t* dataOut; 135 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 136 reinterpret_cast<void**>(&dataOut))); 137 ASSERT_EQ(*dataOut, TEST_DATA); 138 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 139 } 140 141 TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { 142 createBufferQueue(); 143 sp<DummyConsumer> dc(new DummyConsumer); 144 mConsumer->consumerConnect(dc, false); 145 IGraphicBufferProducer::QueueBufferOutput qbo; 146 mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, 147 &qbo); 148 mProducer->setBufferCount(4); 149 150 int slot; 151 sp<Fence> fence; 152 sp<GraphicBuffer> buf; 153 IGraphicBufferProducer::QueueBufferInput qbi(0, false, 154 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 155 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 156 BufferItem item; 157 158 for (int i = 0; i < 2; i++) { 159 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 160 mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0, 161 GRALLOC_USAGE_SW_READ_OFTEN)); 162 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 163 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 164 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 165 } 166 167 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 168 mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0, 169 GRALLOC_USAGE_SW_READ_OFTEN)); 170 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 171 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 172 173 // Acquire the third buffer, which should fail. 174 ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0)); 175 } 176 177 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) { 178 createBufferQueue(); 179 sp<DummyConsumer> dc(new DummyConsumer); 180 mConsumer->consumerConnect(dc, false); 181 182 int minBufferCount; 183 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount)); 184 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount( 185 minBufferCount - 1)); 186 187 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0)); 188 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3)); 189 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount( 190 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1)); 191 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100)); 192 } 193 194 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { 195 createBufferQueue(); 196 sp<DummyConsumer> dc(new DummyConsumer); 197 mConsumer->consumerConnect(dc, false); 198 199 int minBufferCount; 200 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount)); 201 202 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1)); 203 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2)); 204 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount)); 205 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount( 206 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS)); 207 } 208 209 TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { 210 createBufferQueue(); 211 sp<DummyConsumer> dc(new DummyConsumer); 212 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 213 IGraphicBufferProducer::QueueBufferOutput output; 214 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 215 NATIVE_WINDOW_API_CPU, false, &output)); 216 217 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low 218 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer( 219 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high 220 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued 221 222 int slot; 223 sp<Fence> fence; 224 sp<GraphicBuffer> buffer; 225 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 226 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 227 GRALLOC_USAGE_SW_WRITE_OFTEN)); 228 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested 229 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 230 ASSERT_EQ(OK, mProducer->detachBuffer(slot)); 231 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued 232 233 sp<GraphicBuffer> safeToClobberBuffer; 234 // Can no longer request buffer from this slot 235 ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer)); 236 237 uint32_t* dataIn; 238 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 239 reinterpret_cast<void**>(&dataIn))); 240 *dataIn = TEST_DATA; 241 ASSERT_EQ(OK, buffer->unlock()); 242 243 int newSlot; 244 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer)); 245 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL)); 246 247 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer)); 248 IGraphicBufferProducer::QueueBufferInput input(0, false, 249 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 250 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 251 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output)); 252 253 BufferItem item; 254 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 255 256 uint32_t* dataOut; 257 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 258 reinterpret_cast<void**>(&dataOut))); 259 ASSERT_EQ(*dataOut, TEST_DATA); 260 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 261 } 262 263 TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { 264 createBufferQueue(); 265 sp<DummyConsumer> dc(new DummyConsumer); 266 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 267 IGraphicBufferProducer::QueueBufferOutput output; 268 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 269 NATIVE_WINDOW_API_CPU, false, &output)); 270 271 int slot; 272 sp<Fence> fence; 273 sp<GraphicBuffer> buffer; 274 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 275 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 276 GRALLOC_USAGE_SW_WRITE_OFTEN)); 277 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 278 IGraphicBufferProducer::QueueBufferInput input(0, false, 279 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 280 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 281 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 282 283 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low 284 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer( 285 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high 286 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired 287 288 BufferItem item; 289 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 290 291 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf)); 292 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mBuf)); // Not acquired 293 294 uint32_t* dataIn; 295 ASSERT_EQ(OK, item.mGraphicBuffer->lock( 296 GraphicBuffer::USAGE_SW_WRITE_OFTEN, 297 reinterpret_cast<void**>(&dataIn))); 298 *dataIn = TEST_DATA; 299 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 300 301 int newSlot; 302 sp<GraphicBuffer> safeToClobberBuffer; 303 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer)); 304 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL)); 305 ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer)); 306 307 ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY, 308 EGL_NO_SYNC_KHR, Fence::NO_FENCE)); 309 310 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 311 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 312 GRALLOC_USAGE_SW_WRITE_OFTEN)); 313 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 314 315 uint32_t* dataOut; 316 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 317 reinterpret_cast<void**>(&dataOut))); 318 ASSERT_EQ(*dataOut, TEST_DATA); 319 ASSERT_EQ(OK, buffer->unlock()); 320 } 321 322 TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { 323 createBufferQueue(); 324 sp<DummyConsumer> dc(new DummyConsumer); 325 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 326 IGraphicBufferProducer::QueueBufferOutput output; 327 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 328 NATIVE_WINDOW_API_CPU, false, &output)); 329 330 int slot; 331 sp<Fence> fence; 332 sp<GraphicBuffer> buffer; 333 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 334 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 335 GRALLOC_USAGE_SW_WRITE_OFTEN)); 336 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 337 338 uint32_t* dataIn; 339 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 340 reinterpret_cast<void**>(&dataIn))); 341 *dataIn = TEST_DATA; 342 ASSERT_EQ(OK, buffer->unlock()); 343 344 IGraphicBufferProducer::QueueBufferInput input(0, false, 345 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1), 346 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 347 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 348 349 BufferItem item; 350 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 351 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf)); 352 353 int newSlot; 354 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer)); 355 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output)); 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, TestDisallowingAllocation) { 366 createBufferQueue(); 367 sp<DummyConsumer> dc(new DummyConsumer); 368 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 369 IGraphicBufferProducer::QueueBufferOutput output; 370 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 371 NATIVE_WINDOW_API_CPU, true, &output)); 372 373 static const uint32_t WIDTH = 320; 374 static const uint32_t HEIGHT = 240; 375 376 ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT)); 377 378 int slot; 379 sp<Fence> fence; 380 sp<GraphicBuffer> buffer; 381 // This should return an error since it would require an allocation 382 ASSERT_EQ(OK, mProducer->allowAllocation(false)); 383 ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 384 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); 385 386 // This should succeed, now that we've lifted the prohibition 387 ASSERT_EQ(OK, mProducer->allowAllocation(true)); 388 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 389 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 390 GRALLOC_USAGE_SW_WRITE_OFTEN)); 391 392 // Release the previous buffer back to the BufferQueue 393 mProducer->cancelBuffer(slot, fence); 394 395 // This should fail since we're requesting a different size 396 ASSERT_EQ(OK, mProducer->allowAllocation(false)); 397 ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false, 398 WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); 399 } 400 401 TEST_F(BufferQueueTest, TestGenerationNumbers) { 402 createBufferQueue(); 403 sp<DummyConsumer> dc(new DummyConsumer); 404 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); 405 IGraphicBufferProducer::QueueBufferOutput output; 406 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, 407 NATIVE_WINDOW_API_CPU, true, &output)); 408 409 ASSERT_EQ(OK, mProducer->setGenerationNumber(1)); 410 411 // Get one buffer to play with 412 int slot; 413 sp<Fence> fence; 414 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 415 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 0)); 416 417 sp<GraphicBuffer> buffer; 418 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 419 420 // Ensure that the generation number we set propagates to allocated buffers 421 ASSERT_EQ(1U, buffer->getGenerationNumber()); 422 423 ASSERT_EQ(OK, mProducer->detachBuffer(slot)); 424 425 ASSERT_EQ(OK, mProducer->setGenerationNumber(2)); 426 427 // These should fail, since we've changed the generation number on the queue 428 int outSlot; 429 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer)); 430 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer)); 431 432 buffer->setGenerationNumber(2); 433 434 // This should succeed now that we've changed the buffer's generation number 435 ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer)); 436 437 ASSERT_EQ(OK, mProducer->detachBuffer(outSlot)); 438 439 // This should also succeed with the new generation number 440 ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer)); 441 } 442 443 } // namespace android 444