BufferQueue_test.cpp revision b3d0bdf0dbc19f0a0d7d924693025371e24828fd
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 <gtest/gtest.h> 21 22#include <utils/String8.h> 23#include <utils/threads.h> 24 25#include <ui/GraphicBuffer.h> 26 27#include <binder/IPCThreadState.h> 28#include <binder/IServiceManager.h> 29#include <binder/ProcessState.h> 30#include <gui/BufferQueue.h> 31 32namespace android { 33 34class BufferQueueTest : public ::testing::Test { 35 36public: 37protected: 38 BufferQueueTest() { 39 const ::testing::TestInfo* const testInfo = 40 ::testing::UnitTest::GetInstance()->current_test_info(); 41 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), 42 testInfo->name()); 43 } 44 45 ~BufferQueueTest() { 46 const ::testing::TestInfo* const testInfo = 47 ::testing::UnitTest::GetInstance()->current_test_info(); 48 ALOGV("End test: %s.%s", testInfo->test_case_name(), 49 testInfo->name()); 50 } 51 52 void GetMinUndequeuedBufferCount(int* bufferCount) { 53 ASSERT_TRUE(bufferCount != NULL); 54 ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 55 bufferCount)); 56 ASSERT_GE(*bufferCount, 0); 57 } 58 59 void createBufferQueue() { 60 BufferQueue::createBufferQueue(&mProducer, &mConsumer); 61 } 62 63 sp<IGraphicBufferProducer> mProducer; 64 sp<IGraphicBufferConsumer> mConsumer; 65}; 66 67struct DummyConsumer : public BnConsumerListener { 68 virtual void onFrameAvailable() {} 69 virtual void onBuffersReleased() {} 70 virtual void onSidebandStreamChanged() {} 71}; 72 73// XXX: Tests that fork a process to hold the BufferQueue must run before tests 74// that use a local BufferQueue, or else Binder will get unhappy 75TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { 76 const String16 PRODUCER_NAME = String16("BQTestProducer"); 77 const String16 CONSUMER_NAME = String16("BQTestConsumer"); 78 79 pid_t forkPid = fork(); 80 ASSERT_NE(forkPid, -1); 81 82 if (forkPid == 0) { 83 // Child process 84 sp<IGraphicBufferProducer> producer; 85 sp<IGraphicBufferConsumer> consumer; 86 BufferQueue::createBufferQueue(&producer, &consumer); 87 sp<IServiceManager> serviceManager = defaultServiceManager(); 88 serviceManager->addService(PRODUCER_NAME, producer->asBinder()); 89 serviceManager->addService(CONSUMER_NAME, consumer->asBinder()); 90 ProcessState::self()->startThreadPool(); 91 IPCThreadState::self()->joinThreadPool(); 92 LOG_ALWAYS_FATAL("Shouldn't be here"); 93 } 94 95 sp<IServiceManager> serviceManager = defaultServiceManager(); 96 sp<IBinder> binderProducer = 97 serviceManager->getService(PRODUCER_NAME); 98 mProducer = interface_cast<IGraphicBufferProducer>(binderProducer); 99 EXPECT_TRUE(mProducer != NULL); 100 sp<IBinder> binderConsumer = 101 serviceManager->getService(CONSUMER_NAME); 102 mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer); 103 EXPECT_TRUE(mConsumer != NULL); 104 105 sp<DummyConsumer> dc(new DummyConsumer); 106 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 107 IGraphicBufferProducer::QueueBufferOutput output; 108 ASSERT_EQ(OK, 109 mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); 110 111 int slot; 112 sp<Fence> fence; 113 sp<GraphicBuffer> buffer; 114 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 115 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 116 GRALLOC_USAGE_SW_WRITE_OFTEN)); 117 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 118 119 uint32_t* dataIn; 120 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 121 reinterpret_cast<void**>(&dataIn))); 122 *dataIn = 0x12345678; 123 ASSERT_EQ(OK, buffer->unlock()); 124 125 IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), 126 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 127 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 128 129 IGraphicBufferConsumer::BufferItem item; 130 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 131 132 uint32_t* dataOut; 133 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 134 reinterpret_cast<void**>(&dataOut))); 135 ASSERT_EQ(*dataOut, 0x12345678); 136 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 137} 138 139TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { 140 createBufferQueue(); 141 sp<DummyConsumer> dc(new DummyConsumer); 142 mConsumer->consumerConnect(dc, false); 143 IGraphicBufferProducer::QueueBufferOutput qbo; 144 mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &qbo); 145 mProducer->setBufferCount(4); 146 147 int slot; 148 sp<Fence> fence; 149 sp<GraphicBuffer> buf; 150 IGraphicBufferProducer::QueueBufferInput qbi(0, false, Rect(0, 0, 1, 1), 151 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 152 BufferQueue::BufferItem item; 153 154 for (int i = 0; i < 2; i++) { 155 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 156 mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0, 157 GRALLOC_USAGE_SW_READ_OFTEN)); 158 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 159 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 160 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); 161 } 162 163 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 164 mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0, 165 GRALLOC_USAGE_SW_READ_OFTEN)); 166 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf)); 167 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo)); 168 169 // Acquire the third buffer, which should fail. 170 ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0)); 171} 172 173TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) { 174 createBufferQueue(); 175 sp<DummyConsumer> dc(new DummyConsumer); 176 mConsumer->consumerConnect(dc, false); 177 178 int minBufferCount; 179 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount)); 180 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount( 181 minBufferCount - 1)); 182 183 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0)); 184 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3)); 185 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount( 186 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1)); 187 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100)); 188} 189 190TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { 191 createBufferQueue(); 192 sp<DummyConsumer> dc(new DummyConsumer); 193 mConsumer->consumerConnect(dc, false); 194 195 int minBufferCount; 196 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount)); 197 198 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1)); 199 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2)); 200 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount)); 201 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount( 202 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS)); 203} 204 205TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { 206 createBufferQueue(); 207 sp<DummyConsumer> dc(new DummyConsumer); 208 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 209 IGraphicBufferProducer::QueueBufferOutput output; 210 ASSERT_EQ(OK, 211 mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); 212 213 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low 214 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer( 215 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high 216 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued 217 218 int slot; 219 sp<Fence> fence; 220 sp<GraphicBuffer> buffer; 221 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 222 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 223 GRALLOC_USAGE_SW_WRITE_OFTEN)); 224 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested 225 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 226 ASSERT_EQ(OK, mProducer->detachBuffer(slot)); 227 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued 228 229 sp<GraphicBuffer> safeToClobberBuffer; 230 // Can no longer request buffer from this slot 231 ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer)); 232 233 uint32_t* dataIn; 234 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 235 reinterpret_cast<void**>(&dataIn))); 236 *dataIn = 0x12345678; 237 ASSERT_EQ(OK, buffer->unlock()); 238 239 int newSlot; 240 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer)); 241 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL)); 242 243 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer)); 244 IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), 245 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 246 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output)); 247 248 IGraphicBufferConsumer::BufferItem item; 249 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 250 251 uint32_t* dataOut; 252 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 253 reinterpret_cast<void**>(&dataOut))); 254 ASSERT_EQ(*dataOut, 0x12345678); 255 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 256} 257 258TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { 259 createBufferQueue(); 260 sp<DummyConsumer> dc(new DummyConsumer); 261 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 262 IGraphicBufferProducer::QueueBufferOutput output; 263 ASSERT_EQ(OK, 264 mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); 265 266 int slot; 267 sp<Fence> fence; 268 sp<GraphicBuffer> buffer; 269 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 270 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 271 GRALLOC_USAGE_SW_WRITE_OFTEN)); 272 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 273 IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), 274 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 275 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 276 277 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low 278 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer( 279 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high 280 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired 281 282 IGraphicBufferConsumer::BufferItem item; 283 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 284 285 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf)); 286 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mBuf)); // Not acquired 287 288 uint32_t* dataIn; 289 ASSERT_EQ(OK, item.mGraphicBuffer->lock( 290 GraphicBuffer::USAGE_SW_WRITE_OFTEN, 291 reinterpret_cast<void**>(&dataIn))); 292 *dataIn = 0x12345678; 293 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 294 295 int newSlot; 296 sp<GraphicBuffer> safeToClobberBuffer; 297 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer)); 298 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL)); 299 ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer)); 300 301 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mBuf, 0, EGL_NO_DISPLAY, 302 EGL_NO_SYNC_KHR, Fence::NO_FENCE)); 303 304 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 305 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 306 GRALLOC_USAGE_SW_WRITE_OFTEN)); 307 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 308 309 uint32_t* dataOut; 310 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 311 reinterpret_cast<void**>(&dataOut))); 312 ASSERT_EQ(*dataOut, 0x12345678); 313 ASSERT_EQ(OK, buffer->unlock()); 314} 315 316TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { 317 createBufferQueue(); 318 sp<DummyConsumer> dc(new DummyConsumer); 319 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); 320 IGraphicBufferProducer::QueueBufferOutput output; 321 ASSERT_EQ(OK, 322 mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); 323 324 int slot; 325 sp<Fence> fence; 326 sp<GraphicBuffer> buffer; 327 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, 328 mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 329 GRALLOC_USAGE_SW_WRITE_OFTEN)); 330 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); 331 332 uint32_t* dataIn; 333 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, 334 reinterpret_cast<void**>(&dataIn))); 335 *dataIn = 0x12345678; 336 ASSERT_EQ(OK, buffer->unlock()); 337 338 IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), 339 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); 340 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); 341 342 IGraphicBufferConsumer::BufferItem item; 343 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 344 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf)); 345 346 int newSlot; 347 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer)); 348 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output)); 349 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0))); 350 351 uint32_t* dataOut; 352 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, 353 reinterpret_cast<void**>(&dataOut))); 354 ASSERT_EQ(*dataOut, 0x12345678); 355 ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); 356} 357 358} // namespace android 359