blob: 589b31a2856ade3b2440e72ac76136c0eb206ba8 [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,
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070016 uint32_t width, uint32_t height,
17 uint32_t layer_count, uint32_t format,
18 uint64_t usage, size_t user_metadata_size)
Fan Xu2cc68fb2018-10-29 13:07:53 -070019 : BufferHubChannel(service, buffer_id, buffer_id, kDetachedBufferType) {
20 buffer_node_ = std::make_shared<BufferNode>(
21 width, height, layer_count, format, usage, user_metadata_size);
22 if (!buffer_node_->IsValid()) {
23 ALOGE("BufferChannel::BufferChannel: Failed to create BufferNode.");
24 return;
25 }
Tianyu Jiang7e204b72018-10-26 15:39:18 -070026 client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070027}
28
29BufferChannel::BufferChannel(BufferHubService* service, int buffer_id,
30 int channel_id,
Tianyu0229d252018-10-12 13:50:09 -070031 std::shared_ptr<BufferNode> buffer_node)
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070032 : BufferHubChannel(service, buffer_id, channel_id, kDetachedBufferType),
Tianyu0229d252018-10-12 13:50:09 -070033 buffer_node_(buffer_node) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -070034 client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
35 if (client_state_mask_ == 0ULL) {
Tianyu0229d252018-10-12 13:50:09 -070036 ALOGE("BufferChannel::BufferChannel: %s", strerror(errno));
37 buffer_node_ = nullptr;
38 }
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070039}
40
41BufferChannel::~BufferChannel() {
42 ALOGD_IF(TRACE, "BufferChannel::~BufferChannel: channel_id=%d buffer_id=%d.",
43 channel_id(), buffer_id());
Tianyu Jiang7e204b72018-10-26 15:39:18 -070044 if (client_state_mask_ != 0ULL) {
45 buffer_node_->RemoveClientsBitFromMask(client_state_mask_);
Tianyu0229d252018-10-12 13:50:09 -070046 }
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070047 Hangup();
48}
49
50BufferHubChannel::BufferInfo BufferChannel::GetBufferInfo() const {
51 return BufferInfo(
Fan Xubb094a52018-10-26 15:05:02 -070052 buffer_id(), /*consumer_count=*/0, buffer_node_->buffer_desc().width,
53 buffer_node_->buffer_desc().height, buffer_node_->buffer_desc().layers,
54 buffer_node_->buffer_desc().format, buffer_node_->buffer_desc().usage,
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070055 /*pending_count=*/0, /*state=*/0, /*signaled_mask=*/0,
56 /*index=*/0);
57}
58
59void BufferChannel::HandleImpulse(Message& /*message*/) {
60 ATRACE_NAME("BufferChannel::HandleImpulse");
61}
62
63bool BufferChannel::HandleMessage(Message& message) {
64 ATRACE_NAME("BufferChannel::HandleMessage");
65 switch (message.GetOp()) {
66 case DetachedBufferRPC::Import::Opcode:
67 DispatchRemoteMethod<DetachedBufferRPC::Import>(
68 *this, &BufferChannel::OnImport, message);
69 return true;
70
71 case DetachedBufferRPC::Duplicate::Opcode:
72 DispatchRemoteMethod<DetachedBufferRPC::Duplicate>(
73 *this, &BufferChannel::OnDuplicate, message);
74 return true;
75
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070076 default:
77 return false;
78 }
79}
80
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070081Status<BufferTraits<BorrowedHandle>> BufferChannel::OnImport(
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070082 Message& /*message*/) {
83 ATRACE_NAME("BufferChannel::OnImport");
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070084 ALOGD_IF(TRACE, "BufferChannel::OnImport: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070085
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070086 // TODO(b/112057680) Move away from the GraphicBuffer-based IonBuffer.
87 return BufferTraits<BorrowedHandle>{
Fan Xubb094a52018-10-26 15:05:02 -070088 /*buffer_handle=*/buffer_node_->buffer_handle(),
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070089 /*metadata_handle=*/buffer_node_->metadata().ashmem_handle().Borrow(),
90 /*id=*/buffer_id(),
Tianyu Jiang7e204b72018-10-26 15:39:18 -070091 /*client_state_mask=*/client_state_mask_,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070092 /*metadata_size=*/buffer_node_->metadata().metadata_size(),
Fan Xubb094a52018-10-26 15:05:02 -070093 /*width=*/buffer_node_->buffer_desc().width,
94 /*height=*/buffer_node_->buffer_desc().height,
95 /*layer_count=*/buffer_node_->buffer_desc().layers,
96 /*format=*/buffer_node_->buffer_desc().format,
97 /*usage=*/buffer_node_->buffer_desc().usage,
98 /*stride=*/buffer_node_->buffer_desc().stride,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070099 /*acquire_fence_fd=*/BorrowedHandle{},
100 /*released_fence_fd=*/BorrowedHandle{}};
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700101}
102
Tianyu0229d252018-10-12 13:50:09 -0700103Status<RemoteChannelHandle> BufferChannel::OnDuplicate(Message& message) {
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700104 ATRACE_NAME("BufferChannel::OnDuplicate");
Tianyu0229d252018-10-12 13:50:09 -0700105 ALOGD_IF(TRACE, "BufferChannel::OnDuplicate: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700106
107 int channel_id;
108 auto status = message.PushChannel(0, nullptr, &channel_id);
Tianyu0229d252018-10-12 13:50:09 -0700109 if (!status.ok()) {
110 ALOGE("BufferChannel::OnDuplicate: Failed to push buffer channel: %s",
111 status.GetErrorMessage().c_str());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700112 return ErrorStatus(ENOMEM);
113 }
114
Tianyu0229d252018-10-12 13:50:09 -0700115 auto channel = std::shared_ptr<BufferChannel>(
116 new BufferChannel(service(), buffer_id(), channel_id, buffer_node_));
117 if (!channel->IsValid()) {
118 ALOGE("BufferChannel::OnDuplicate: Invalid buffer. %s", strerror(errno));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700119 return ErrorStatus(EINVAL);
120 }
121
122 const auto channel_status =
123 service()->SetChannel(channel_id, std::move(channel));
124 if (!channel_status) {
125 // Technically, this should never fail, as we just pushed the channel. Note
126 // that LOG_FATAL will be stripped out in non-debug build.
127 LOG_FATAL(
128 "BufferChannel::OnDuplicate: Failed to set new buffer channel: %s.",
129 channel_status.GetErrorMessage().c_str());
130 }
131
132 return status;
133}
134
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700135} // namespace dvr
136} // namespace android