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