blob: bccfe67c0ca3d4f14be52fc412b5d9fb25c640b1 [file] [log] [blame]
Tianyu0229d252018-10-12 13:50:09 -07001#include <errno.h>
Fan Xu74df4902018-09-20 16:40:51 -07002#include <private/dvr/buffer_channel.h>
3#include <private/dvr/producer_channel.h>
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -07004
5using android::pdx::BorrowedHandle;
6using android::pdx::ErrorStatus;
7using android::pdx::Message;
8using android::pdx::RemoteChannelHandle;
9using android::pdx::Status;
10using android::pdx::rpc::DispatchRemoteMethod;
11
12namespace android {
13namespace dvr {
14
15BufferChannel::BufferChannel(BufferHubService* service, int buffer_id,
16 int channel_id, IonBuffer buffer,
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070017 size_t user_metadata_size)
18 : BufferHubChannel(service, buffer_id, channel_id, kDetachedBufferType),
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070019 buffer_node_(
Tianyu0229d252018-10-12 13:50:09 -070020 std::make_shared<BufferNode>(std::move(buffer), user_metadata_size)) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -070021 client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070022}
23
24BufferChannel::BufferChannel(BufferHubService* service, int buffer_id,
25 uint32_t width, uint32_t height,
26 uint32_t layer_count, uint32_t format,
27 uint64_t usage, size_t user_metadata_size)
Fan Xu2cc68fb2018-10-29 13:07:53 -070028 : BufferHubChannel(service, buffer_id, buffer_id, kDetachedBufferType) {
29 buffer_node_ = std::make_shared<BufferNode>(
30 width, height, layer_count, format, usage, user_metadata_size);
31 if (!buffer_node_->IsValid()) {
32 ALOGE("BufferChannel::BufferChannel: Failed to create BufferNode.");
33 return;
34 }
Tianyu Jiang7e204b72018-10-26 15:39:18 -070035 client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070036}
37
38BufferChannel::BufferChannel(BufferHubService* service, int buffer_id,
39 int channel_id,
Tianyu0229d252018-10-12 13:50:09 -070040 std::shared_ptr<BufferNode> buffer_node)
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070041 : BufferHubChannel(service, buffer_id, channel_id, kDetachedBufferType),
Tianyu0229d252018-10-12 13:50:09 -070042 buffer_node_(buffer_node) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -070043 client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
44 if (client_state_mask_ == 0ULL) {
Tianyu0229d252018-10-12 13:50:09 -070045 ALOGE("BufferChannel::BufferChannel: %s", strerror(errno));
46 buffer_node_ = nullptr;
47 }
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070048}
49
50BufferChannel::~BufferChannel() {
51 ALOGD_IF(TRACE, "BufferChannel::~BufferChannel: channel_id=%d buffer_id=%d.",
52 channel_id(), buffer_id());
Tianyu Jiang7e204b72018-10-26 15:39:18 -070053 if (client_state_mask_ != 0ULL) {
54 buffer_node_->RemoveClientsBitFromMask(client_state_mask_);
Tianyu0229d252018-10-12 13:50:09 -070055 }
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070056 Hangup();
57}
58
59BufferHubChannel::BufferInfo BufferChannel::GetBufferInfo() const {
60 return BufferInfo(
61 buffer_id(), /*consumer_count=*/0, buffer_node_->buffer().width(),
62 buffer_node_->buffer().height(), buffer_node_->buffer().layer_count(),
63 buffer_node_->buffer().format(), buffer_node_->buffer().usage(),
64 /*pending_count=*/0, /*state=*/0, /*signaled_mask=*/0,
65 /*index=*/0);
66}
67
68void BufferChannel::HandleImpulse(Message& /*message*/) {
69 ATRACE_NAME("BufferChannel::HandleImpulse");
70}
71
72bool BufferChannel::HandleMessage(Message& message) {
73 ATRACE_NAME("BufferChannel::HandleMessage");
74 switch (message.GetOp()) {
75 case DetachedBufferRPC::Import::Opcode:
76 DispatchRemoteMethod<DetachedBufferRPC::Import>(
77 *this, &BufferChannel::OnImport, message);
78 return true;
79
80 case DetachedBufferRPC::Duplicate::Opcode:
81 DispatchRemoteMethod<DetachedBufferRPC::Duplicate>(
82 *this, &BufferChannel::OnDuplicate, message);
83 return true;
84
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070085 default:
86 return false;
87 }
88}
89
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070090Status<BufferTraits<BorrowedHandle>> BufferChannel::OnImport(
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070091 Message& /*message*/) {
92 ATRACE_NAME("BufferChannel::OnImport");
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070093 ALOGD_IF(TRACE, "BufferChannel::OnImport: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070094
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070095 // TODO(b/112057680) Move away from the GraphicBuffer-based IonBuffer.
96 return BufferTraits<BorrowedHandle>{
97 /*buffer_handle=*/buffer_node_->buffer().handle(),
98 /*metadata_handle=*/buffer_node_->metadata().ashmem_handle().Borrow(),
99 /*id=*/buffer_id(),
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700100 /*client_state_mask=*/client_state_mask_,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700101 /*metadata_size=*/buffer_node_->metadata().metadata_size(),
102 /*width=*/buffer_node_->buffer().width(),
103 /*height=*/buffer_node_->buffer().height(),
104 /*layer_count=*/buffer_node_->buffer().layer_count(),
105 /*format=*/buffer_node_->buffer().format(),
106 /*usage=*/buffer_node_->buffer().usage(),
107 /*stride=*/buffer_node_->buffer().stride(),
108 /*acquire_fence_fd=*/BorrowedHandle{},
109 /*released_fence_fd=*/BorrowedHandle{}};
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700110}
111
Tianyu0229d252018-10-12 13:50:09 -0700112Status<RemoteChannelHandle> BufferChannel::OnDuplicate(Message& message) {
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700113 ATRACE_NAME("BufferChannel::OnDuplicate");
Tianyu0229d252018-10-12 13:50:09 -0700114 ALOGD_IF(TRACE, "BufferChannel::OnDuplicate: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700115
116 int channel_id;
117 auto status = message.PushChannel(0, nullptr, &channel_id);
Tianyu0229d252018-10-12 13:50:09 -0700118 if (!status.ok()) {
119 ALOGE("BufferChannel::OnDuplicate: Failed to push buffer channel: %s",
120 status.GetErrorMessage().c_str());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700121 return ErrorStatus(ENOMEM);
122 }
123
Tianyu0229d252018-10-12 13:50:09 -0700124 auto channel = std::shared_ptr<BufferChannel>(
125 new BufferChannel(service(), buffer_id(), channel_id, buffer_node_));
126 if (!channel->IsValid()) {
127 ALOGE("BufferChannel::OnDuplicate: Invalid buffer. %s", strerror(errno));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700128 return ErrorStatus(EINVAL);
129 }
130
131 const auto channel_status =
132 service()->SetChannel(channel_id, std::move(channel));
133 if (!channel_status) {
134 // Technically, this should never fail, as we just pushed the channel. Note
135 // that LOG_FATAL will be stripped out in non-debug build.
136 LOG_FATAL(
137 "BufferChannel::OnDuplicate: Failed to set new buffer channel: %s.",
138 channel_status.GetErrorMessage().c_str());
139 }
140
141 return status;
142}
143
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700144} // namespace dvr
145} // namespace android