Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27fd1adc authored by Jiwen 'Steve' Cai's avatar Jiwen 'Steve' Cai Committed by android-build-merger
Browse files

Merge "bufferhubd: Add DetachedBufferChannel" into pi-dev

am: 8f7fe1aa

Change-Id: Icac53290af3b2d9f7b9d6149ea1ebf90e475422e
parents 3bb85dac 8f7fe1aa
Loading
Loading
Loading
Loading
+58 −0
Original line number Original line Diff line number Diff line
@@ -25,7 +25,9 @@ using android::dvr::BufferHubDefs::IsBufferPosted;
using android::dvr::BufferHubDefs::IsBufferAcquired;
using android::dvr::BufferHubDefs::IsBufferAcquired;
using android::dvr::BufferHubDefs::IsBufferReleased;
using android::dvr::BufferHubDefs::IsBufferReleased;
using android::dvr::BufferProducer;
using android::dvr::BufferProducer;
using android::pdx::LocalChannelHandle;
using android::pdx::LocalHandle;
using android::pdx::LocalHandle;
using android::pdx::Status;


const int kWidth = 640;
const int kWidth = 640;
const int kHeight = 480;
const int kHeight = 480;
@@ -717,3 +719,59 @@ TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
  // Producer should be able to gain no matter what.
  // Producer should be able to gain no matter what.
  EXPECT_EQ(0, p->GainAsync(&meta, &fence));
  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);
}
+18 −0
Original line number Original line Diff line number Diff line
@@ -608,5 +608,23 @@ std::unique_ptr<BufferProducer> BufferProducer::Import(
                       : LocalChannelHandle{nullptr, -status.error()});
                       : 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 dvr
}  // namespace android
}  // namespace android
+8 −0
Original line number Original line Diff line number Diff line
@@ -217,6 +217,14 @@ class BufferProducer : public pdx::ClientBase<BufferProducer, BufferHubBuffer> {
  // succeeded, or a negative errno code if local error check fails.
  // succeeded, or a negative errno code if local error check fails.
  int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
  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:
 private:
  friend BASE;
  friend BASE;


+26 −0
Original line number Original line Diff line number Diff line
@@ -373,6 +373,10 @@ struct BufferHubRPC {
    kOpConsumerAcquire,
    kOpConsumerAcquire,
    kOpConsumerRelease,
    kOpConsumerRelease,
    kOpConsumerSetIgnore,
    kOpConsumerSetIgnore,
    kOpProducerBufferDetach,
    kOpConsumerBufferDetach,
    kOpCreateDetachedBuffer,
    kOpDetachedBufferPromote,
    kOpCreateProducerQueue,
    kOpCreateProducerQueue,
    kOpCreateConsumerQueue,
    kOpCreateConsumerQueue,
    kOpGetQueueInfo,
    kOpGetQueueInfo,
@@ -400,6 +404,28 @@ struct BufferHubRPC {
  PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease,
  PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease,
                    void(LocalFence release_fence));
                    void(LocalFence release_fence));
  PDX_REMOTE_METHOD(ConsumerSetIgnore, kOpConsumerSetIgnore, void(bool ignore));
  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.
  // Buffer Queue Methods.
  PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
  PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
+1 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@ sourceFiles = [
    "bufferhubd.cpp",
    "bufferhubd.cpp",
    "consumer_channel.cpp",
    "consumer_channel.cpp",
    "producer_channel.cpp",
    "producer_channel.cpp",
    "detached_buffer_channel.cpp",
    "consumer_queue_channel.cpp",
    "consumer_queue_channel.cpp",
    "producer_queue_channel.cpp",
    "producer_queue_channel.cpp",
]
]
Loading