blob: 6c64bcd27925b3090475d6ba7523941105191426 [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
Fan Xu069e8382018-11-16 16:28:08 -080086 BorrowedHandle ashmem_handle =
87 BorrowedHandle(buffer_node_->metadata().ashmem_fd().get());
88
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070089 // TODO(b/112057680) Move away from the GraphicBuffer-based IonBuffer.
90 return BufferTraits<BorrowedHandle>{
Fan Xubb094a52018-10-26 15:05:02 -070091 /*buffer_handle=*/buffer_node_->buffer_handle(),
Fan Xu069e8382018-11-16 16:28:08 -080092 /*metadata_handle=*/ashmem_handle,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070093 /*id=*/buffer_id(),
Tianyu Jiang7e204b72018-10-26 15:39:18 -070094 /*client_state_mask=*/client_state_mask_,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070095 /*metadata_size=*/buffer_node_->metadata().metadata_size(),
Fan Xubb094a52018-10-26 15:05:02 -070096 /*width=*/buffer_node_->buffer_desc().width,
97 /*height=*/buffer_node_->buffer_desc().height,
98 /*layer_count=*/buffer_node_->buffer_desc().layers,
99 /*format=*/buffer_node_->buffer_desc().format,
100 /*usage=*/buffer_node_->buffer_desc().usage,
101 /*stride=*/buffer_node_->buffer_desc().stride,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700102 /*acquire_fence_fd=*/BorrowedHandle{},
103 /*released_fence_fd=*/BorrowedHandle{}};
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700104}
105
Tianyu0229d252018-10-12 13:50:09 -0700106Status<RemoteChannelHandle> BufferChannel::OnDuplicate(Message& message) {
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700107 ATRACE_NAME("BufferChannel::OnDuplicate");
Tianyu0229d252018-10-12 13:50:09 -0700108 ALOGD_IF(TRACE, "BufferChannel::OnDuplicate: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700109
110 int channel_id;
111 auto status = message.PushChannel(0, nullptr, &channel_id);
Tianyu0229d252018-10-12 13:50:09 -0700112 if (!status.ok()) {
113 ALOGE("BufferChannel::OnDuplicate: Failed to push buffer channel: %s",
114 status.GetErrorMessage().c_str());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700115 return ErrorStatus(ENOMEM);
116 }
117
Tianyu0229d252018-10-12 13:50:09 -0700118 auto channel = std::shared_ptr<BufferChannel>(
119 new BufferChannel(service(), buffer_id(), channel_id, buffer_node_));
120 if (!channel->IsValid()) {
121 ALOGE("BufferChannel::OnDuplicate: Invalid buffer. %s", strerror(errno));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700122 return ErrorStatus(EINVAL);
123 }
124
125 const auto channel_status =
126 service()->SetChannel(channel_id, std::move(channel));
127 if (!channel_status) {
128 // Technically, this should never fail, as we just pushed the channel. Note
129 // that LOG_FATAL will be stripped out in non-debug build.
130 LOG_FATAL(
131 "BufferChannel::OnDuplicate: Failed to set new buffer channel: %s.",
132 channel_status.GetErrorMessage().c_str());
133 }
134
135 return status;
136}
137
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700138} // namespace dvr
139} // namespace android