blob: 53dd7027928c5636510988a47055a98845adea3c [file] [log] [blame]
Fan Xu574a6852018-11-02 13:22:42 -07001#include <errno.h>
2
3#include <bufferhub/BufferNode.h>
4#include <private/dvr/buffer_hub_defs.h>
5#include <ui/GraphicBufferAllocator.h>
6
7namespace android {
8namespace frameworks {
9namespace bufferhub {
10namespace V1_0 {
11namespace implementation {
12
13void BufferNode::InitializeMetadata() {
14 // Using placement new here to reuse shared memory instead of new allocation
15 // Initialize the atomic variables to zero.
16 dvr::BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header();
17 buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint64_t>(0);
18 fence_state_ = new (&metadata_header->fence_state) std::atomic<uint64_t>(0);
19 active_clients_bit_mask_ =
20 new (&metadata_header->active_clients_bit_mask) std::atomic<uint64_t>(0);
21}
22
23// Allocates a new BufferNode.
24BufferNode::BufferNode(uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
25 uint64_t usage, size_t user_metadata_size) {
26 uint32_t out_stride = 0;
27 // graphicBufferId is not used in GraphicBufferAllocator::allocate
28 // TODO(b/112338294) After move to the service folder, stop using the
29 // hardcoded service name "bufferhub".
30 int ret = GraphicBufferAllocator::get().allocate(width, height, format, layer_count, usage,
31 const_cast<const native_handle_t**>(
32 &buffer_handle_),
33 &out_stride,
34 /*graphicBufferId=*/0,
35 /*requestor=*/"bufferhub");
36
37 if (ret != OK || buffer_handle_ == nullptr) {
Fan Xu19a3e2b2018-11-12 13:45:33 -080038 ALOGE("%s: Failed to allocate buffer: %s", __FUNCTION__, strerror(-ret));
Fan Xu574a6852018-11-02 13:22:42 -070039 return;
40 }
41
42 buffer_desc_.width = width;
43 buffer_desc_.height = height;
44 buffer_desc_.layers = layer_count;
45 buffer_desc_.format = format;
46 buffer_desc_.usage = usage;
47 buffer_desc_.stride = out_stride;
48
49 metadata_ = BufferHubMetadata::Create(user_metadata_size);
50 if (!metadata_.IsValid()) {
Fan Xu19a3e2b2018-11-12 13:45:33 -080051 ALOGE("%s: Failed to allocate metadata.", __FUNCTION__);
Fan Xu574a6852018-11-02 13:22:42 -070052 return;
53 }
54 InitializeMetadata();
55}
56
57// Free the handle
58BufferNode::~BufferNode() {
59 if (buffer_handle_ != nullptr) {
60 status_t ret = GraphicBufferAllocator::get().free(buffer_handle_);
61 if (ret != OK) {
Fan Xu19a3e2b2018-11-12 13:45:33 -080062 ALOGE("%s: Failed to free handle; Got error: %d", __FUNCTION__, ret);
Fan Xu574a6852018-11-02 13:22:42 -070063 }
64 }
65}
66
67uint64_t BufferNode::GetActiveClientsBitMask() const {
68 return active_clients_bit_mask_->load(std::memory_order_acquire);
69}
70
71uint64_t BufferNode::AddNewActiveClientsBitToMask() {
72 uint64_t current_active_clients_bit_mask = GetActiveClientsBitMask();
73 uint64_t client_state_mask = 0ULL;
74 uint64_t updated_active_clients_bit_mask = 0ULL;
75 do {
76 client_state_mask = dvr::BufferHubDefs::FindNextAvailableClientStateMask(
77 current_active_clients_bit_mask);
78 if (client_state_mask == 0ULL) {
Fan Xu19a3e2b2018-11-12 13:45:33 -080079 ALOGE("%s: reached the maximum number of channels per buffer node: 32.", __FUNCTION__);
Fan Xu574a6852018-11-02 13:22:42 -070080 errno = E2BIG;
81 return 0ULL;
82 }
83 updated_active_clients_bit_mask = current_active_clients_bit_mask | client_state_mask;
84 } while (!(active_clients_bit_mask_->compare_exchange_weak(current_active_clients_bit_mask,
85 updated_active_clients_bit_mask,
86 std::memory_order_acq_rel,
87 std::memory_order_acquire)));
88 return client_state_mask;
89}
90
91void BufferNode::RemoveClientsBitFromMask(const uint64_t& value) {
92 active_clients_bit_mask_->fetch_and(~value);
93}
94
95} // namespace implementation
96} // namespace V1_0
97} // namespace bufferhub
98} // namespace frameworks
99} // namespace android