blob: d5e6dfbbef9900899a7026bcfb9c2ced31053d3c [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)
28 : BufferHubChannel(service, buffer_id, buffer_id, kDetachedBufferType),
29 buffer_node_(std::make_shared<BufferNode>(
Tianyu0229d252018-10-12 13:50:09 -070030 width, height, layer_count, format, usage, user_metadata_size)) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -070031 client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070032}
33
34BufferChannel::BufferChannel(BufferHubService* service, int buffer_id,
35 int channel_id,
Tianyu0229d252018-10-12 13:50:09 -070036 std::shared_ptr<BufferNode> buffer_node)
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070037 : BufferHubChannel(service, buffer_id, channel_id, kDetachedBufferType),
Tianyu0229d252018-10-12 13:50:09 -070038 buffer_node_(buffer_node) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -070039 client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
40 if (client_state_mask_ == 0ULL) {
Tianyu0229d252018-10-12 13:50:09 -070041 ALOGE("BufferChannel::BufferChannel: %s", strerror(errno));
42 buffer_node_ = nullptr;
43 }
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070044}
45
46BufferChannel::~BufferChannel() {
47 ALOGD_IF(TRACE, "BufferChannel::~BufferChannel: channel_id=%d buffer_id=%d.",
48 channel_id(), buffer_id());
Tianyu Jiang7e204b72018-10-26 15:39:18 -070049 if (client_state_mask_ != 0ULL) {
50 buffer_node_->RemoveClientsBitFromMask(client_state_mask_);
Tianyu0229d252018-10-12 13:50:09 -070051 }
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070052 Hangup();
53}
54
55BufferHubChannel::BufferInfo BufferChannel::GetBufferInfo() const {
56 return BufferInfo(
57 buffer_id(), /*consumer_count=*/0, buffer_node_->buffer().width(),
58 buffer_node_->buffer().height(), buffer_node_->buffer().layer_count(),
59 buffer_node_->buffer().format(), buffer_node_->buffer().usage(),
60 /*pending_count=*/0, /*state=*/0, /*signaled_mask=*/0,
61 /*index=*/0);
62}
63
64void BufferChannel::HandleImpulse(Message& /*message*/) {
65 ATRACE_NAME("BufferChannel::HandleImpulse");
66}
67
68bool BufferChannel::HandleMessage(Message& message) {
69 ATRACE_NAME("BufferChannel::HandleMessage");
70 switch (message.GetOp()) {
71 case DetachedBufferRPC::Import::Opcode:
72 DispatchRemoteMethod<DetachedBufferRPC::Import>(
73 *this, &BufferChannel::OnImport, message);
74 return true;
75
76 case DetachedBufferRPC::Duplicate::Opcode:
77 DispatchRemoteMethod<DetachedBufferRPC::Duplicate>(
78 *this, &BufferChannel::OnDuplicate, message);
79 return true;
80
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070081 default:
82 return false;
83 }
84}
85
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070086Status<BufferTraits<BorrowedHandle>> BufferChannel::OnImport(
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070087 Message& /*message*/) {
88 ATRACE_NAME("BufferChannel::OnImport");
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070089 ALOGD_IF(TRACE, "BufferChannel::OnImport: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070090
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070091 // TODO(b/112057680) Move away from the GraphicBuffer-based IonBuffer.
92 return BufferTraits<BorrowedHandle>{
93 /*buffer_handle=*/buffer_node_->buffer().handle(),
94 /*metadata_handle=*/buffer_node_->metadata().ashmem_handle().Borrow(),
95 /*id=*/buffer_id(),
Tianyu Jiang7e204b72018-10-26 15:39:18 -070096 /*client_state_mask=*/client_state_mask_,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070097 /*metadata_size=*/buffer_node_->metadata().metadata_size(),
98 /*width=*/buffer_node_->buffer().width(),
99 /*height=*/buffer_node_->buffer().height(),
100 /*layer_count=*/buffer_node_->buffer().layer_count(),
101 /*format=*/buffer_node_->buffer().format(),
102 /*usage=*/buffer_node_->buffer().usage(),
103 /*stride=*/buffer_node_->buffer().stride(),
104 /*acquire_fence_fd=*/BorrowedHandle{},
105 /*released_fence_fd=*/BorrowedHandle{}};
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700106}
107
Tianyu0229d252018-10-12 13:50:09 -0700108Status<RemoteChannelHandle> BufferChannel::OnDuplicate(Message& message) {
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700109 ATRACE_NAME("BufferChannel::OnDuplicate");
Tianyu0229d252018-10-12 13:50:09 -0700110 ALOGD_IF(TRACE, "BufferChannel::OnDuplicate: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700111
112 int channel_id;
113 auto status = message.PushChannel(0, nullptr, &channel_id);
Tianyu0229d252018-10-12 13:50:09 -0700114 if (!status.ok()) {
115 ALOGE("BufferChannel::OnDuplicate: Failed to push buffer channel: %s",
116 status.GetErrorMessage().c_str());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700117 return ErrorStatus(ENOMEM);
118 }
119
Tianyu0229d252018-10-12 13:50:09 -0700120 auto channel = std::shared_ptr<BufferChannel>(
121 new BufferChannel(service(), buffer_id(), channel_id, buffer_node_));
122 if (!channel->IsValid()) {
123 ALOGE("BufferChannel::OnDuplicate: Invalid buffer. %s", strerror(errno));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700124 return ErrorStatus(EINVAL);
125 }
126
127 const auto channel_status =
128 service()->SetChannel(channel_id, std::move(channel));
129 if (!channel_status) {
130 // Technically, this should never fail, as we just pushed the channel. Note
131 // that LOG_FATAL will be stripped out in non-debug build.
132 LOG_FATAL(
133 "BufferChannel::OnDuplicate: Failed to set new buffer channel: %s.",
134 channel_status.GetErrorMessage().c_str());
135 }
136
137 return status;
138}
139
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700140} // namespace dvr
141} // namespace android