blob: cc9cf20ff9923a17191709e43dc397993a08f0ce [file] [log] [blame]
Fan Xu74df4902018-09-20 16:40:51 -07001#include <private/dvr/buffer_channel.h>
2#include <private/dvr/producer_channel.h>
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -07003
4using android::pdx::BorrowedHandle;
5using android::pdx::ErrorStatus;
6using android::pdx::Message;
7using android::pdx::RemoteChannelHandle;
8using android::pdx::Status;
9using android::pdx::rpc::DispatchRemoteMethod;
10
11namespace android {
12namespace dvr {
13
14BufferChannel::BufferChannel(BufferHubService* service, int buffer_id,
15 int channel_id, IonBuffer buffer,
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070016 size_t user_metadata_size)
17 : BufferHubChannel(service, buffer_id, channel_id, kDetachedBufferType),
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070018 buffer_node_(
19 std::make_shared<BufferNode>(std::move(buffer), user_metadata_size)),
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070020 buffer_state_bit_(BufferHubDefs::FindFirstClearedBit()) {
21 buffer_node_->set_buffer_state_bit(buffer_state_bit_);
22}
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>(
30 width, height, layer_count, format, usage, user_metadata_size)),
31 buffer_state_bit_(BufferHubDefs::FindFirstClearedBit()) {
32 buffer_node_->set_buffer_state_bit(buffer_state_bit_);
33}
34
35BufferChannel::BufferChannel(BufferHubService* service, int buffer_id,
36 int channel_id,
37 std::shared_ptr<BufferNode> buffer_node,
38 uint64_t buffer_state_bit)
39 : BufferHubChannel(service, buffer_id, channel_id, kDetachedBufferType),
40 buffer_node_(buffer_node),
41 buffer_state_bit_(buffer_state_bit) {
42 buffer_node_->set_buffer_state_bit(buffer_state_bit_);
43}
44
45BufferChannel::~BufferChannel() {
46 ALOGD_IF(TRACE, "BufferChannel::~BufferChannel: channel_id=%d buffer_id=%d.",
47 channel_id(), buffer_id());
48 Hangup();
49}
50
51BufferHubChannel::BufferInfo BufferChannel::GetBufferInfo() const {
52 return BufferInfo(
53 buffer_id(), /*consumer_count=*/0, buffer_node_->buffer().width(),
54 buffer_node_->buffer().height(), buffer_node_->buffer().layer_count(),
55 buffer_node_->buffer().format(), buffer_node_->buffer().usage(),
56 /*pending_count=*/0, /*state=*/0, /*signaled_mask=*/0,
57 /*index=*/0);
58}
59
60void BufferChannel::HandleImpulse(Message& /*message*/) {
61 ATRACE_NAME("BufferChannel::HandleImpulse");
62}
63
64bool BufferChannel::HandleMessage(Message& message) {
65 ATRACE_NAME("BufferChannel::HandleMessage");
66 switch (message.GetOp()) {
67 case DetachedBufferRPC::Import::Opcode:
68 DispatchRemoteMethod<DetachedBufferRPC::Import>(
69 *this, &BufferChannel::OnImport, message);
70 return true;
71
72 case DetachedBufferRPC::Duplicate::Opcode:
73 DispatchRemoteMethod<DetachedBufferRPC::Duplicate>(
74 *this, &BufferChannel::OnDuplicate, message);
75 return true;
76
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070077 default:
78 return false;
79 }
80}
81
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070082Status<BufferTraits<BorrowedHandle>> BufferChannel::OnImport(
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070083 Message& /*message*/) {
84 ATRACE_NAME("BufferChannel::OnImport");
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070085 ALOGD_IF(TRACE, "BufferChannel::OnImport: buffer=%d.", buffer_id());
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -070086
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070087 // TODO(b/112057680) Move away from the GraphicBuffer-based IonBuffer.
88 return BufferTraits<BorrowedHandle>{
89 /*buffer_handle=*/buffer_node_->buffer().handle(),
90 /*metadata_handle=*/buffer_node_->metadata().ashmem_handle().Borrow(),
91 /*id=*/buffer_id(),
92 /*buffer_state_bit=*/buffer_state_bit_,
93 /*metadata_size=*/buffer_node_->metadata().metadata_size(),
94 /*width=*/buffer_node_->buffer().width(),
95 /*height=*/buffer_node_->buffer().height(),
96 /*layer_count=*/buffer_node_->buffer().layer_count(),
97 /*format=*/buffer_node_->buffer().format(),
98 /*usage=*/buffer_node_->buffer().usage(),
99 /*stride=*/buffer_node_->buffer().stride(),
100 /*acquire_fence_fd=*/BorrowedHandle{},
101 /*released_fence_fd=*/BorrowedHandle{}};
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700102}
103
104Status<RemoteChannelHandle> BufferChannel::OnDuplicate(
105 Message& message) {
106 ATRACE_NAME("BufferChannel::OnDuplicate");
107 ALOGD_IF(TRACE, "BufferChannel::OnDuplicate: buffer=%d.",
108 buffer_id());
109
110 int channel_id;
111 auto status = message.PushChannel(0, nullptr, &channel_id);
112 if (!status) {
113 ALOGE(
114 "BufferChannel::OnDuplicate: Failed to push buffer channel: %s",
115 status.GetErrorMessage().c_str());
116 return ErrorStatus(ENOMEM);
117 }
118
119 // Try find the next buffer state bit which has not been claimed by any
120 // other buffers yet.
121 uint64_t buffer_state_bit =
122 BufferHubDefs::FindNextClearedBit(buffer_node_->active_buffer_bit_mask() |
123 BufferHubDefs::kProducerStateBit);
124 if (buffer_state_bit == 0ULL) {
125 ALOGE(
126 "BufferChannel::OnDuplicate: reached the maximum mumber of channels "
127 "per buffer node: 63.");
128 return ErrorStatus(E2BIG);
129 }
130
131 auto channel =
132 std::shared_ptr<BufferChannel>(new BufferChannel(
133 service(), buffer_id(), channel_id, buffer_node_, buffer_state_bit));
134 if (!channel) {
135 ALOGE("BufferChannel::OnDuplicate: Invalid buffer.");
136 return ErrorStatus(EINVAL);
137 }
138
139 const auto channel_status =
140 service()->SetChannel(channel_id, std::move(channel));
141 if (!channel_status) {
142 // Technically, this should never fail, as we just pushed the channel. Note
143 // that LOG_FATAL will be stripped out in non-debug build.
144 LOG_FATAL(
145 "BufferChannel::OnDuplicate: Failed to set new buffer channel: %s.",
146 channel_status.GetErrorMessage().c_str());
147 }
148
149 return status;
150}
151
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700152} // namespace dvr
153} // namespace android