blob: 695396caf21833c50387aac5ef87a76d0cef48df [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();
Tianyu Jianga99f9112018-12-13 18:23:07 -080035 if (client_state_mask_ == 0U) {
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 Jianga99f9112018-12-13 18:23:07 -080044 if (client_state_mask_ != 0U) {
Tianyu Jiang7e204b72018-10-26 15:39:18 -070045 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,
Tianyu Jiang0cdd2a02018-11-15 10:20:45 -080055 /*state=*/0, /*signaled_mask=*/0, /*index=*/0);
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070056}
57
58void BufferChannel::HandleImpulse(Message& /*message*/) {
59 ATRACE_NAME("BufferChannel::HandleImpulse");
60}
61
62bool BufferChannel::HandleMessage(Message& message) {
63 ATRACE_NAME("BufferChannel::HandleMessage");
64 switch (message.GetOp()) {
65 case DetachedBufferRPC::Import::Opcode:
66 DispatchRemoteMethod<DetachedBufferRPC::Import>(
67 *this, &BufferChannel::OnImport, message);
68 return true;
69
70 case DetachedBufferRPC::Duplicate::Opcode:
71 DispatchRemoteMethod<DetachedBufferRPC::Duplicate>(
72 *this, &BufferChannel::OnDuplicate, message);
73 return true;
74
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070075 default:
76 return false;
77 }
78}
79
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070080Status<BufferTraits<BorrowedHandle>> BufferChannel::OnImport(
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070081 Message& /*message*/) {
82 ATRACE_NAME("BufferChannel::OnImport");
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070083 ALOGD_IF(TRACE, "BufferChannel::OnImport: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070084
Fan Xu069e8382018-11-16 16:28:08 -080085 BorrowedHandle ashmem_handle =
86 BorrowedHandle(buffer_node_->metadata().ashmem_fd().get());
87
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070088 // TODO(b/112057680) Move away from the GraphicBuffer-based IonBuffer.
89 return BufferTraits<BorrowedHandle>{
Fan Xubb094a52018-10-26 15:05:02 -070090 /*buffer_handle=*/buffer_node_->buffer_handle(),
Fan Xu069e8382018-11-16 16:28:08 -080091 /*metadata_handle=*/ashmem_handle,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070092 /*id=*/buffer_id(),
Tianyu Jiang7e204b72018-10-26 15:39:18 -070093 /*client_state_mask=*/client_state_mask_,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070094 /*metadata_size=*/buffer_node_->metadata().metadata_size(),
Fan Xubb094a52018-10-26 15:05:02 -070095 /*width=*/buffer_node_->buffer_desc().width,
96 /*height=*/buffer_node_->buffer_desc().height,
97 /*layer_count=*/buffer_node_->buffer_desc().layers,
98 /*format=*/buffer_node_->buffer_desc().format,
99 /*usage=*/buffer_node_->buffer_desc().usage,
100 /*stride=*/buffer_node_->buffer_desc().stride,
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700101 /*acquire_fence_fd=*/BorrowedHandle{},
102 /*released_fence_fd=*/BorrowedHandle{}};
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700103}
104
Tianyu0229d252018-10-12 13:50:09 -0700105Status<RemoteChannelHandle> BufferChannel::OnDuplicate(Message& message) {
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700106 ATRACE_NAME("BufferChannel::OnDuplicate");
Tianyu0229d252018-10-12 13:50:09 -0700107 ALOGD_IF(TRACE, "BufferChannel::OnDuplicate: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700108
109 int channel_id;
110 auto status = message.PushChannel(0, nullptr, &channel_id);
Tianyu0229d252018-10-12 13:50:09 -0700111 if (!status.ok()) {
112 ALOGE("BufferChannel::OnDuplicate: Failed to push buffer channel: %s",
113 status.GetErrorMessage().c_str());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700114 return ErrorStatus(ENOMEM);
115 }
116
Tianyu0229d252018-10-12 13:50:09 -0700117 auto channel = std::shared_ptr<BufferChannel>(
118 new BufferChannel(service(), buffer_id(), channel_id, buffer_node_));
119 if (!channel->IsValid()) {
120 ALOGE("BufferChannel::OnDuplicate: Invalid buffer. %s", strerror(errno));
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700121 return ErrorStatus(EINVAL);
122 }
123
124 const auto channel_status =
125 service()->SetChannel(channel_id, std::move(channel));
126 if (!channel_status) {
127 // Technically, this should never fail, as we just pushed the channel. Note
128 // that LOG_FATAL will be stripped out in non-debug build.
129 LOG_FATAL(
130 "BufferChannel::OnDuplicate: Failed to set new buffer channel: %s.",
131 channel_status.GetErrorMessage().c_str());
132 }
133
134 return status;
135}
136
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700137} // namespace dvr
138} // namespace android