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