Loading libs/gui/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ cc_library_shared { "android.hardware.graphics.common@1.1", "libsync", "libbinder", "libbufferhub", "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui. "libpdx_default_transport", "libcutils", Loading @@ -149,6 +150,7 @@ cc_library_shared { "BufferHubProducer.cpp", ], exclude_shared_libs: [ "libbufferhub", "libbufferhubqueue", "libpdx_default_transport", ], Loading libs/gui/BufferHubProducer.cpp +81 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <gui/BufferHubProducer.h> #include <inttypes.h> #include <log/log.h> #include <private/dvr/detached_buffer.h> #include <system/window.h> #include <ui/DetachedBufferHandle.h> Loading Loading @@ -363,13 +364,86 @@ status_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<F return error; } status_t BufferHubProducer::attachBuffer(int* /* out_slot */, const sp<GraphicBuffer>& /* buffer */) { // With this BufferHub backed implementation, we assume (for now) all buffers // are allocated and owned by the BufferHub. Thus the attempt of transfering // ownership of a buffer to the buffer queue is intentionally unsupported. LOG_ALWAYS_FATAL("BufferHubProducer::attachBuffer not supported."); return INVALID_OPERATION; status_t BufferHubProducer::attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) { // In the BufferHub design, all buffers are allocated and owned by the BufferHub. Thus only // GraphicBuffers that are originated from BufferHub can be attached to a BufferHubProducer. ALOGV("queueBuffer: buffer=%p", buffer.get()); if (out_slot == nullptr) { ALOGE("attachBuffer: out_slot cannot be NULL."); return BAD_VALUE; } if (buffer == nullptr || !buffer->isDetachedBuffer()) { ALOGE("attachBuffer: invalid GraphicBuffer."); return BAD_VALUE; } std::unique_lock<std::mutex> lock(mutex_); if (connected_api_ == kNoConnectedApi) { ALOGE("attachBuffer: BufferQueue has no connected producer"); return NO_INIT; } // Before attaching the buffer, caller is supposed to call // IGraphicBufferProducer::setGenerationNumber to inform the // BufferHubProducer the next generation number. if (buffer->getGenerationNumber() != generation_number_) { ALOGE("attachBuffer: Mismatched generation number, buffer: %u, queue: %u.", buffer->getGenerationNumber(), generation_number_); return BAD_VALUE; } // Creates a BufferProducer from the GraphicBuffer. std::unique_ptr<DetachedBufferHandle> detached_handle = buffer->takeDetachedBufferHandle(); if (detached_handle == nullptr) { ALOGE("attachBuffer: DetachedBufferHandle cannot be NULL."); return BAD_VALUE; } auto detached_buffer = DetachedBuffer::Import(std::move(detached_handle->handle())); if (detached_buffer == nullptr) { ALOGE("attachBuffer: DetachedBuffer cannot be NULL."); return BAD_VALUE; } auto status_or_handle = detached_buffer->Promote(); if (!status_or_handle.ok()) { ALOGE("attachBuffer: Failed to promote a DetachedBuffer into a BufferProducer, error=%d.", status_or_handle.error()); return BAD_VALUE; } std::shared_ptr<BufferProducer> buffer_producer = BufferProducer::Import(status_or_handle.take()); if (buffer_producer == nullptr) { ALOGE("attachBuffer: Failed to import BufferProducer."); return BAD_VALUE; } // Adds the BufferProducer into the Queue. auto status_or_slot = queue_->InsertBuffer(buffer_producer); if (!status_or_slot.ok()) { ALOGE("attachBuffer: Failed to insert buffer, error=%d.", status_or_slot.error()); return BAD_VALUE; } size_t slot = status_or_slot.get(); ALOGV("attachBuffer: returning slot %zu.", slot); if (slot >= static_cast<size_t>(max_buffer_count_)) { ALOGE("attachBuffer: Invalid slot: %zu.", slot); return BAD_VALUE; } // The just attached buffer should be in dequeued state according to IGraphicBufferProducer // interface. In BufferHub's language the buffer should be in Gained state. buffers_[slot].mGraphicBuffer = buffer; buffers_[slot].mBufferState.attachProducer(); buffers_[slot].mEglFence = EGL_NO_SYNC_KHR; buffers_[slot].mFence = Fence::NO_FENCE; buffers_[slot].mRequestBufferCalled = true; buffers_[slot].mAcquireCalled = false; buffers_[slot].mNeedsReallocation = false; *out_slot = static_cast<int>(slot); return NO_ERROR; } status_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input, Loading libs/gui/tests/IGraphicBufferProducer_test.cpp +24 −3 Original line number Diff line number Diff line Loading @@ -787,10 +787,31 @@ TEST_P(IGraphicBufferProducerTest, ASSERT_OK(mProducer->disconnect(TEST_API)); if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) { // TODO(b/69981968): Implement BufferHubProducer::attachBuffer ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer)); } TEST_P(IGraphicBufferProducerTest, DetachThenAttach_Succeeds) { int slot = -1; sp<Fence> fence; sp<GraphicBuffer> buffer; setupDequeueRequestBuffer(&slot, &fence, &buffer); ASSERT_TRUE(buffer != nullptr); ASSERT_OK(mProducer->detachBuffer(slot)); EXPECT_OK(buffer->initCheck()); if (GetParam() == USE_BUFFER_HUB_PRODUCER) { // For a GraphicBuffer backed by BufferHub, once detached from an IGBP, it should have // isDetachedBuffer() set. Note that this only applies to BufferHub. EXPECT_TRUE(buffer->isDetachedBuffer()); } else { EXPECT_FALSE(buffer->isDetachedBuffer()); } EXPECT_OK(mProducer->attachBuffer(&slot, buffer)); EXPECT_FALSE(buffer->isDetachedBuffer()); EXPECT_OK(buffer->initCheck()); } #if USE_BUFFER_HUB_AS_BUFFER_QUEUE Loading libs/vr/libbufferhub/buffer_hub_client.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -42,11 +42,13 @@ LocalChannelHandle BufferHubClient::TakeChannelHandle() { BufferHubBuffer::BufferHubBuffer(LocalChannelHandle channel_handle) : Client{pdx::default_transport::ClientChannel::Create( std::move(channel_handle))}, id_(-1) {} id_(-1), cid_(-1) {} BufferHubBuffer::BufferHubBuffer(const std::string& endpoint_path) : Client{pdx::default_transport::ClientChannelFactory::Create( endpoint_path)}, id_(-1) {} id_(-1), cid_(-1) {} BufferHubBuffer::~BufferHubBuffer() { if (metadata_header_ != nullptr) { Loading Loading @@ -136,6 +138,7 @@ int BufferHubBuffer::ImportBuffer() { } id_ = new_id; cid_ = buffer_desc.buffer_cid(); buffer_state_bit_ = buffer_desc.buffer_state_bit(); // Note that here the buffer state is mapped from shared memory as an atomic Loading libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h +7 −0 Original line number Diff line number Diff line Loading @@ -107,8 +107,14 @@ class BufferHubBuffer : public pdx::Client { IonBuffer* buffer() { return &buffer_; } const IonBuffer* buffer() const { return &buffer_; } // Gets ID of the buffer client. All BufferHubBuffer clients derived from the // same buffer in bufferhubd share the same buffer id. int id() const { return id_; } // Gets the channel id of the buffer client. Each BufferHubBuffer client has // its system unique channel id. int cid() const { return cid_; } // Returns the buffer buffer state. uint64_t buffer_state() { return buffer_state_->load(); }; Loading Loading @@ -170,6 +176,7 @@ class BufferHubBuffer : public pdx::Client { // for logging and debugging purposes only and should not be used for lookup // or any other functional purpose as a security precaution. int id_; int cid_; uint64_t buffer_state_bit_{0ULL}; IonBuffer buffer_; IonBuffer metadata_buffer_; Loading Loading
libs/gui/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ cc_library_shared { "android.hardware.graphics.common@1.1", "libsync", "libbinder", "libbufferhub", "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui. "libpdx_default_transport", "libcutils", Loading @@ -149,6 +150,7 @@ cc_library_shared { "BufferHubProducer.cpp", ], exclude_shared_libs: [ "libbufferhub", "libbufferhubqueue", "libpdx_default_transport", ], Loading
libs/gui/BufferHubProducer.cpp +81 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <gui/BufferHubProducer.h> #include <inttypes.h> #include <log/log.h> #include <private/dvr/detached_buffer.h> #include <system/window.h> #include <ui/DetachedBufferHandle.h> Loading Loading @@ -363,13 +364,86 @@ status_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<F return error; } status_t BufferHubProducer::attachBuffer(int* /* out_slot */, const sp<GraphicBuffer>& /* buffer */) { // With this BufferHub backed implementation, we assume (for now) all buffers // are allocated and owned by the BufferHub. Thus the attempt of transfering // ownership of a buffer to the buffer queue is intentionally unsupported. LOG_ALWAYS_FATAL("BufferHubProducer::attachBuffer not supported."); return INVALID_OPERATION; status_t BufferHubProducer::attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) { // In the BufferHub design, all buffers are allocated and owned by the BufferHub. Thus only // GraphicBuffers that are originated from BufferHub can be attached to a BufferHubProducer. ALOGV("queueBuffer: buffer=%p", buffer.get()); if (out_slot == nullptr) { ALOGE("attachBuffer: out_slot cannot be NULL."); return BAD_VALUE; } if (buffer == nullptr || !buffer->isDetachedBuffer()) { ALOGE("attachBuffer: invalid GraphicBuffer."); return BAD_VALUE; } std::unique_lock<std::mutex> lock(mutex_); if (connected_api_ == kNoConnectedApi) { ALOGE("attachBuffer: BufferQueue has no connected producer"); return NO_INIT; } // Before attaching the buffer, caller is supposed to call // IGraphicBufferProducer::setGenerationNumber to inform the // BufferHubProducer the next generation number. if (buffer->getGenerationNumber() != generation_number_) { ALOGE("attachBuffer: Mismatched generation number, buffer: %u, queue: %u.", buffer->getGenerationNumber(), generation_number_); return BAD_VALUE; } // Creates a BufferProducer from the GraphicBuffer. std::unique_ptr<DetachedBufferHandle> detached_handle = buffer->takeDetachedBufferHandle(); if (detached_handle == nullptr) { ALOGE("attachBuffer: DetachedBufferHandle cannot be NULL."); return BAD_VALUE; } auto detached_buffer = DetachedBuffer::Import(std::move(detached_handle->handle())); if (detached_buffer == nullptr) { ALOGE("attachBuffer: DetachedBuffer cannot be NULL."); return BAD_VALUE; } auto status_or_handle = detached_buffer->Promote(); if (!status_or_handle.ok()) { ALOGE("attachBuffer: Failed to promote a DetachedBuffer into a BufferProducer, error=%d.", status_or_handle.error()); return BAD_VALUE; } std::shared_ptr<BufferProducer> buffer_producer = BufferProducer::Import(status_or_handle.take()); if (buffer_producer == nullptr) { ALOGE("attachBuffer: Failed to import BufferProducer."); return BAD_VALUE; } // Adds the BufferProducer into the Queue. auto status_or_slot = queue_->InsertBuffer(buffer_producer); if (!status_or_slot.ok()) { ALOGE("attachBuffer: Failed to insert buffer, error=%d.", status_or_slot.error()); return BAD_VALUE; } size_t slot = status_or_slot.get(); ALOGV("attachBuffer: returning slot %zu.", slot); if (slot >= static_cast<size_t>(max_buffer_count_)) { ALOGE("attachBuffer: Invalid slot: %zu.", slot); return BAD_VALUE; } // The just attached buffer should be in dequeued state according to IGraphicBufferProducer // interface. In BufferHub's language the buffer should be in Gained state. buffers_[slot].mGraphicBuffer = buffer; buffers_[slot].mBufferState.attachProducer(); buffers_[slot].mEglFence = EGL_NO_SYNC_KHR; buffers_[slot].mFence = Fence::NO_FENCE; buffers_[slot].mRequestBufferCalled = true; buffers_[slot].mAcquireCalled = false; buffers_[slot].mNeedsReallocation = false; *out_slot = static_cast<int>(slot); return NO_ERROR; } status_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input, Loading
libs/gui/tests/IGraphicBufferProducer_test.cpp +24 −3 Original line number Diff line number Diff line Loading @@ -787,10 +787,31 @@ TEST_P(IGraphicBufferProducerTest, ASSERT_OK(mProducer->disconnect(TEST_API)); if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) { // TODO(b/69981968): Implement BufferHubProducer::attachBuffer ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer)); } TEST_P(IGraphicBufferProducerTest, DetachThenAttach_Succeeds) { int slot = -1; sp<Fence> fence; sp<GraphicBuffer> buffer; setupDequeueRequestBuffer(&slot, &fence, &buffer); ASSERT_TRUE(buffer != nullptr); ASSERT_OK(mProducer->detachBuffer(slot)); EXPECT_OK(buffer->initCheck()); if (GetParam() == USE_BUFFER_HUB_PRODUCER) { // For a GraphicBuffer backed by BufferHub, once detached from an IGBP, it should have // isDetachedBuffer() set. Note that this only applies to BufferHub. EXPECT_TRUE(buffer->isDetachedBuffer()); } else { EXPECT_FALSE(buffer->isDetachedBuffer()); } EXPECT_OK(mProducer->attachBuffer(&slot, buffer)); EXPECT_FALSE(buffer->isDetachedBuffer()); EXPECT_OK(buffer->initCheck()); } #if USE_BUFFER_HUB_AS_BUFFER_QUEUE Loading
libs/vr/libbufferhub/buffer_hub_client.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -42,11 +42,13 @@ LocalChannelHandle BufferHubClient::TakeChannelHandle() { BufferHubBuffer::BufferHubBuffer(LocalChannelHandle channel_handle) : Client{pdx::default_transport::ClientChannel::Create( std::move(channel_handle))}, id_(-1) {} id_(-1), cid_(-1) {} BufferHubBuffer::BufferHubBuffer(const std::string& endpoint_path) : Client{pdx::default_transport::ClientChannelFactory::Create( endpoint_path)}, id_(-1) {} id_(-1), cid_(-1) {} BufferHubBuffer::~BufferHubBuffer() { if (metadata_header_ != nullptr) { Loading Loading @@ -136,6 +138,7 @@ int BufferHubBuffer::ImportBuffer() { } id_ = new_id; cid_ = buffer_desc.buffer_cid(); buffer_state_bit_ = buffer_desc.buffer_state_bit(); // Note that here the buffer state is mapped from shared memory as an atomic Loading
libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h +7 −0 Original line number Diff line number Diff line Loading @@ -107,8 +107,14 @@ class BufferHubBuffer : public pdx::Client { IonBuffer* buffer() { return &buffer_; } const IonBuffer* buffer() const { return &buffer_; } // Gets ID of the buffer client. All BufferHubBuffer clients derived from the // same buffer in bufferhubd share the same buffer id. int id() const { return id_; } // Gets the channel id of the buffer client. Each BufferHubBuffer client has // its system unique channel id. int cid() const { return cid_; } // Returns the buffer buffer state. uint64_t buffer_state() { return buffer_state_->load(); }; Loading Loading @@ -170,6 +176,7 @@ class BufferHubBuffer : public pdx::Client { // for logging and debugging purposes only and should not be used for lookup // or any other functional purpose as a security precaution. int id_; int cid_; uint64_t buffer_state_bit_{0ULL}; IonBuffer buffer_; IonBuffer metadata_buffer_; Loading