diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp index 3598a8610..cdd06f315 100644 --- a/libs/gui/IGraphicBufferConsumer.cpp +++ b/libs/gui/IGraphicBufferConsumer.cpp @@ -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(); } @@ -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(b)); +} + +static bool readBoolFromInt(void const*& buffer, size_t& size) { + int32_t i; + FlattenableUtils::read(buffer, size, i); + return static_cast(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; } @@ -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; } @@ -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; } diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 5aa34a575..7943476a6 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -24,7 +24,9 @@ #include +#include #include +#include #include namespace android { @@ -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 serviceManager = defaultServiceManager(); - serviceManager->addService(PRODUCER_NAME, mProducer.get()); - serviceManager->addService(CONSUMER_NAME, mConsumer.get()); } ~BufferQueueTest() { @@ -62,12 +56,13 @@ protected: ASSERT_GE(*bufferCount, 0); } - sp mProducer; - sp mConsumer; -}; + void createBufferQueue() { + BufferQueue::createBufferQueue(&mProducer, &mConsumer); + } -const String16 BufferQueueTest::PRODUCER_NAME = String16("BQTestProducer"); -const String16 BufferQueueTest::CONSUMER_NAME = String16("BQTestConsumer"); + sp mProducer; + sp mConsumer; +}; struct DummyConsumer : public BnConsumerListener { virtual void onFrameAvailable() {} @@ -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 producer; + sp consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + sp 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 serviceManager = defaultServiceManager(); + sp binderProducer = + serviceManager->getService(PRODUCER_NAME); + mProducer = interface_cast(binderProducer); + EXPECT_TRUE(mProducer != NULL); + sp binderConsumer = + serviceManager->getService(CONSUMER_NAME); + mConsumer = interface_cast(binderConsumer); + EXPECT_TRUE(mConsumer != NULL); + + sp 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; + sp 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(&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(&dataOut))); + ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); +} + TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { + createBufferQueue(); sp dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); IGraphicBufferProducer::QueueBufferOutput qbo; @@ -109,6 +171,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { } TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) { + createBufferQueue(); sp dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); @@ -125,6 +188,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) } TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { + createBufferQueue(); sp dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); @@ -139,6 +203,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { } TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { + createBufferQueue(); sp dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; @@ -187,9 +252,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { + createBufferQueue(); sp dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; @@ -243,9 +310,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(OK, buffer->unlock()); } TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { + createBufferQueue(); sp dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; @@ -283,6 +352,7 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, reinterpret_cast(&dataOut))); ASSERT_EQ(*dataOut, 0x12345678); + ASSERT_EQ(OK, item.mGraphicBuffer->unlock()); } } // namespace android