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