blob: 31c6ef007ca4557c67eac9ca4c0b6ca3aa87c114 [file] [log] [blame]
Tianyu0229d252018-10-12 13:50:09 -07001#include <errno.h>
Fan Xubb094a52018-10-26 15:05:02 -07002
3#include <private/dvr/IBufferHub.h>
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -07004#include <private/dvr/buffer_hub_defs.h>
Fan Xu74df4902018-09-20 16:40:51 -07005#include <private/dvr/buffer_node.h>
Fan Xubb094a52018-10-26 15:05:02 -07006#include <ui/GraphicBufferAllocator.h>
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -07007
8namespace android {
9namespace dvr {
10
Tianyu0229d252018-10-12 13:50:09 -070011void BufferNode::InitializeMetadata() {
12 // Using placement new here to reuse shared memory instead of new allocation
13 // Initialize the atomic variables to zero.
14 BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header();
15 buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint64_t>(0);
16 fence_state_ = new (&metadata_header->fence_state) std::atomic<uint64_t>(0);
17 active_clients_bit_mask_ =
18 new (&metadata_header->active_clients_bit_mask) std::atomic<uint64_t>(0);
19}
20
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070021// Allocates a new BufferNode.
22BufferNode::BufferNode(uint32_t width, uint32_t height, uint32_t layer_count,
23 uint32_t format, uint64_t usage,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070024 size_t user_metadata_size) {
Fan Xubb094a52018-10-26 15:05:02 -070025 uint32_t out_stride = 0;
26 // graphicBufferId is not used in GraphicBufferAllocator::allocate
27 int ret = GraphicBufferAllocator::get().allocate(
28 width, height, format, layer_count, usage,
29 const_cast<const native_handle_t**>(&buffer_handle_), &out_stride,
30 /*graphicBufferId=*/0, IBufferHub::getServiceName());
31
32 if (ret != OK || buffer_handle_ == nullptr) {
33 ALOGE("BufferNode::BufferNode: Failed to allocate buffer: %s",
34 strerror(-ret));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070035 return;
36 }
37
Fan Xubb094a52018-10-26 15:05:02 -070038 buffer_desc_.width = width;
39 buffer_desc_.height = height;
40 buffer_desc_.layers = layer_count;
41 buffer_desc_.format = format;
42 buffer_desc_.usage = usage;
43 buffer_desc_.stride = out_stride;
44
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070045 metadata_ = BufferHubMetadata::Create(user_metadata_size);
Fan Xu2cc68fb2018-10-29 13:07:53 -070046 if (!metadata_.IsValid()) {
47 ALOGE("BufferNode::BufferNode: Failed to allocate metadata.");
48 return;
49 }
Tianyu0229d252018-10-12 13:50:09 -070050 InitializeMetadata();
51}
52
Fan Xubb094a52018-10-26 15:05:02 -070053// Free the handle
54BufferNode::~BufferNode() {
55 if (buffer_handle_ != nullptr) {
56 status_t ret = GraphicBufferAllocator::get().free(buffer_handle_);
57 if (ret != OK) {
58 ALOGE("BufferNode::~BufferNode: Failed to free handle; Got error: %d",
59 ret);
60 }
61 }
62}
63
Tianyu0229d252018-10-12 13:50:09 -070064uint64_t BufferNode::GetActiveClientsBitMask() const {
65 return active_clients_bit_mask_->load(std::memory_order_acquire);
66}
67
68uint64_t BufferNode::AddNewActiveClientsBitToMask() {
69 uint64_t current_active_clients_bit_mask = GetActiveClientsBitMask();
Tianyu Jiang7e204b72018-10-26 15:39:18 -070070 uint64_t client_state_mask = 0ULL;
Tianyu0229d252018-10-12 13:50:09 -070071 uint64_t updated_active_clients_bit_mask = 0ULL;
72 do {
Tianyu Jiang83a991f2018-10-30 16:59:29 -070073 client_state_mask = BufferHubDefs::FindNextAvailableClientStateMask(
74 current_active_clients_bit_mask);
Tianyu Jiang7e204b72018-10-26 15:39:18 -070075 if (client_state_mask == 0ULL) {
Tianyu0229d252018-10-12 13:50:09 -070076 ALOGE(
77 "BufferNode::AddNewActiveClientsBitToMask: reached the maximum "
78 "mumber of channels per buffer node: 32.");
79 errno = E2BIG;
80 return 0ULL;
81 }
82 updated_active_clients_bit_mask =
Tianyu Jiang7e204b72018-10-26 15:39:18 -070083 current_active_clients_bit_mask | client_state_mask;
Tianyu0229d252018-10-12 13:50:09 -070084 } while (!(active_clients_bit_mask_->compare_exchange_weak(
85 current_active_clients_bit_mask, updated_active_clients_bit_mask,
86 std::memory_order_acq_rel, std::memory_order_acquire)));
Tianyu Jiang7e204b72018-10-26 15:39:18 -070087 return client_state_mask;
Tianyu0229d252018-10-12 13:50:09 -070088}
89
90void BufferNode::RemoveClientsBitFromMask(const uint64_t& value) {
91 active_clients_bit_mask_->fetch_and(~value);
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070092}
93
94} // namespace dvr
95} // namespace android