Loading libs/gui/IGraphicBufferConsumer.cpp +21 −11 Original line number Diff line number Diff line Loading @@ -71,11 +71,11 @@ size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const { size_t c = 0; if (mGraphicBuffer != 0) { c += mGraphicBuffer->getFlattenedSize(); FlattenableUtils::align<4>(c); c = FlattenableUtils::align<4>(c); } if (mFence != 0) { c += mFence->getFlattenedSize(); FlattenableUtils::align<4>(c); c = FlattenableUtils::align<4>(c); } return sizeof(int32_t) + c + getPodSize(); } Loading @@ -91,11 +91,21 @@ size_t IGraphicBufferConsumer::BufferItem::getFdCount() const { return c; } static void writeBoolAsInt(void*& buffer, size_t& size, bool b) { FlattenableUtils::write(buffer, size, static_cast<int32_t>(b)); } static bool readBoolFromInt(void const*& buffer, size_t& size) { int32_t i; FlattenableUtils::read(buffer, size, i); return static_cast<bool>(i); } status_t IGraphicBufferConsumer::BufferItem::flatten( void*& buffer, size_t& size, int*& fds, size_t& count) const { // make sure we have enough space if (count < BufferItem::getFlattenedSize()) { if (size < BufferItem::getFlattenedSize()) { return NO_MEMORY; } Loading Loading @@ -128,12 +138,12 @@ status_t IGraphicBufferConsumer::BufferItem::flatten( FlattenableUtils::write(buffer, size, mTransform); FlattenableUtils::write(buffer, size, mScalingMode); FlattenableUtils::write(buffer, size, mTimestamp); FlattenableUtils::write(buffer, size, mIsAutoTimestamp); writeBoolAsInt(buffer, size, mIsAutoTimestamp); FlattenableUtils::write(buffer, size, mFrameNumber); FlattenableUtils::write(buffer, size, mBuf); FlattenableUtils::write(buffer, size, mIsDroppable); FlattenableUtils::write(buffer, size, mAcquireCalled); FlattenableUtils::write(buffer, size, mTransformToDisplayInverse); writeBoolAsInt(buffer, size, mIsDroppable); writeBoolAsInt(buffer, size, mAcquireCalled); writeBoolAsInt(buffer, size, mTransformToDisplayInverse); return NO_ERROR; } Loading Loading @@ -170,12 +180,12 @@ status_t IGraphicBufferConsumer::BufferItem::unflatten( FlattenableUtils::read(buffer, size, mTransform); FlattenableUtils::read(buffer, size, mScalingMode); FlattenableUtils::read(buffer, size, mTimestamp); FlattenableUtils::read(buffer, size, mIsAutoTimestamp); mIsAutoTimestamp = readBoolFromInt(buffer, size); FlattenableUtils::read(buffer, size, mFrameNumber); FlattenableUtils::read(buffer, size, mBuf); FlattenableUtils::read(buffer, size, mIsDroppable); FlattenableUtils::read(buffer, size, mAcquireCalled); FlattenableUtils::read(buffer, size, mTransformToDisplayInverse); mIsDroppable = readBoolFromInt(buffer, size); mAcquireCalled = readBoolFromInt(buffer, size); mTransformToDisplayInverse = readBoolFromInt(buffer, size); return NO_ERROR; } Loading libs/gui/tests/BufferQueue_test.cpp +83 −13 Original line number Diff line number Diff line Loading @@ -24,7 +24,9 @@ #include <ui/GraphicBuffer.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/ProcessState.h> #include <gui/BufferQueue.h> namespace android { Loading @@ -32,20 +34,12 @@ namespace android { class BufferQueueTest : public ::testing::Test { public: static const String16 PRODUCER_NAME; static const String16 CONSUMER_NAME; protected: BufferQueueTest() { const ::testing::TestInfo* const testInfo = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name()); BufferQueue::createBufferQueue(&mProducer, &mConsumer); sp<IServiceManager> serviceManager = defaultServiceManager(); serviceManager->addService(PRODUCER_NAME, mProducer.get()); serviceManager->addService(CONSUMER_NAME, mConsumer.get()); } ~BufferQueueTest() { Loading @@ -62,12 +56,13 @@ protected: ASSERT_GE(*bufferCount, 0); } sp<BnGraphicBufferProducer> mProducer; sp<BnGraphicBufferConsumer> mConsumer; }; void createBufferQueue() { BufferQueue::createBufferQueue(&mProducer, &mConsumer); } const String16 BufferQueueTest::PRODUCER_NAME = String16("BQTestProducer"); const String16 BufferQueueTest::CONSUMER_NAME = String16("BQTestConsumer"); sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; }; struct DummyConsumer : public BnConsumerListener { virtual void onFrameAvailable() {} Loading @@ -75,7 +70,74 @@ struct DummyConsumer : public BnConsumerListener { virtual void onSidebandStreamChanged() {} }; // XXX: Tests that fork a process to hold the BufferQueue must run before tests // that use a local BufferQueue, or else Binder will get unhappy TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { const String16 PRODUCER_NAME = String16("BQTestProducer"); const String16 CONSUMER_NAME = String16("BQTestConsumer"); pid_t forkPid = fork(); ASSERT_NE(forkPid, -1); if (forkPid == 0) { // Child process sp<BnGraphicBufferProducer> producer; sp<BnGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); sp<IServiceManager> serviceManager = defaultServiceManager(); serviceManager->addService(PRODUCER_NAME, producer.get()); serviceManager->addService(CONSUMER_NAME, consumer.get()); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); LOG_ALWAYS_FATAL("Shouldn't be here"); } sp<IServiceManager> serviceManager = defaultServiceManager(); sp<IBinder> binderProducer = serviceManager->getService(PRODUCER_NAME); mProducer = interface_cast<IGraphicBufferProducer>(binderProducer); EXPECT_TRUE(mProducer != NULL); sp<IBinder> binderConsumer = serviceManager->getService(CONSUMER_NAME); mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer); EXPECT_TRUE(mConsumer != NULL); sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; ASSERT_EQ(OK, mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); int slot; sp<Fence> fence; sp<GraphicBuffer> buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); uint32_t* dataIn; ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&dataIn))); *dataIn = 0x12345678; ASSERT_EQ(OK, buffer->unlock()); IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); IGraphicBufferConsumer::BufferItem item; ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); uint32_t* dataOut; ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); IGraphicBufferProducer::QueueBufferOutput qbo; Loading Loading @@ -109,6 +171,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { } TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); Loading @@ -125,6 +188,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) } TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); Loading @@ -139,6 +203,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { } TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; Loading Loading @@ -187,9 +252,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; Loading Loading @@ -243,9 +310,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); ASSERT_EQ(OK, buffer->unlock()); } TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; Loading Loading @@ -283,6 +352,7 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } } // namespace android Loading
libs/gui/IGraphicBufferConsumer.cpp +21 −11 Original line number Diff line number Diff line Loading @@ -71,11 +71,11 @@ size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const { size_t c = 0; if (mGraphicBuffer != 0) { c += mGraphicBuffer->getFlattenedSize(); FlattenableUtils::align<4>(c); c = FlattenableUtils::align<4>(c); } if (mFence != 0) { c += mFence->getFlattenedSize(); FlattenableUtils::align<4>(c); c = FlattenableUtils::align<4>(c); } return sizeof(int32_t) + c + getPodSize(); } Loading @@ -91,11 +91,21 @@ size_t IGraphicBufferConsumer::BufferItem::getFdCount() const { return c; } static void writeBoolAsInt(void*& buffer, size_t& size, bool b) { FlattenableUtils::write(buffer, size, static_cast<int32_t>(b)); } static bool readBoolFromInt(void const*& buffer, size_t& size) { int32_t i; FlattenableUtils::read(buffer, size, i); return static_cast<bool>(i); } status_t IGraphicBufferConsumer::BufferItem::flatten( void*& buffer, size_t& size, int*& fds, size_t& count) const { // make sure we have enough space if (count < BufferItem::getFlattenedSize()) { if (size < BufferItem::getFlattenedSize()) { return NO_MEMORY; } Loading Loading @@ -128,12 +138,12 @@ status_t IGraphicBufferConsumer::BufferItem::flatten( FlattenableUtils::write(buffer, size, mTransform); FlattenableUtils::write(buffer, size, mScalingMode); FlattenableUtils::write(buffer, size, mTimestamp); FlattenableUtils::write(buffer, size, mIsAutoTimestamp); writeBoolAsInt(buffer, size, mIsAutoTimestamp); FlattenableUtils::write(buffer, size, mFrameNumber); FlattenableUtils::write(buffer, size, mBuf); FlattenableUtils::write(buffer, size, mIsDroppable); FlattenableUtils::write(buffer, size, mAcquireCalled); FlattenableUtils::write(buffer, size, mTransformToDisplayInverse); writeBoolAsInt(buffer, size, mIsDroppable); writeBoolAsInt(buffer, size, mAcquireCalled); writeBoolAsInt(buffer, size, mTransformToDisplayInverse); return NO_ERROR; } Loading Loading @@ -170,12 +180,12 @@ status_t IGraphicBufferConsumer::BufferItem::unflatten( FlattenableUtils::read(buffer, size, mTransform); FlattenableUtils::read(buffer, size, mScalingMode); FlattenableUtils::read(buffer, size, mTimestamp); FlattenableUtils::read(buffer, size, mIsAutoTimestamp); mIsAutoTimestamp = readBoolFromInt(buffer, size); FlattenableUtils::read(buffer, size, mFrameNumber); FlattenableUtils::read(buffer, size, mBuf); FlattenableUtils::read(buffer, size, mIsDroppable); FlattenableUtils::read(buffer, size, mAcquireCalled); FlattenableUtils::read(buffer, size, mTransformToDisplayInverse); mIsDroppable = readBoolFromInt(buffer, size); mAcquireCalled = readBoolFromInt(buffer, size); mTransformToDisplayInverse = readBoolFromInt(buffer, size); return NO_ERROR; } Loading
libs/gui/tests/BufferQueue_test.cpp +83 −13 Original line number Diff line number Diff line Loading @@ -24,7 +24,9 @@ #include <ui/GraphicBuffer.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/ProcessState.h> #include <gui/BufferQueue.h> namespace android { Loading @@ -32,20 +34,12 @@ namespace android { class BufferQueueTest : public ::testing::Test { public: static const String16 PRODUCER_NAME; static const String16 CONSUMER_NAME; protected: BufferQueueTest() { const ::testing::TestInfo* const testInfo = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name()); BufferQueue::createBufferQueue(&mProducer, &mConsumer); sp<IServiceManager> serviceManager = defaultServiceManager(); serviceManager->addService(PRODUCER_NAME, mProducer.get()); serviceManager->addService(CONSUMER_NAME, mConsumer.get()); } ~BufferQueueTest() { Loading @@ -62,12 +56,13 @@ protected: ASSERT_GE(*bufferCount, 0); } sp<BnGraphicBufferProducer> mProducer; sp<BnGraphicBufferConsumer> mConsumer; }; void createBufferQueue() { BufferQueue::createBufferQueue(&mProducer, &mConsumer); } const String16 BufferQueueTest::PRODUCER_NAME = String16("BQTestProducer"); const String16 BufferQueueTest::CONSUMER_NAME = String16("BQTestConsumer"); sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; }; struct DummyConsumer : public BnConsumerListener { virtual void onFrameAvailable() {} Loading @@ -75,7 +70,74 @@ struct DummyConsumer : public BnConsumerListener { virtual void onSidebandStreamChanged() {} }; // XXX: Tests that fork a process to hold the BufferQueue must run before tests // that use a local BufferQueue, or else Binder will get unhappy TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) { const String16 PRODUCER_NAME = String16("BQTestProducer"); const String16 CONSUMER_NAME = String16("BQTestConsumer"); pid_t forkPid = fork(); ASSERT_NE(forkPid, -1); if (forkPid == 0) { // Child process sp<BnGraphicBufferProducer> producer; sp<BnGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); sp<IServiceManager> serviceManager = defaultServiceManager(); serviceManager->addService(PRODUCER_NAME, producer.get()); serviceManager->addService(CONSUMER_NAME, consumer.get()); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); LOG_ALWAYS_FATAL("Shouldn't be here"); } sp<IServiceManager> serviceManager = defaultServiceManager(); sp<IBinder> binderProducer = serviceManager->getService(PRODUCER_NAME); mProducer = interface_cast<IGraphicBufferProducer>(binderProducer); EXPECT_TRUE(mProducer != NULL); sp<IBinder> binderConsumer = serviceManager->getService(CONSUMER_NAME); mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer); EXPECT_TRUE(mConsumer != NULL); sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; ASSERT_EQ(OK, mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); int slot; sp<Fence> fence; sp<GraphicBuffer> buffer; ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN)); ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); uint32_t* dataIn; ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, reinterpret_cast<void**>(&dataIn))); *dataIn = 0x12345678; ASSERT_EQ(OK, buffer->unlock()); IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE); ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); IGraphicBufferConsumer::BufferItem item; ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0)); uint32_t* dataOut; ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); IGraphicBufferProducer::QueueBufferOutput qbo; Loading Loading @@ -109,6 +171,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { } TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); Loading @@ -125,6 +188,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) } TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); Loading @@ -139,6 +203,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { } TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; Loading Loading @@ -187,9 +252,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; Loading Loading @@ -243,9 +310,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); ASSERT_EQ(OK, buffer->unlock()); } TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { createBufferQueue(); sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; Loading Loading @@ -283,6 +352,7 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } } // namespace android