diff options
| author | 2018-11-02 13:22:42 -0700 | |
|---|---|---|
| committer | 2018-11-05 15:40:35 -0800 | |
| commit | 574a6852953ca2b38ed346348a3e88f66fcf90fe (patch) | |
| tree | af6b07a92164d4479efcb06b89ca03bf23947b42 /services/bufferhub/BufferNode.cpp | |
| parent | 6894160b3159973f62d0a73b476d33526258a7a5 (diff) | |
Move BufferNode to libbufferhubservice
BufferNode is a server-side class and should be located in the service
folder. Also, making the old bufferhubd service depending on
libbufferhubservice could solve the dependency problem.
Test: "atest buffer_node-test", "atest buffer_hub-test" passed.
Bug: 118893702
Change-Id: I5fad37d3c0475d6cd4f4e0ed17f911b6777a6868
Diffstat (limited to 'services/bufferhub/BufferNode.cpp')
| -rw-r--r-- | services/bufferhub/BufferNode.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp new file mode 100644 index 0000000000..62583a666d --- /dev/null +++ b/services/bufferhub/BufferNode.cpp @@ -0,0 +1,100 @@ +#include <errno.h> + +#include <bufferhub/BufferNode.h> +#include <private/dvr/buffer_hub_defs.h> +#include <ui/GraphicBufferAllocator.h> + +namespace android { +namespace frameworks { +namespace bufferhub { +namespace V1_0 { +namespace implementation { + +void BufferNode::InitializeMetadata() { + // Using placement new here to reuse shared memory instead of new allocation + // Initialize the atomic variables to zero. + dvr::BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header(); + buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint64_t>(0); + fence_state_ = new (&metadata_header->fence_state) std::atomic<uint64_t>(0); + active_clients_bit_mask_ = + new (&metadata_header->active_clients_bit_mask) std::atomic<uint64_t>(0); +} + +// Allocates a new BufferNode. +BufferNode::BufferNode(uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format, + uint64_t usage, size_t user_metadata_size) { + uint32_t out_stride = 0; + // graphicBufferId is not used in GraphicBufferAllocator::allocate + // TODO(b/112338294) After move to the service folder, stop using the + // hardcoded service name "bufferhub". + int ret = GraphicBufferAllocator::get().allocate(width, height, format, layer_count, usage, + const_cast<const native_handle_t**>( + &buffer_handle_), + &out_stride, + /*graphicBufferId=*/0, + /*requestor=*/"bufferhub"); + + if (ret != OK || buffer_handle_ == nullptr) { + ALOGE("BufferNode::BufferNode: Failed to allocate buffer: %s", strerror(-ret)); + return; + } + + buffer_desc_.width = width; + buffer_desc_.height = height; + buffer_desc_.layers = layer_count; + buffer_desc_.format = format; + buffer_desc_.usage = usage; + buffer_desc_.stride = out_stride; + + metadata_ = BufferHubMetadata::Create(user_metadata_size); + if (!metadata_.IsValid()) { + ALOGE("BufferNode::BufferNode: Failed to allocate metadata."); + return; + } + InitializeMetadata(); +} + +// Free the handle +BufferNode::~BufferNode() { + if (buffer_handle_ != nullptr) { + status_t ret = GraphicBufferAllocator::get().free(buffer_handle_); + if (ret != OK) { + ALOGE("BufferNode::~BufferNode: Failed to free handle; Got error: %d", ret); + } + } +} + +uint64_t BufferNode::GetActiveClientsBitMask() const { + return active_clients_bit_mask_->load(std::memory_order_acquire); +} + +uint64_t BufferNode::AddNewActiveClientsBitToMask() { + uint64_t current_active_clients_bit_mask = GetActiveClientsBitMask(); + uint64_t client_state_mask = 0ULL; + uint64_t updated_active_clients_bit_mask = 0ULL; + do { + client_state_mask = dvr::BufferHubDefs::FindNextAvailableClientStateMask( + current_active_clients_bit_mask); + if (client_state_mask == 0ULL) { + ALOGE("BufferNode::AddNewActiveClientsBitToMask: reached the maximum " + "mumber of channels per buffer node: 32."); + errno = E2BIG; + return 0ULL; + } + updated_active_clients_bit_mask = current_active_clients_bit_mask | client_state_mask; + } while (!(active_clients_bit_mask_->compare_exchange_weak(current_active_clients_bit_mask, + updated_active_clients_bit_mask, + std::memory_order_acq_rel, + std::memory_order_acquire))); + return client_state_mask; +} + +void BufferNode::RemoveClientsBitFromMask(const uint64_t& value) { + active_clients_bit_mask_->fetch_and(~value); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace bufferhub +} // namespace frameworks +} // namespace android |