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

Commit f326fcec authored by Jiwen 'Steve' Cai's avatar Jiwen 'Steve' Cai
Browse files

Enabled shared memory for DetachedBuffer

Bug: 112011098
Bug: 112012812
Bug: 111976433
Bug: 70046255
Test: buffer_hub-test
Change-Id: I5111d08c1de1d1386e6896d3f7aba4e068d1adc4
parent f5a824e8
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -968,8 +968,19 @@ TEST_F(LibBufferHubTest, TestDuplicateDetachedBuffer) {
  ASSERT_TRUE(b2 != nullptr);
  int b2_id = b2->id();

  // The duplicated buffer should inherit the same buffer id.
  // These two buffer instances are based on the same physical buffer under the
  // hood, so they should share the same id.
  EXPECT_EQ(b1_id, b2_id);
  // We use buffer_state_bit() to tell those two instances apart.
  EXPECT_NE(b1->buffer_state_bit(), b2->buffer_state_bit());
  EXPECT_NE(b1->buffer_state_bit(), 0ULL);
  EXPECT_NE(b2->buffer_state_bit(), 0ULL);
  EXPECT_NE(b1->buffer_state_bit(), kProducerStateBit);
  EXPECT_NE(b2->buffer_state_bit(), kProducerStateBit);

  // Both buffer instances should be in gained state.
  EXPECT_TRUE(IsBufferGained(b1->buffer_state()));
  EXPECT_TRUE(IsBufferGained(b2->buffer_state()));

  // Promote the detached buffer should fail as b1 is no longer the exclusive
  // owner of the buffer..
+45 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ DetachedBuffer::DetachedBuffer(LocalChannelHandle channel_handle)
}

int DetachedBuffer::ImportGraphicBuffer() {
  ATRACE_NAME("DetachedBuffer::DetachedBuffer");
  ATRACE_NAME("DetachedBuffer::ImportGraphicBuffer");

  auto status = client_.InvokeRemoteMethod<DetachedBufferRPC::Import>();
  if (!status) {
@@ -76,9 +76,53 @@ int DetachedBuffer::ImportGraphicBuffer() {
    return ret;
  }

  // Import the metadata.
  IonBuffer metadata_buffer;
  if (const int ret = buffer_desc.ImportMetadata(&metadata_buffer)) {
    ALOGE("Failed to import metadata buffer, error=%d", ret);
    return ret;
  }
  size_t metadata_buf_size = metadata_buffer.width();
  if (metadata_buf_size < BufferHubDefs::kMetadataHeaderSize) {
    ALOGE("DetachedBuffer::ImportGraphicBuffer: metadata buffer too small: %zu",
          metadata_buf_size);
    return -EINVAL;
  }

  // If all imports succeed, replace the previous buffer and id.
  id_ = buffer_id;
  buffer_ = std::move(ion_buffer);
  metadata_buffer_ = std::move(metadata_buffer);
  user_metadata_size_ = metadata_buf_size - BufferHubDefs::kMetadataHeaderSize;

  void* metadata_ptr = nullptr;
  if (const int ret =
          metadata_buffer_.Lock(BufferHubDefs::kMetadataUsage, /*x=*/0,
                                /*y=*/0, metadata_buf_size,
                                /*height=*/1, &metadata_ptr)) {
    ALOGE("DetachedBuffer::ImportGraphicBuffer: Failed to lock metadata.");
    return ret;
  }

  // TODO(b/112012161) Set up shared fences.

  // Note that here the buffer state is mapped from shared memory as an atomic
  // object. The std::atomic's constructor will not be called so that the
  // original value stored in the memory region can be preserved.
  metadata_header_ = static_cast<BufferHubDefs::MetadataHeader*>(metadata_ptr);
  if (user_metadata_size_) {
    user_metadata_ptr_ = static_cast<void*>(metadata_header_ + 1);
  } else {
    user_metadata_ptr_ = nullptr;
  }

  id_ = buffer_desc.id();
  buffer_state_bit_ = buffer_desc.buffer_state_bit();

  ALOGD_IF(TRACE,
           "DetachedBuffer::ImportGraphicBuffer: id=%d, buffer_state=%" PRIx64
           ".",
           id(), metadata_header_->buffer_state.load());
  return 0;
}

+20 −0
Original line number Diff line number Diff line
@@ -30,8 +30,17 @@ class DetachedBuffer {

  const sp<GraphicBuffer>& buffer() const { return buffer_.buffer(); }

  // Gets ID of the buffer client. All DetachedBuffer clients derived from the
  // same buffer in bufferhubd share the same buffer id.
  int id() const { return id_; }

  // Returns the current value of MetadataHeader::buffer_state.
  uint64_t buffer_state() { return metadata_header_->buffer_state.load(); }

  // A state mask which is unique to a buffer hub client among all its siblings
  // sharing the same concrete graphic buffer.
  uint64_t buffer_state_bit() const { return buffer_state_bit_; }

  // Returns true if the buffer holds an open PDX channels towards bufferhubd.
  bool IsConnected() const { return client_.IsValid(); }

@@ -75,7 +84,18 @@ class DetachedBuffer {

  // Global id for the buffer that is consistent across processes.
  int id_;
  uint64_t buffer_state_bit_;

  // The concrete Ion buffers.
  IonBuffer buffer_;
  IonBuffer metadata_buffer_;

  // buffer metadata.
  size_t user_metadata_size_ = 0;
  BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
  void* user_metadata_ptr_ = nullptr;

  // PDX backend.
  BufferHubClient client_;
};