Enabled shared memory for DetachedBuffer
Bug: 112011098
Bug: 112012812
Bug: 111976433
Bug: 70046255
Test: buffer_hub-test
Change-Id: I5111d08c1de1d1386e6896d3f7aba4e068d1adc4
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 2a962b5..2ab5b65 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -968,8 +968,19 @@
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..
diff --git a/libs/vr/libbufferhub/detached_buffer.cpp b/libs/vr/libbufferhub/detached_buffer.cpp
index 60f11e2..02abd91 100644
--- a/libs/vr/libbufferhub/detached_buffer.cpp
+++ b/libs/vr/libbufferhub/detached_buffer.cpp
@@ -49,7 +49,7 @@
}
int DetachedBuffer::ImportGraphicBuffer() {
- ATRACE_NAME("DetachedBuffer::DetachedBuffer");
+ ATRACE_NAME("DetachedBuffer::ImportGraphicBuffer");
auto status = client_.InvokeRemoteMethod<DetachedBufferRPC::Import>();
if (!status) {
@@ -76,9 +76,53 @@
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;
}
diff --git a/libs/vr/libbufferhub/include/private/dvr/detached_buffer.h b/libs/vr/libbufferhub/include/private/dvr/detached_buffer.h
index 376b53e..1fc011b 100644
--- a/libs/vr/libbufferhub/include/private/dvr/detached_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/detached_buffer.h
@@ -30,8 +30,17 @@
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 @@
// 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_;
};