From d6cb17f84067ac0374ac28ef65f2e862c8cbb167 Mon Sep 17 00:00:00 2001 From: Jiwen 'Steve' Cai Date: Mon, 8 May 2017 16:15:35 -0700 Subject: [PATCH] BufferHubQueue Cleanup 1/ Add support for NATIVE_WINDOW_CONSUMER_IS_PROTECTED 2/ Remove BufferHubQueueConsumer as we don't need it after all 3/ Merge BufferHubQueueCore into BufferHubQueueProducer 4/ Remove redundant |onAsBinder| Bug: 38137120 Test: buffer_hub_queue-test and buffer_hub_queue_producer-test Change-Id: I32bc040f4ce9c6dc9e4382a589fea241870eeb2d --- libs/vr/libbufferhubqueue/Android.bp | 3 +- .../buffer_hub_queue_consumer.cpp | 11 -- .../vr/libbufferhubqueue/buffer_hub_queue_core.cpp | 76 -------- .../buffer_hub_queue_producer.cpp | 212 +++++++++++++-------- .../private/dvr/buffer_hub_queue_consumer.h | 22 --- .../include/private/dvr/buffer_hub_queue_core.h | 159 ---------------- .../private/dvr/buffer_hub_queue_producer.h | 80 +++++++- .../tests/buffer_hub_queue_producer-test.cpp | 3 +- libs/vr/libdvr/dvr_buffer_queue.cpp | 12 +- 9 files changed, 207 insertions(+), 371 deletions(-) delete mode 100644 libs/vr/libbufferhubqueue/buffer_hub_queue_consumer.cpp delete mode 100644 libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp delete mode 100644 libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_consumer.h delete mode 100644 libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_core.h diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp index 2a3f5fc289..0b3b2f0fb9 100644 --- a/libs/vr/libbufferhubqueue/Android.bp +++ b/libs/vr/libbufferhubqueue/Android.bp @@ -14,8 +14,6 @@ sourceFiles = [ "buffer_hub_queue_client.cpp", - "buffer_hub_queue_core.cpp", - "buffer_hub_queue_consumer.cpp", "buffer_hub_queue_producer.cpp", ] @@ -41,6 +39,7 @@ sharedLibraries = [ ] headerLibraries = [ + "libdvr_headers", "libnativebase_headers", ] diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_consumer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_consumer.cpp deleted file mode 100644 index 1ea39946e3..0000000000 --- a/libs/vr/libbufferhubqueue/buffer_hub_queue_consumer.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "include/private/dvr/buffer_hub_queue_consumer.h" - -namespace android { -namespace dvr { - -BufferHubQueueConsumer::BufferHubQueueConsumer( - const std::shared_ptr& core) - : core_(core) {} - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp deleted file mode 100644 index 31cccf0a36..0000000000 --- a/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "include/private/dvr/buffer_hub_queue_core.h" - -#include - -namespace android { -namespace dvr { - -/* static */ -std::shared_ptr BufferHubQueueCore::Create() { - auto core = std::shared_ptr(new BufferHubQueueCore()); - core->producer_ = ProducerQueue::Create(); - return core; -} - -/* static */ -std::shared_ptr BufferHubQueueCore::Create( - const std::shared_ptr& producer) { - if (producer->metadata_size() != sizeof(NativeBufferMetadata)) { - ALOGE( - "BufferHubQueueCore::Create producer's metadata size is different than " - "the size of BufferHubQueueCore::NativeBufferMetadata"); - return nullptr; - } - - auto core = std::shared_ptr(new BufferHubQueueCore()); - core->producer_ = producer; - return core; -} - -BufferHubQueueCore::BufferHubQueueCore() - : generation_number_(0), - dequeue_timeout_ms_(BufferHubQueue::kNoTimeOut), - unique_id_(getUniqueId()) {} - -status_t BufferHubQueueCore::AllocateBuffer(uint32_t width, uint32_t height, - uint32_t layer_count, - PixelFormat format, - uint64_t usage) { - size_t slot; - - // Allocate new buffer through BufferHub and add it into |producer_| queue for - // bookkeeping. - if (producer_->AllocateBuffer(width, height, layer_count, format, usage, - &slot) < 0) { - ALOGE("Failed to allocate new buffer in BufferHub."); - return NO_MEMORY; - } - - auto buffer_producer = producer_->GetBuffer(slot); - - LOG_ALWAYS_FATAL_IF(buffer_producer == nullptr, - "Failed to get buffer producer at slot: %zu", slot); - - buffers_[slot].mBufferProducer = buffer_producer; - - return NO_ERROR; -} - -status_t BufferHubQueueCore::DetachBuffer(size_t slot) { - // Detach the buffer producer via BufferHubRPC. - int ret = producer_->DetachBuffer(slot); - if (ret < 0) { - ALOGE("BufferHubQueueCore::DetachBuffer failed through RPC, ret=%s", - strerror(-ret)); - return ret; - } - - // Reset in memory objects related the the buffer. - buffers_[slot].mBufferProducer = nullptr; - buffers_[slot].mGraphicBuffer = nullptr; - buffers_[slot].mBufferState.detachProducer(); - return NO_ERROR; -} - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp index e0a3a34d2d..87efeedc64 100644 --- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp +++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp @@ -1,5 +1,6 @@ #include "include/private/dvr/buffer_hub_queue_producer.h" +#include #include #include #include @@ -7,17 +8,35 @@ namespace android { namespace dvr { -BufferHubQueueProducer::BufferHubQueueProducer( - const std::shared_ptr& core) - : core_(core) {} +/* static */ +sp BufferHubQueueProducer::Create() { + sp producer = new BufferHubQueueProducer; + producer->queue_ = ProducerQueue::Create(); + return producer; +} + +/* static */ +sp BufferHubQueueProducer::Create( + const std::shared_ptr& queue) { + if (queue->metadata_size() != sizeof(DvrNativeBufferMetadata)) { + ALOGE( + "BufferHubQueueProducer::Create producer's metadata size is different " + "than the size of DvrNativeBufferMetadata"); + return nullptr; + } + + sp producer = new BufferHubQueueProducer; + producer->queue_ = queue; + return producer; +} status_t BufferHubQueueProducer::requestBuffer(int slot, sp* buf) { ALOGD_IF(TRACE, "requestBuffer: slot=%d", slot); - std::unique_lock lock(core_->mutex_); + std::unique_lock lock(mutex_); - if (core_->connected_api_ == BufferHubQueueCore::kNoConnectedApi) { + if (connected_api_ == kNoConnectedApi) { ALOGE("requestBuffer: BufferHubQueueProducer has no connected producer"); return NO_INIT; } @@ -26,23 +45,23 @@ status_t BufferHubQueueProducer::requestBuffer(int slot, ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); return BAD_VALUE; - } else if (!core_->buffers_[slot].mBufferState.isDequeued()) { + } else if (!buffers_[slot].mBufferState.isDequeued()) { ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)", - slot, core_->buffers_[slot].mBufferState.string()); + slot, buffers_[slot].mBufferState.string()); return BAD_VALUE; - } else if (core_->buffers_[slot].mGraphicBuffer != nullptr) { + } else if (buffers_[slot].mGraphicBuffer != nullptr) { ALOGE("requestBuffer: slot %d is not empty.", slot); return BAD_VALUE; - } else if (core_->buffers_[slot].mBufferProducer == nullptr) { + } else if (buffers_[slot].mBufferProducer == nullptr) { ALOGE("requestBuffer: slot %d is not dequeued.", slot); return BAD_VALUE; } - const auto& buffer_producer = core_->buffers_[slot].mBufferProducer; + const auto& buffer_producer = buffers_[slot].mBufferProducer; sp graphic_buffer = buffer_producer->buffer()->buffer(); - core_->buffers_[slot].mGraphicBuffer = graphic_buffer; - core_->buffers_[slot].mRequestBufferCalled = true; + buffers_[slot].mGraphicBuffer = graphic_buffer; + buffers_[slot].mRequestBufferCalled = true; *buf = graphic_buffer; return NO_ERROR; @@ -53,12 +72,12 @@ status_t BufferHubQueueProducer::setMaxDequeuedBufferCount( ALOGD_IF(TRACE, "setMaxDequeuedBufferCount: max_dequeued_buffers=%d", max_dequeued_buffers); - std::unique_lock lock(core_->mutex_); + std::unique_lock lock(mutex_); if (max_dequeued_buffers <= 0 || max_dequeued_buffers > static_cast(BufferHubQueue::kMaxQueueCapacity - - BufferHubQueueCore::kDefaultUndequeuedBuffers)) { + kDefaultUndequeuedBuffers)) { ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]", max_dequeued_buffers, BufferHubQueue::kMaxQueueCapacity); return BAD_VALUE; @@ -67,7 +86,7 @@ status_t BufferHubQueueProducer::setMaxDequeuedBufferCount( // The new dequeued_buffers count should not be violated by the number // of currently dequeued buffers. int dequeued_count = 0; - for (const auto& buf : core_->buffers_) { + for (const auto& buf : buffers_) { if (buf.mBufferState.isDequeued()) { dequeued_count++; } @@ -115,22 +134,21 @@ status_t BufferHubQueueProducer::dequeueBuffer( height, format, usage); status_t ret; - std::unique_lock lock(core_->mutex_); + std::unique_lock lock(mutex_); - if (core_->connected_api_ == BufferHubQueueCore::kNoConnectedApi) { + if (connected_api_ == kNoConnectedApi) { ALOGE("dequeueBuffer: BufferQueue has no connected producer"); return NO_INIT; } const uint32_t kLayerCount = 1; - if (static_cast(core_->producer_->capacity()) < - max_dequeued_buffer_count_ + - BufferHubQueueCore::kDefaultUndequeuedBuffers) { - // Lazy allocation. When the capacity of |core_->producer_| has not reach + if (static_cast(queue_->capacity()) < + max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) { + // Lazy allocation. When the capacity of |queue_| has not reached // |max_dequeued_buffer_count_|, allocate new buffer. // TODO(jwcai) To save memory, the really reasonable thing to do is to go // over existing slots and find first existing one to dequeue. - ret = core_->AllocateBuffer(width, height, kLayerCount, format, usage); + ret = AllocateBuffer(width, height, kLayerCount, format, usage); if (ret < 0) return ret; } @@ -140,8 +158,7 @@ status_t BufferHubQueueProducer::dequeueBuffer( for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) { LocalHandle fence; - auto buffer_status = - core_->producer_->Dequeue(core_->dequeue_timeout_ms_, &slot, &fence); + auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence); buffer_producer = buffer_status.take(); if (!buffer_producer) @@ -164,34 +181,34 @@ status_t BufferHubQueueProducer::dequeueBuffer( buffer_producer->height(), buffer_producer->format()); // Mark the slot as reallocating, so that later we can set // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued. - core_->buffers_[slot].mIsReallocating = true; + buffers_[slot].mIsReallocating = true; - // Detach the old buffer once the allocation before allocating its + // Remove the old buffer once the allocation before allocating its // replacement. - core_->DetachBuffer(slot); + RemoveBuffer(slot); // Allocate a new producer buffer with new buffer configs. Note that if // there are already multiple buffers in the queue, the next one returned - // from |core_->producer_->Dequeue| may not be the new buffer we just - // reallocated. Retry up to BufferHubQueue::kMaxQueueCapacity times. - ret = core_->AllocateBuffer(width, height, kLayerCount, format, usage); + // from |queue_->Dequeue| may not be the new buffer we just reallocated. + // Retry up to BufferHubQueue::kMaxQueueCapacity times. + ret = AllocateBuffer(width, height, kLayerCount, format, usage); if (ret < 0) return ret; } // With the BufferHub backed solution. Buffer slot returned from - // |core_->producer_->Dequeue| is guaranteed to avaiable for producer's use. + // |queue_->Dequeue| is guaranteed to avaiable for producer's use. // It's either in free state (if the buffer has never been used before) or // in queued state (if the buffer has been dequeued and queued back to // BufferHubQueue). // TODO(jwcai) Clean this up, make mBufferState compatible with BufferHub's // model. - LOG_ALWAYS_FATAL_IF((!core_->buffers_[slot].mBufferState.isFree() && - !core_->buffers_[slot].mBufferState.isQueued()), + LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() && + !buffers_[slot].mBufferState.isQueued()), "dequeueBuffer: slot %zu is not free or queued.", slot); - core_->buffers_[slot].mBufferState.freeQueued(); - core_->buffers_[slot].mBufferState.dequeue(); + buffers_[slot].mBufferState.freeQueued(); + buffers_[slot].mBufferState.dequeue(); ALOGD_IF(TRACE, "dequeueBuffer: slot=%zu", slot); // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we @@ -200,9 +217,9 @@ status_t BufferHubQueueProducer::dequeueBuffer( *out_slot = slot; ret = NO_ERROR; - if (core_->buffers_[slot].mIsReallocating) { + if (buffers_[slot].mIsReallocating) { ret |= BUFFER_NEEDS_REALLOCATION; - core_->buffers_[slot].mIsReallocating = false; + buffers_[slot].mIsReallocating = false; } return ret; @@ -267,9 +284,9 @@ status_t BufferHubQueueProducer::queueBuffer(int slot, } status_t ret; - std::unique_lock lock(core_->mutex_); + std::unique_lock lock(mutex_); - if (core_->connected_api_ == BufferHubQueueCore::kNoConnectedApi) { + if (connected_api_ == kNoConnectedApi) { ALOGE("queueBuffer: BufferQueue has no connected producer"); return NO_INIT; } @@ -278,22 +295,22 @@ status_t BufferHubQueueProducer::queueBuffer(int slot, ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); return BAD_VALUE; - } else if (!core_->buffers_[slot].mBufferState.isDequeued()) { + } else if (!buffers_[slot].mBufferState.isDequeued()) { ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)", - slot, core_->buffers_[slot].mBufferState.string()); + slot, buffers_[slot].mBufferState.string()); return BAD_VALUE; - } else if ((!core_->buffers_[slot].mRequestBufferCalled || - core_->buffers_[slot].mGraphicBuffer == nullptr)) { + } else if ((!buffers_[slot].mRequestBufferCalled || + buffers_[slot].mGraphicBuffer == nullptr)) { ALOGE( "queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, " "mGraphicBuffer=%p)", - slot, core_->buffers_[slot].mRequestBufferCalled, - core_->buffers_[slot].mGraphicBuffer.get()); + slot, buffers_[slot].mRequestBufferCalled, + buffers_[slot].mGraphicBuffer.get()); return BAD_VALUE; } // Post the buffer producer with timestamp in the metadata. - const auto& buffer_producer = core_->buffers_[slot].mBufferProducer; + const auto& buffer_producer = buffers_[slot].mBufferProducer; // Check input crop is not out of boundary of current buffer. Rect buffer_rect(buffer_producer->width(), buffer_producer->height()); @@ -306,7 +323,7 @@ status_t BufferHubQueueProducer::queueBuffer(int slot, LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1); - BufferHubQueueCore::NativeBufferMetadata meta_data = {}; + DvrNativeBufferMetadata meta_data = {}; meta_data.timestamp = timestamp; meta_data.is_auto_timestamp = static_cast(is_auto_timestamp); meta_data.dataspace = static_cast(dataspace); @@ -318,7 +335,7 @@ status_t BufferHubQueueProducer::queueBuffer(int slot, meta_data.transform = static_cast(transform); buffer_producer->Post(fence_fd, &meta_data, sizeof(meta_data)); - core_->buffers_[slot].mBufferState.queue(); + buffers_[slot].mBufferState.queue(); output->width = buffer_producer->width(); output->height = buffer_producer->height(); @@ -341,9 +358,9 @@ status_t BufferHubQueueProducer::cancelBuffer(int slot, const sp& fence) { ALOGD_IF(TRACE, __FUNCTION__); - std::unique_lock lock(core_->mutex_); + std::unique_lock lock(mutex_); - if (core_->connected_api_ == BufferHubQueueCore::kNoConnectedApi) { + if (connected_api_ == kNoConnectedApi) { ALOGE("cancelBuffer: BufferQueue has no connected producer"); return NO_INIT; } @@ -352,19 +369,19 @@ status_t BufferHubQueueProducer::cancelBuffer(int slot, ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); return BAD_VALUE; - } else if (!core_->buffers_[slot].mBufferState.isDequeued()) { + } else if (!buffers_[slot].mBufferState.isDequeued()) { ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)", - slot, core_->buffers_[slot].mBufferState.string()); + slot, buffers_[slot].mBufferState.string()); return BAD_VALUE; } else if (fence == nullptr) { ALOGE("cancelBuffer: fence is NULL"); return BAD_VALUE; } - auto buffer_producer = core_->buffers_[slot].mBufferProducer; - core_->producer_->Enqueue(buffer_producer, slot); - core_->buffers_[slot].mBufferState.cancel(); - core_->buffers_[slot].mFence = fence; + auto buffer_producer = buffers_[slot].mBufferProducer; + queue_->Enqueue(buffer_producer, slot); + buffers_[slot].mBufferState.cancel(); + buffers_[slot].mFence = fence; ALOGD_IF(TRACE, "cancelBuffer: slot %d", slot); return NO_ERROR; @@ -373,7 +390,7 @@ status_t BufferHubQueueProducer::cancelBuffer(int slot, status_t BufferHubQueueProducer::query(int what, int* out_value) { ALOGD_IF(TRACE, __FUNCTION__); - std::unique_lock lock(core_->mutex_); + std::unique_lock lock(mutex_); if (out_value == nullptr) { ALOGE("query: out_value was NULL"); @@ -386,19 +403,19 @@ status_t BufferHubQueueProducer::query(int what, int* out_value) { // TODO(b/36187402) This should be the maximum number of buffers that this // producer queue's consumer can acquire. Set to be at least one. Need to // find a way to set from the consumer side. - value = BufferHubQueueCore::kDefaultUndequeuedBuffers; + value = kDefaultUndequeuedBuffers; break; case NATIVE_WINDOW_BUFFER_AGE: value = 0; break; case NATIVE_WINDOW_WIDTH: - value = core_->producer_->default_width(); + value = queue_->default_width(); break; case NATIVE_WINDOW_HEIGHT: - value = core_->producer_->default_height(); + value = queue_->default_height(); break; case NATIVE_WINDOW_FORMAT: - value = core_->producer_->default_format(); + value = queue_->default_format(); break; case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: // BufferHubQueue is always operating in async mode, thus semantically @@ -421,6 +438,11 @@ status_t BufferHubQueueProducer::query(int what, int* out_value) { // there is no way dvr::ConsumerQueue can set it. value = 0; break; + case NATIVE_WINDOW_CONSUMER_IS_PROTECTED: + // In Daydream's implementation, the consumer end (i.e. VR Compostior) + // knows how to handle protected buffers. + value = 1; + break; default: return BAD_VALUE; } @@ -442,9 +464,9 @@ status_t BufferHubQueueProducer::connect( return BAD_VALUE; } - std::unique_lock lock(core_->mutex_); + std::unique_lock lock(mutex_); - if (core_->connected_api_ != BufferHubQueueCore::kNoConnectedApi) { + if (connected_api_ != kNoConnectedApi) { return BAD_VALUE; } @@ -453,10 +475,10 @@ status_t BufferHubQueueProducer::connect( case NATIVE_WINDOW_API_CPU: case NATIVE_WINDOW_API_MEDIA: case NATIVE_WINDOW_API_CAMERA: - core_->connected_api_ = api; + connected_api_ = api; - output->width = core_->producer_->default_width(); - output->height = core_->producer_->default_height(); + output->width = queue_->default_width(); + output->height = queue_->default_height(); // default values, we don't use them yet. output->transformHint = 0; @@ -479,15 +501,15 @@ status_t BufferHubQueueProducer::disconnect(int api, DisconnectMode /*mode*/) { // parameter checks here. ALOGD_IF(TRACE, __FUNCTION__); - std::unique_lock lock(core_->mutex_); + std::unique_lock lock(mutex_); - if (BufferHubQueueCore::kNoConnectedApi == core_->connected_api_) { + if (kNoConnectedApi == connected_api_) { return NO_INIT; - } else if (api != core_->connected_api_) { + } else if (api != connected_api_) { return BAD_VALUE; } - core_->connected_api_ = BufferHubQueueCore::kNoConnectedApi; + connected_api_ = kNoConnectedApi; return NO_ERROR; } @@ -521,8 +543,8 @@ status_t BufferHubQueueProducer::setGenerationNumber( uint32_t generation_number) { ALOGD_IF(TRACE, __FUNCTION__); - std::unique_lock lock(core_->mutex_); - core_->generation_number_ = generation_number; + std::unique_lock lock(mutex_); + generation_number_ = generation_number; return NO_ERROR; } @@ -557,8 +579,8 @@ status_t BufferHubQueueProducer::setAutoRefresh(bool auto_refresh) { status_t BufferHubQueueProducer::setDequeueTimeout(nsecs_t timeout) { ALOGD_IF(TRACE, __FUNCTION__); - std::unique_lock lock(core_->mutex_); - core_->dequeue_timeout_ms_ = static_cast(timeout / (1000 * 1000)); + std::unique_lock lock(mutex_); + dequeue_timeout_ms_ = static_cast(timeout / (1000 * 1000)); return NO_ERROR; } @@ -577,15 +599,45 @@ void BufferHubQueueProducer::getFrameTimestamps( status_t BufferHubQueueProducer::getUniqueId(uint64_t* out_id) const { ALOGD_IF(TRACE, __FUNCTION__); - *out_id = core_->unique_id_; + *out_id = unique_id_; + return NO_ERROR; +} + +status_t BufferHubQueueProducer::AllocateBuffer(uint32_t width, uint32_t height, + uint32_t layer_count, + PixelFormat format, + uint64_t usage) { + size_t slot; + + if (queue_->AllocateBuffer(width, height, layer_count, format, usage, &slot) < + 0) { + ALOGE("Failed to allocate new buffer in BufferHub."); + return NO_MEMORY; + } + + auto buffer_producer = queue_->GetBuffer(slot); + + LOG_ALWAYS_FATAL_IF(buffer_producer == nullptr, + "Failed to get buffer producer at slot: %zu", slot); + + buffers_[slot].mBufferProducer = buffer_producer; + return NO_ERROR; } -IBinder* BufferHubQueueProducer::onAsBinder() { - // BufferHubQueueProducer is a non-binder implementation of - // IGraphicBufferProducer. - ALOGW("BufferHubQueueProducer::onAsBinder is not efficiently supported."); - return this; +status_t BufferHubQueueProducer::RemoveBuffer(size_t slot) { + int ret = queue_->DetachBuffer(slot); + if (ret < 0) { + ALOGE("BufferHubQueueProducer::RemoveBuffer failed through RPC, ret=%s", + strerror(-ret)); + return ret; + } + + // Reset in memory objects related the the buffer. + buffers_[slot].mBufferProducer = nullptr; + buffers_[slot].mGraphicBuffer = nullptr; + buffers_[slot].mBufferState.detachProducer(); + return NO_ERROR; } } // namespace dvr diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_consumer.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_consumer.h deleted file mode 100644 index 8d7bfccd2f..0000000000 --- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_consumer.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_CONSUMER_H_ -#define ANDROID_DVR_BUFFER_HUB_QUEUE_CONSUMER_H_ - -#include - -#include - -namespace android { -namespace dvr { - -class BufferHubQueueConsumer : public IGraphicBufferConsumer { - public: - BufferHubQueueConsumer(const std::shared_ptr& core); - - private: - std::shared_ptr core_; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_BUFFER_HUB_QUEUE_CONSUMER_H_ diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_core.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_core.h deleted file mode 100644 index 180906b241..0000000000 --- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_core.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_CORE_H_ -#define ANDROID_DVR_BUFFER_HUB_QUEUE_CORE_H_ - -#include - -#include -#include -#include - -#include - -namespace android { -namespace dvr { - -class BufferHubQueueCore { - private: - friend class BufferHubQueueProducer; - - public: - static constexpr int kNoConnectedApi = -1; - - // TODO(b/36187402) The actual implementation of BufferHubQueue's consumer - // side logic doesn't limit the number of buffer it can acquire - // simultaneously. We need a way for consumer logic to configure and enforce - // that. - static constexpr int kDefaultUndequeuedBuffers = 1; - - // Create a BufferHubQueueCore instance by creating a new producer queue. - static std::shared_ptr Create(); - - // Create a BufferHubQueueCore instance by importing an existing prodcuer - // queue. - static std::shared_ptr Create( - const std::shared_ptr& producer); - - // The buffer metadata that an Android Surface (a.k.a. ANativeWindow) - // will populate. This must be aligned with the |DvrNativeBufferMetadata| - // defined in |dvr_buffer_queue.h|. Please do not remove, modify, or reorder - // existing data members. If new fields need to be added, please take extra - // care to make sure that new data field is padded properly the size of the - // struct stays same. - // TODO(b/37578558) Move |dvr_api.h| into a header library so that this - // structure won't be copied between |dvr_api.h| and |buffer_hub_qeue_core.h|. - struct NativeBufferMetadata { - // Timestamp of the frame. - int64_t timestamp; - - // Whether the buffer is using auto timestamp. - int32_t is_auto_timestamp; - - // Must be one of the HAL_DATASPACE_XXX value defined in system/graphics.h - int32_t dataspace; - - // Crop extracted from an ACrop or android::Crop object. - int32_t crop_left; - int32_t crop_top; - int32_t crop_right; - int32_t crop_bottom; - - // Must be one of the NATIVE_WINDOW_SCALING_MODE_XXX value defined in - // system/window.h. - int32_t scaling_mode; - - // Must be one of the ANATIVEWINDOW_TRANSFORM_XXX value defined in - // android/native_window.h - int32_t transform; - - // Reserved bytes for so that the struct is forward compatible. - int32_t reserved[16]; - }; - - class NativeBuffer - : public ANativeObjectBase { - public: - explicit NativeBuffer(const std::shared_ptr& buffer) - : buffer_(buffer) { - ANativeWindowBuffer::width = buffer_->width(); - ANativeWindowBuffer::height = buffer_->height(); - ANativeWindowBuffer::stride = buffer_->stride(); - ANativeWindowBuffer::format = buffer_->format(); - ANativeWindowBuffer::usage = buffer_->usage(); - ANativeWindowBuffer::handle = buffer_->buffer()->handle(); - } - - std::shared_ptr buffer() { return buffer_; } - - private: - std::shared_ptr buffer_; - }; - - // Get the unique buffer producer queue backing this BufferHubQueue. - std::shared_ptr GetProducerQueue() { return producer_; } - - private: - using LocalHandle = pdx::LocalHandle; - - struct BufferHubSlot : public BufferSlot { - BufferHubSlot() : mBufferProducer(nullptr), mIsReallocating(false) {} - // BufferSlot comes from android framework, using m prefix to comply with - // the name convention with the reset of data fields from BufferSlot. - std::shared_ptr mBufferProducer; - bool mIsReallocating; - }; - - static String8 getUniqueName() { - static volatile int32_t counter = 0; - return String8::format("unnamed-%d-%d", getpid(), - android_atomic_inc(&counter)); - } - - static uint64_t getUniqueId() { - static std::atomic counter{0}; - static uint64_t id = static_cast(getpid()) << 32; - return id | counter++; - } - - // Private constructor to force use of |Create|. - BufferHubQueueCore(); - - // Allocate a new buffer producer through BufferHub. - int AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count, - PixelFormat format, uint64_t usage); - - // Detach a buffer producer through BufferHub. - int DetachBuffer(size_t slot); - - // Mutex for thread safety. - std::mutex mutex_; - - // Connect client API, should be one of the NATIVE_WINDOW_API_* flags. - int connected_api_{kNoConnectedApi}; - - // |buffers_| stores the buffers that have been dequeued from - // |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets - // filled in with the result of |Dequeue|. - // TODO(jwcai) The buffer allocated to a slot will also be replaced if the - // requested buffer usage or geometry differs from that of the buffer - // allocated to a slot. - BufferHubSlot buffers_[BufferHubQueue::kMaxQueueCapacity]; - - // Concreate implementation backed by BufferHubBuffer. - std::shared_ptr producer_; - - // |generation_number_| stores the current generation number of the attached - // producer. Any attempt to attach a buffer with a different generation - // number will fail. - uint32_t generation_number_; - - // Sets how long dequeueBuffer or attachBuffer will block if a buffer or - // slot is not yet available. The timeout is stored in milliseconds. - int dequeue_timeout_ms_; - - const uint64_t unique_id_; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_BUFFER_HUB_QUEUE_CORE_H_ diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h index bf916bad2d..7890176f04 100644 --- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h +++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h @@ -1,16 +1,29 @@ #ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_PRODUCER_H_ #define ANDROID_DVR_BUFFER_HUB_QUEUE_PRODUCER_H_ -#include - #include +#include namespace android { namespace dvr { -class BufferHubQueueProducer : public BnInterface { +class BufferHubQueueProducer : public BnGraphicBufferProducer { public: - BufferHubQueueProducer(const std::shared_ptr& core); + static constexpr int kNoConnectedApi = -1; + + // TODO(b/36187402) The actual implementation of BufferHubQueue's consumer + // side logic doesn't limit the number of buffer it can acquire + // simultaneously. We need a way for consumer logic to configure and enforce + // that. + static constexpr int kDefaultUndequeuedBuffers = 1; + + // Create a BufferHubQueueProducer instance by creating a new producer queue. + static sp Create(); + + // Create a BufferHubQueueProducer instance by importing an existing prodcuer + // queue. + static sp Create( + const std::shared_ptr& producer); // See |IGraphicBufferProducer::requestBuffer| status_t requestBuffer(int slot, sp* buf) override; @@ -98,14 +111,34 @@ class BufferHubQueueProducer : public BnInterface { // See |IGraphicBufferProducer::getUniqueId| status_t getUniqueId(uint64_t* out_id) const override; - protected: - IBinder* onAsBinder() override; - private: using LocalHandle = pdx::LocalHandle; - // |core_| holds the actually buffer slots. - std::shared_ptr core_; + // Private constructor to force use of |Create|. + BufferHubQueueProducer() {} + + static uint64_t genUniqueId() { + static std::atomic counter{0}; + static uint64_t id = static_cast(getpid()) << 32; + return id | counter++; + } + + // Allocate new buffer through BufferHub and add it into |queue_| for + // bookkeeping. + status_t AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count, + PixelFormat format, uint64_t usage); + + // Remove a buffer via BufferHubRPC. + status_t RemoveBuffer(size_t slot); + + // Concreate implementation backed by BufferHubBuffer. + std::shared_ptr queue_; + + // Mutex for thread safety. + std::mutex mutex_; + + // Connect client API, should be one of the NATIVE_WINDOW_API_* flags. + int connected_api_{kNoConnectedApi}; // |max_buffer_count_| sets the capacity of the underlying buffer queue. int32_t max_buffer_count_{BufferHubQueue::kMaxQueueCapacity}; @@ -113,6 +146,35 @@ class BufferHubQueueProducer : public BnInterface { // |max_dequeued_buffer_count_| set the maximum number of buffers that can // be dequeued at the same momment. int32_t max_dequeued_buffer_count_{1}; + + // Sets how long dequeueBuffer or attachBuffer will block if a buffer or + // slot is not yet available. The timeout is stored in milliseconds. + int dequeue_timeout_ms_{BufferHubQueue::kNoTimeOut}; + + // |generation_number_| stores the current generation number of the attached + // producer. Any attempt to attach a buffer with a different generation + // number will fail. + // TOOD(b/38137191) Currently not used as we don't support + // IGraphicBufferProducer::detachBuffer. + uint32_t generation_number_{0}; + + // |buffers_| stores the buffers that have been dequeued from + // |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets + // filled in with the result of |Dequeue|. + // TODO(jwcai) The buffer allocated to a slot will also be replaced if the + // requested buffer usage or geometry differs from that of the buffer + // allocated to a slot. + struct BufferHubSlot : public BufferSlot { + BufferHubSlot() : mBufferProducer(nullptr), mIsReallocating(false) {} + // BufferSlot comes from android framework, using m prefix to comply with + // the name convention with the reset of data fields from BufferSlot. + std::shared_ptr mBufferProducer; + bool mIsReallocating; + }; + BufferHubSlot buffers_[BufferHubQueue::kMaxQueueCapacity]; + + // A uniqueId used by IGraphicBufferProducer interface. + const uint64_t unique_id_{genUniqueId()}; }; } // namespace dvr diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp index 64034e8800..2b6239f499 100644 --- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp +++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp @@ -92,8 +92,7 @@ class BufferHubQueueProducerTest : public ::testing::Test { ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(), testInfo->name()); - auto core = BufferHubQueueCore::Create(); - mProducer = new BufferHubQueueProducer(core); + mProducer = BufferHubQueueProducer::Create(); ASSERT_TRUE(mProducer != nullptr); mSurface = new Surface(mProducer, true); ASSERT_TRUE(mSurface != nullptr); diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp index 95c0e26421..f668510304 100644 --- a/libs/vr/libdvr/dvr_buffer_queue.cpp +++ b/libs/vr/libdvr/dvr_buffer_queue.cpp @@ -75,16 +75,8 @@ int dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue, // Lazy creation of |native_window|. if (write_queue->native_window == nullptr) { - std::shared_ptr core = - dvr::BufferHubQueueCore::Create(write_queue->producer_queue); - if (core == nullptr) { - ALOGE( - "dvrWriteBufferQueueGetExternalSurface: Failed to create native " - "window."); - return -ENOMEM; - } - - sp gbp = new dvr::BufferHubQueueProducer(core); + sp gbp = + dvr::BufferHubQueueProducer::Create(write_queue->producer_queue); sp surface = new Surface(gbp, true); write_queue->native_window = static_cast(surface.get()); ANativeWindow_acquire(write_queue->native_window); -- 2.11.0