Loading libs/vr/libbufferhub/buffer_hub-test.cpp +58 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ using android::dvr::BufferHubDefs::IsBufferPosted; using android::dvr::BufferHubDefs::IsBufferAcquired; using android::dvr::BufferHubDefs::IsBufferReleased; using android::dvr::BufferProducer; using android::pdx::LocalChannelHandle; using android::pdx::LocalHandle; using android::pdx::Status; const int kWidth = 640; const int kHeight = 480; Loading Loading @@ -717,3 +719,59 @@ TEST_F(LibBufferHubTest, TestOrphanedAcquire) { // Producer should be able to gain no matter what. EXPECT_EQ(0, p->GainAsync(&meta, &fence)); } TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) { std::unique_ptr<BufferProducer> p = BufferProducer::Create( kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); std::unique_ptr<BufferConsumer> c = BufferConsumer::Import(p->CreateConsumer()); ASSERT_TRUE(p.get() != nullptr); ASSERT_TRUE(c.get() != nullptr); DvrNativeBufferMetadata metadata; LocalHandle invalid_fence; // Detach in posted state should fail. EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0); auto s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in acquired state should fail. EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in released state should fail. EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence)); EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0); s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in gained state should succeed. EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence)); s1 = p->Detach(); EXPECT_TRUE(s1); LocalChannelHandle detached_buffer = s1.take(); EXPECT_TRUE(detached_buffer.valid()); // Both producer and consumer should have hangup. EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0); auto s2 = p->GetEventMask(POLLHUP); EXPECT_TRUE(s2); EXPECT_EQ(s2.get(), POLLHUP); EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0); s2 = p->GetEventMask(POLLHUP); EXPECT_TRUE(s2); EXPECT_EQ(s2.get(), POLLHUP); auto s3 = p->CreateConsumer(); EXPECT_FALSE(s3); EXPECT_EQ(s3.error(), EOPNOTSUPP); s3 = c->CreateConsumer(); EXPECT_FALSE(s3); EXPECT_EQ(s3.error(), EOPNOTSUPP); } libs/vr/libbufferhub/buffer_hub_client.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -608,5 +608,23 @@ std::unique_ptr<BufferProducer> BufferProducer::Import( : LocalChannelHandle{nullptr, -status.error()}); } Status<LocalChannelHandle> BufferProducer::Detach() { uint64_t buffer_state = buffer_state_->load(); if (!BufferHubDefs::IsBufferGained(buffer_state)) { // Can only detach a BufferProducer when it's in gained state. ALOGW("BufferProducer::Detach: The buffer (id=%d, state=0x%" PRIx64 ") is not in gained state.", id(), buffer_state); return {}; } Status<LocalChannelHandle> status = InvokeRemoteMethod<BufferHubRPC::ProducerBufferDetach>(); ALOGE_IF(!status, "BufferProducer::Detach: Failed to detach buffer (id=%d): %s.", id(), status.GetErrorMessage().c_str()); return status; } } // namespace dvr } // namespace android libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h +8 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,14 @@ class BufferProducer : public pdx::ClientBase<BufferProducer, BufferHubBuffer> { // succeeded, or a negative errno code if local error check fails. int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence); // Detaches a ProducerBuffer from an existing producer/consumer set. Can only // be called when a producer buffer has exclusive access to the buffer (i.e. // in the gain'ed state). On the successful return of the IPC call, a new // LocalChannelHandle representing a detached buffer will be returned and all // existing producer and consumer channels will be closed. Further IPCs // towards those channels will return error. Status<LocalChannelHandle> Detach(); private: friend BASE; Loading libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h +26 −0 Original line number Diff line number Diff line Loading @@ -373,6 +373,10 @@ struct BufferHubRPC { kOpConsumerAcquire, kOpConsumerRelease, kOpConsumerSetIgnore, kOpProducerBufferDetach, kOpConsumerBufferDetach, kOpCreateDetachedBuffer, kOpDetachedBufferPromote, kOpCreateProducerQueue, kOpCreateConsumerQueue, kOpGetQueueInfo, Loading Loading @@ -400,6 +404,28 @@ struct BufferHubRPC { PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease, void(LocalFence release_fence)); PDX_REMOTE_METHOD(ConsumerSetIgnore, kOpConsumerSetIgnore, void(bool ignore)); PDX_REMOTE_METHOD(ProducerBufferDetach, kOpProducerBufferDetach, LocalChannelHandle(Void)); // Detaches a ConsumerBuffer from an existing producer/consumer set. Can only // be called when the consumer is the only consumer and it has exclusive // access to the buffer (i.e. in the acquired'ed state). On the successful // return of the IPC call, a new DetachedBufferChannel handle will be returned // and all existing producer and consumer channels will be closed. Further // IPCs towards those channels will return error. PDX_REMOTE_METHOD(ConsumerBufferDetach, kOpConsumerBufferDetach, LocalChannelHandle(Void)); // Creates a standalone DetachedBuffer not associated with any // producer/consumer set. PDX_REMOTE_METHOD(CreateDetachedBuffer, kOpCreateDetachedBuffer, LocalChannelHandle(Void)); // Promotes a DetachedBuffer to become a ProducerBuffer. Once promoted the // DetachedBuffer channel will be closed automatically on successful IPC // return. Further IPCs towards this channel will return error. PDX_REMOTE_METHOD(DetachedBufferPromote, kOpDetachedBufferPromote, LocalChannelHandle(Void)); // Buffer Queue Methods. PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue, Loading services/vr/bufferhubd/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ sourceFiles = [ "bufferhubd.cpp", "consumer_channel.cpp", "producer_channel.cpp", "detached_buffer_channel.cpp", "consumer_queue_channel.cpp", "producer_queue_channel.cpp", ] Loading Loading
libs/vr/libbufferhub/buffer_hub-test.cpp +58 −0 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ using android::dvr::BufferHubDefs::IsBufferPosted; using android::dvr::BufferHubDefs::IsBufferAcquired; using android::dvr::BufferHubDefs::IsBufferReleased; using android::dvr::BufferProducer; using android::pdx::LocalChannelHandle; using android::pdx::LocalHandle; using android::pdx::Status; const int kWidth = 640; const int kHeight = 480; Loading Loading @@ -717,3 +719,59 @@ TEST_F(LibBufferHubTest, TestOrphanedAcquire) { // Producer should be able to gain no matter what. EXPECT_EQ(0, p->GainAsync(&meta, &fence)); } TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) { std::unique_ptr<BufferProducer> p = BufferProducer::Create( kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t)); std::unique_ptr<BufferConsumer> c = BufferConsumer::Import(p->CreateConsumer()); ASSERT_TRUE(p.get() != nullptr); ASSERT_TRUE(c.get() != nullptr); DvrNativeBufferMetadata metadata; LocalHandle invalid_fence; // Detach in posted state should fail. EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence)); EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0); auto s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in acquired state should fail. EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence)); s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in released state should fail. EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence)); EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0); s1 = p->Detach(); EXPECT_FALSE(s1); // Detach in gained state should succeed. EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence)); s1 = p->Detach(); EXPECT_TRUE(s1); LocalChannelHandle detached_buffer = s1.take(); EXPECT_TRUE(detached_buffer.valid()); // Both producer and consumer should have hangup. EXPECT_GT(RETRY_EINTR(p->Poll(kPollTimeoutMs)), 0); auto s2 = p->GetEventMask(POLLHUP); EXPECT_TRUE(s2); EXPECT_EQ(s2.get(), POLLHUP); EXPECT_GT(RETRY_EINTR(c->Poll(kPollTimeoutMs)), 0); s2 = p->GetEventMask(POLLHUP); EXPECT_TRUE(s2); EXPECT_EQ(s2.get(), POLLHUP); auto s3 = p->CreateConsumer(); EXPECT_FALSE(s3); EXPECT_EQ(s3.error(), EOPNOTSUPP); s3 = c->CreateConsumer(); EXPECT_FALSE(s3); EXPECT_EQ(s3.error(), EOPNOTSUPP); }
libs/vr/libbufferhub/buffer_hub_client.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -608,5 +608,23 @@ std::unique_ptr<BufferProducer> BufferProducer::Import( : LocalChannelHandle{nullptr, -status.error()}); } Status<LocalChannelHandle> BufferProducer::Detach() { uint64_t buffer_state = buffer_state_->load(); if (!BufferHubDefs::IsBufferGained(buffer_state)) { // Can only detach a BufferProducer when it's in gained state. ALOGW("BufferProducer::Detach: The buffer (id=%d, state=0x%" PRIx64 ") is not in gained state.", id(), buffer_state); return {}; } Status<LocalChannelHandle> status = InvokeRemoteMethod<BufferHubRPC::ProducerBufferDetach>(); ALOGE_IF(!status, "BufferProducer::Detach: Failed to detach buffer (id=%d): %s.", id(), status.GetErrorMessage().c_str()); return status; } } // namespace dvr } // namespace android
libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h +8 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,14 @@ class BufferProducer : public pdx::ClientBase<BufferProducer, BufferHubBuffer> { // succeeded, or a negative errno code if local error check fails. int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence); // Detaches a ProducerBuffer from an existing producer/consumer set. Can only // be called when a producer buffer has exclusive access to the buffer (i.e. // in the gain'ed state). On the successful return of the IPC call, a new // LocalChannelHandle representing a detached buffer will be returned and all // existing producer and consumer channels will be closed. Further IPCs // towards those channels will return error. Status<LocalChannelHandle> Detach(); private: friend BASE; Loading
libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h +26 −0 Original line number Diff line number Diff line Loading @@ -373,6 +373,10 @@ struct BufferHubRPC { kOpConsumerAcquire, kOpConsumerRelease, kOpConsumerSetIgnore, kOpProducerBufferDetach, kOpConsumerBufferDetach, kOpCreateDetachedBuffer, kOpDetachedBufferPromote, kOpCreateProducerQueue, kOpCreateConsumerQueue, kOpGetQueueInfo, Loading Loading @@ -400,6 +404,28 @@ struct BufferHubRPC { PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease, void(LocalFence release_fence)); PDX_REMOTE_METHOD(ConsumerSetIgnore, kOpConsumerSetIgnore, void(bool ignore)); PDX_REMOTE_METHOD(ProducerBufferDetach, kOpProducerBufferDetach, LocalChannelHandle(Void)); // Detaches a ConsumerBuffer from an existing producer/consumer set. Can only // be called when the consumer is the only consumer and it has exclusive // access to the buffer (i.e. in the acquired'ed state). On the successful // return of the IPC call, a new DetachedBufferChannel handle will be returned // and all existing producer and consumer channels will be closed. Further // IPCs towards those channels will return error. PDX_REMOTE_METHOD(ConsumerBufferDetach, kOpConsumerBufferDetach, LocalChannelHandle(Void)); // Creates a standalone DetachedBuffer not associated with any // producer/consumer set. PDX_REMOTE_METHOD(CreateDetachedBuffer, kOpCreateDetachedBuffer, LocalChannelHandle(Void)); // Promotes a DetachedBuffer to become a ProducerBuffer. Once promoted the // DetachedBuffer channel will be closed automatically on successful IPC // return. Further IPCs towards this channel will return error. PDX_REMOTE_METHOD(DetachedBufferPromote, kOpDetachedBufferPromote, LocalChannelHandle(Void)); // Buffer Queue Methods. PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue, Loading
services/vr/bufferhubd/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ sourceFiles = [ "bufferhubd.cpp", "consumer_channel.cpp", "producer_channel.cpp", "detached_buffer_channel.cpp", "consumer_queue_channel.cpp", "producer_queue_channel.cpp", ] Loading