blob: cc87e15917b8ebab61accf261df92e49423cd987 [file] [log] [blame]
Fan Xu574a6852018-11-02 13:22:42 -07001#include <errno.h>
2
Fan Xuffde7862018-11-08 16:29:13 -08003#include <bufferhub/BufferHubService.h>
Fan Xu574a6852018-11-02 13:22:42 -07004#include <bufferhub/BufferNode.h>
Fan Xu574a6852018-11-02 13:22:42 -07005#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.
Fan Xud34a80a2018-12-04 11:32:39 -080016 BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header();
Tianyu Jianga99f9112018-12-13 18:23:07 -080017 buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint32_t>(0);
18 fence_state_ = new (&metadata_header->fence_state) std::atomic<uint32_t>(0);
Fan Xu574a6852018-11-02 13:22:42 -070019 active_clients_bit_mask_ =
Tianyu Jianga99f9112018-12-13 18:23:07 -080020 new (&metadata_header->active_clients_bit_mask) std::atomic<uint32_t>(0);
Fan Xu574a6852018-11-02 13:22:42 -070021}
22
23// Allocates a new BufferNode.
24BufferNode::BufferNode(uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
Fan Xuffde7862018-11-08 16:29:13 -080025 uint64_t usage, size_t user_metadata_size, uint32_t id)
26 : mId(id) {
Fan Xu574a6852018-11-02 13:22:42 -070027 uint32_t out_stride = 0;
28 // graphicBufferId is not used in GraphicBufferAllocator::allocate
29 // TODO(b/112338294) After move to the service folder, stop using the
30 // hardcoded service name "bufferhub".
31 int ret = GraphicBufferAllocator::get().allocate(width, height, format, layer_count, usage,
32 const_cast<const native_handle_t**>(
33 &buffer_handle_),
34 &out_stride,
35 /*graphicBufferId=*/0,
36 /*requestor=*/"bufferhub");
37
38 if (ret != OK || buffer_handle_ == nullptr) {
Fan Xu19a3e2b2018-11-12 13:45:33 -080039 ALOGE("%s: Failed to allocate buffer: %s", __FUNCTION__, strerror(-ret));
Fan Xu574a6852018-11-02 13:22:42 -070040 return;
41 }
42
43 buffer_desc_.width = width;
44 buffer_desc_.height = height;
45 buffer_desc_.layers = layer_count;
46 buffer_desc_.format = format;
47 buffer_desc_.usage = usage;
48 buffer_desc_.stride = out_stride;
49
50 metadata_ = BufferHubMetadata::Create(user_metadata_size);
51 if (!metadata_.IsValid()) {
Fan Xu19a3e2b2018-11-12 13:45:33 -080052 ALOGE("%s: Failed to allocate metadata.", __FUNCTION__);
Fan Xu574a6852018-11-02 13:22:42 -070053 return;
54 }
55 InitializeMetadata();
56}
57
Fan Xu574a6852018-11-02 13:22:42 -070058BufferNode::~BufferNode() {
Fan Xuffde7862018-11-08 16:29:13 -080059 // Free the handle
Fan Xu574a6852018-11-02 13:22:42 -070060 if (buffer_handle_ != nullptr) {
61 status_t ret = GraphicBufferAllocator::get().free(buffer_handle_);
62 if (ret != OK) {
Fan Xu19a3e2b2018-11-12 13:45:33 -080063 ALOGE("%s: Failed to free handle; Got error: %d", __FUNCTION__, ret);
Fan Xu574a6852018-11-02 13:22:42 -070064 }
65 }
Fan Xuffde7862018-11-08 16:29:13 -080066
67 // Free the id, if valid
Fan Xu1c16df52018-11-19 16:27:27 -080068 if (id() != BufferHubIdGenerator::kInvalidId) {
69 if (BufferHubIdGenerator::getInstance().freeId(id())) {
Fan Xuffde7862018-11-08 16:29:13 -080070 ALOGI("%s: id #%u is freed.", __FUNCTION__, id());
71 } else {
72 ALOGE("%s: Cannot free nonexistent id #%u", __FUNCTION__, id());
73 }
74 }
Fan Xu574a6852018-11-02 13:22:42 -070075}
76
Tianyu Jianga99f9112018-12-13 18:23:07 -080077uint32_t BufferNode::GetActiveClientsBitMask() const {
Fan Xu574a6852018-11-02 13:22:42 -070078 return active_clients_bit_mask_->load(std::memory_order_acquire);
79}
80
Tianyu Jianga99f9112018-12-13 18:23:07 -080081uint32_t BufferNode::AddNewActiveClientsBitToMask() {
82 uint32_t current_active_clients_bit_mask = GetActiveClientsBitMask();
83 uint32_t client_state_mask = 0U;
84 uint32_t updated_active_clients_bit_mask = 0U;
Fan Xu574a6852018-11-02 13:22:42 -070085 do {
Fan Xud34a80a2018-12-04 11:32:39 -080086 client_state_mask =
87 BufferHubDefs::FindNextAvailableClientStateMask(current_active_clients_bit_mask);
Tianyu Jianga99f9112018-12-13 18:23:07 -080088 if (client_state_mask == 0U) {
Fan Xud34a80a2018-12-04 11:32:39 -080089 ALOGE("%s: reached the maximum number of channels per buffer node: %d.", __FUNCTION__,
90 BufferHubDefs::kMaxNumberOfClients);
Fan Xu574a6852018-11-02 13:22:42 -070091 errno = E2BIG;
Tianyu Jianga99f9112018-12-13 18:23:07 -080092 return 0U;
Fan Xu574a6852018-11-02 13:22:42 -070093 }
94 updated_active_clients_bit_mask = current_active_clients_bit_mask | client_state_mask;
95 } while (!(active_clients_bit_mask_->compare_exchange_weak(current_active_clients_bit_mask,
96 updated_active_clients_bit_mask,
97 std::memory_order_acq_rel,
98 std::memory_order_acquire)));
99 return client_state_mask;
100}
101
Tianyu Jianga99f9112018-12-13 18:23:07 -0800102void BufferNode::RemoveClientsBitFromMask(const uint32_t& value) {
Fan Xu574a6852018-11-02 13:22:42 -0700103 active_clients_bit_mask_->fetch_and(~value);
104}
105
106} // namespace implementation
107} // namespace V1_0
108} // namespace bufferhub
109} // namespace frameworks
110} // namespace android