blob: f50d2920f24b6f7e363ad2ba68818c77ad9955c3 [file] [log] [blame]
Corey Tabakacd52dd92017-04-07 18:03:57 -07001#include <inttypes.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08002#include <poll.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003
4#include <iomanip>
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -07005#include <memory>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08006#include <sstream>
7#include <string>
8#include <thread>
9
Fan Xu74df4902018-09-20 16:40:51 -070010#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080011#include <pdx/default_transport/service_endpoint.h>
12#include <private/dvr/bufferhub_rpc.h>
Fan Xu74df4902018-09-20 16:40:51 -070013#include <private/dvr/buffer_channel.h>
14#include <private/dvr/buffer_hub.h>
15#include <private/dvr/consumer_channel.h>
16#include <private/dvr/producer_channel.h>
17#include <private/dvr/producer_queue_channel.h>
18#include <utils/Trace.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080019
20using android::pdx::Channel;
Corey Tabaka1db8a5d2017-03-22 02:12:52 -070021using android::pdx::ErrorStatus;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080022using android::pdx::Message;
Corey Tabaka1db8a5d2017-03-22 02:12:52 -070023using android::pdx::Status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080024using android::pdx::default_transport::Endpoint;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070025using android::pdx::rpc::DispatchRemoteMethod;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080026
27namespace android {
28namespace dvr {
29
30BufferHubService::BufferHubService()
31 : BASE("BufferHub", Endpoint::Create(BufferHubRPC::kClientPath)) {}
32
33BufferHubService::~BufferHubService() {}
34
Corey Tabaka1db8a5d2017-03-22 02:12:52 -070035bool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080036
37std::string BufferHubService::DumpState(size_t /*max_length*/) {
38 std::ostringstream stream;
39 auto channels = GetChannels<BufferHubChannel>();
40
41 std::sort(channels.begin(), channels.end(),
42 [](const std::shared_ptr<BufferHubChannel>& a,
43 const std::shared_ptr<BufferHubChannel>& b) {
44 return a->buffer_id() < b->buffer_id();
45 });
46
47 stream << "Active Producer Buffers:\n";
48 stream << std::right;
49 stream << std::setw(6) << "Id";
50 stream << " ";
51 stream << std::setw(9) << "Consumers";
52 stream << " ";
53 stream << std::setw(14) << "Geometry";
54 stream << " ";
55 stream << std::setw(6) << "Format";
56 stream << " ";
Corey Tabaka52ea25c2017-09-13 18:02:48 -070057 stream << std::setw(10) << "Usage";
58 stream << " ";
Corey Tabaka52ea25c2017-09-13 18:02:48 -070059 stream << std::setw(18) << "State";
60 stream << " ";
61 stream << std::setw(18) << "Signaled";
62 stream << " ";
63 stream << std::setw(10) << "Index";
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080064 stream << std::endl;
65
66 for (const auto& channel : channels) {
67 if (channel->channel_type() == BufferHubChannel::kProducerType) {
68 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
69
70 stream << std::right;
71 stream << std::setw(6) << info.id;
72 stream << " ";
73 stream << std::setw(9) << info.consumer_count;
74 stream << " ";
75 if (info.format == HAL_PIXEL_FORMAT_BLOB) {
76 std::string size = std::to_string(info.width) + " B";
77 stream << std::setw(14) << size;
78 } else {
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070079 std::string dimensions = std::to_string(info.width) + "x" +
80 std::to_string(info.height) + "x" +
81 std::to_string(info.layer_count);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080082 stream << std::setw(14) << dimensions;
83 }
84 stream << " ";
85 stream << std::setw(6) << info.format;
86 stream << " ";
87 stream << "0x" << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -070088 stream << std::setw(8) << info.usage;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080089 stream << std::dec << std::setfill(' ');
90 stream << " ";
Corey Tabaka52ea25c2017-09-13 18:02:48 -070091 stream << "0x" << std::hex << std::setfill('0');
92 stream << std::setw(16) << info.state;
93 stream << " ";
94 stream << "0x" << std::setw(16) << info.signaled_mask;
95 stream << std::dec << std::setfill(' ');
96 stream << " ";
97 stream << std::setw(8) << info.index;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080098 stream << std::endl;
99 }
Jiwen 'Steve' Cai23c1a732018-03-12 12:16:47 -0700100
101 if (channel->channel_type() == BufferHubChannel::kDetachedBufferType) {
102 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
103
104 stream << std::right;
105 stream << std::setw(6) << info.id;
106 stream << " ";
107 stream << std::setw(9) << "N/A";
108 stream << " ";
109 if (info.format == HAL_PIXEL_FORMAT_BLOB) {
110 std::string size = std::to_string(info.width) + " B";
111 stream << std::setw(14) << size;
112 } else {
113 std::string dimensions = std::to_string(info.width) + "x" +
114 std::to_string(info.height) + "x" +
115 std::to_string(info.layer_count);
116 stream << std::setw(14) << dimensions;
117 }
118 stream << " ";
119 stream << std::setw(6) << info.format;
120 stream << " ";
121 stream << "0x" << std::hex << std::setfill('0');
122 stream << std::setw(8) << info.usage;
123 stream << std::dec << std::setfill(' ');
124 stream << " ";
125 stream << std::setw(9) << "N/A";
126 stream << " ";
127 stream << std::hex << std::setfill(' ');
128 stream << std::setw(18) << "Detached";
129 stream << " ";
130 stream << std::setw(18) << "N/A";
131 stream << " ";
132 stream << std::setw(10) << "N/A";
133 stream << std::endl;
134 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800135 }
136
137 stream << std::endl;
138 stream << "Active Producer Queues:\n";
139 stream << std::right << std::setw(6) << "Id";
Corey Tabaka8a4e6a92017-04-20 13:42:02 -0700140 stream << std::right << std::setw(12) << " Capacity";
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800141 stream << std::right << std::setw(12) << " Consumers";
142 stream << " UsageSetMask";
143 stream << " UsageClearMask";
144 stream << " UsageDenySetMask";
145 stream << " UsageDenyClearMask";
146 stream << " ";
147 stream << std::endl;
148
149 for (const auto& channel : channels) {
150 if (channel->channel_type() == BufferHubChannel::kProducerQueueType) {
151 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
152
153 stream << std::dec << std::setfill(' ');
154 stream << std::right << std::setw(6) << info.id;
155 stream << std::right << std::setw(12) << info.capacity;
156 stream << std::right << std::setw(12) << info.consumer_count;
157 stream << std::setw(5) << std::setfill(' ') << "0x";
158 stream << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700159 stream << std::setw(8) << info.usage_policy.usage_set_mask;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800160 stream << std::setw(7) << std::setfill(' ') << "0x";
161 stream << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700162 stream << std::setw(8) << info.usage_policy.usage_clear_mask;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800163 stream << std::setw(9) << std::setfill(' ') << "0x";
164 stream << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700165 stream << std::setw(8) << info.usage_policy.usage_deny_set_mask;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800166 stream << std::setw(11) << std::setfill(' ') << "0x";
167 stream << std::hex << std::setfill('0');
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700168 stream << std::setw(8) << info.usage_policy.usage_deny_clear_mask;
Corey Tabakacd52dd92017-04-07 18:03:57 -0700169 stream << std::hex << std::setfill('0');
170 stream << std::endl;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800171 }
172 }
173
174 stream << std::endl;
175 stream << "Active Consumer Queues:\n";
176 stream << std::dec << std::setfill(' ');
177 stream << std::right << std::setw(6) << "Id";
178 stream << std::right << std::setw(12) << " Imported";
179 stream << " ";
180 stream << std::endl;
181
182 for (const auto& channel : channels) {
183 if (channel->channel_type() == BufferHubChannel::kConsumerQueueType) {
184 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
185
186 stream << std::right << std::setw(6) << info.id;
187 stream << std::right << std::setw(12) << info.capacity;
Corey Tabakacd52dd92017-04-07 18:03:57 -0700188 stream << std::endl;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800189 }
190 }
191
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700192 stream << std::endl;
193 stream << "Orphaned Consumer Buffers:\n";
194 stream << std::right;
195 stream << std::setw(6) << "Id";
196 stream << " ";
Jiwen 'Steve' Cai2f260332018-02-15 18:39:47 -0800197 stream << std::setw(14) << "Info";
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700198 stream << std::endl;
199
200 for (const auto& channel : channels) {
201 BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
202 // consumer_count is tracked by producer. When it's zero, producer must have
203 // already hung up and the consumer is orphaned.
204 if (channel->channel_type() == BufferHubChannel::kConsumerType &&
205 info.consumer_count == 0) {
206 stream << std::right;
207 stream << std::setw(6) << info.id;
208 stream << " ";
209
210 stream << std::setw(14) << "Orphaned.";
211 stream << (" channel_id=" + std::to_string(channel->channel_id()));
212 stream << std::endl;
213 }
214 }
215
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800216 return stream.str();
217}
218
219void BufferHubService::HandleImpulse(Message& message) {
220 ATRACE_NAME("BufferHubService::HandleImpulse");
221 if (auto channel = message.GetChannel<BufferHubChannel>())
222 channel->HandleImpulse(message);
223}
224
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700225pdx::Status<void> BufferHubService::HandleMessage(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800226 ATRACE_NAME("BufferHubService::HandleMessage");
227 auto channel = message.GetChannel<BufferHubChannel>();
228
229 ALOGD_IF(
230 TRACE,
231 "BufferHubService::HandleMessage: channel=%p channel_id=%d opcode=%d",
232 channel.get(), message.GetChannelId(), message.GetOp());
233
234 // If the channel is already set up, let it handle the message.
235 if (channel && !channel->HandleMessage(message))
236 return DefaultHandleMessage(message);
237
238 // This channel has not been set up yet, the following are valid operations.
239 switch (message.GetOp()) {
240 case BufferHubRPC::CreateBuffer::Opcode:
241 DispatchRemoteMethod<BufferHubRPC::CreateBuffer>(
242 *this, &BufferHubService::OnCreateBuffer, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700243 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800244
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700245 case DetachedBufferRPC::Create::Opcode:
246 DispatchRemoteMethod<DetachedBufferRPC::Create>(
247 *this, &BufferHubService::OnCreateDetachedBuffer, message);
248 return {};
249
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800250 case BufferHubRPC::CreateProducerQueue::Opcode:
251 DispatchRemoteMethod<BufferHubRPC::CreateProducerQueue>(
252 *this, &BufferHubService::OnCreateProducerQueue, message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700253 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800254
255 default:
256 return DefaultHandleMessage(message);
257 }
258}
259
Corey Tabakacd52dd92017-04-07 18:03:57 -0700260Status<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
261 uint32_t height, uint32_t format,
Jiwen 'Steve' Cai0057fdd2017-05-02 11:21:18 -0700262 uint64_t usage,
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700263 size_t meta_size_bytes) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800264 // Use the producer channel id as the global buffer id.
265 const int buffer_id = message.GetChannelId();
266 ALOGD_IF(TRACE,
Corey Tabakacd52dd92017-04-07 18:03:57 -0700267 "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
Hendrik Wagenaar4d3590f2017-05-06 22:36:04 -0700268 "format=%u usage=%" PRIx64 " meta_size_bytes=%zu",
269 buffer_id, width, height, format, usage, meta_size_bytes);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800270
271 // See if this channel is already attached to a buffer.
272 if (const auto channel = message.GetChannel<BufferHubChannel>()) {
273 ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
274 buffer_id);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700275 return ErrorStatus(EALREADY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800276 }
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700277 const uint32_t kDefaultLayerCount = 1;
278 auto status = ProducerChannel::Create(this, buffer_id, width, height,
279 kDefaultLayerCount, format, usage,
280 meta_size_bytes);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700281 if (status) {
282 message.SetChannel(status.take());
283 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800284 } else {
Corey Tabakacd52dd92017-04-07 18:03:57 -0700285 ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
286 status.GetErrorMessage().c_str());
287 return status.error_status();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800288 }
289}
290
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700291pdx::Status<void> BufferHubService::OnCreateDetachedBuffer(
292 pdx::Message& message, uint32_t width, uint32_t height,
293 uint32_t layer_count, uint32_t format, uint64_t usage,
294 size_t user_metadata_size) {
295 // Use the producer channel id as the global buffer id.
296 const int buffer_id = message.GetChannelId();
297 ALOGD_IF(TRACE,
298 "BufferHubService::OnCreateDetachedBuffer: buffer_id=%d width=%u "
299 "height=%u layer_count=%u format=%u usage=%" PRIx64
300 " user_metadata_size=%zu",
301 buffer_id, width, height, layer_count, format, usage,
302 user_metadata_size);
303
304 // See if this channel is already attached to a buffer.
305 if (const auto channel = message.GetChannel<BufferHubChannel>()) {
306 ALOGE(
307 "BufferHubService::OnCreateDetachedBuffer: Buffer already created: "
308 "buffer=%d",
309 buffer_id);
310 return ErrorStatus(EALREADY);
311 }
312
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700313 std::unique_ptr<BufferChannel> channel =
314 BufferChannel::Create(this, buffer_id, width, height, layer_count, format,
315 usage, user_metadata_size);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700316 if (!channel) {
317 ALOGE(
318 "BufferHubService::OnCreateDetachedBuffer: Failed to allocate buffer, "
319 "buffer=%d.",
320 buffer_id);
321 return ErrorStatus(ENOMEM);
322 }
323
324 message.SetChannel(std::move(channel));
325 return {};
326}
327
Corey Tabaka1db8a5d2017-03-22 02:12:52 -0700328Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
Jiwen 'Steve' Cai6bffc672017-05-18 23:05:05 -0700329 pdx::Message& message, const ProducerQueueConfig& producer_config,
Corey Tabakacd52dd92017-04-07 18:03:57 -0700330 const UsagePolicy& usage_policy) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800331 // Use the producer channel id as the global queue id.
332 const int queue_id = message.GetChannelId();
333 ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
334 queue_id);
335
336 // See if this channel is already attached to another object.
337 if (const auto channel = message.GetChannel<BufferHubChannel>()) {
338 ALOGE("BufferHubService::OnCreateProducerQueue: already created: queue=%d",
339 queue_id);
Corey Tabaka1db8a5d2017-03-22 02:12:52 -0700340 return ErrorStatus(EALREADY);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800341 }
342
Jiwen 'Steve' Cai6bffc672017-05-18 23:05:05 -0700343 auto status = ProducerQueueChannel::Create(this, queue_id, producer_config,
Corey Tabakacd52dd92017-04-07 18:03:57 -0700344 usage_policy);
345 if (status) {
346 message.SetChannel(status.take());
Jiwen 'Steve' Cai6bffc672017-05-18 23:05:05 -0700347 return {{producer_config, queue_id}};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800348 } else {
349 ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
Corey Tabakacd52dd92017-04-07 18:03:57 -0700350 return status.error_status();
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800351 }
352}
353
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800354void BufferHubChannel::SignalAvailable() {
355 ATRACE_NAME("BufferHubChannel::SignalAvailable");
Corey Tabaka3079cb72017-01-19 15:07:26 -0800356 ALOGD_IF(TRACE,
357 "BufferHubChannel::SignalAvailable: channel_id=%d buffer_id=%d",
358 channel_id(), buffer_id());
Jiwen 'Steve' Cai2f260332018-02-15 18:39:47 -0800359 signaled_ = true;
360 const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLIN);
361 ALOGE_IF(!status,
362 "BufferHubChannel::SignalAvailable: failed to signal availability "
363 "channel_id=%d: %s",
364 channel_id_, status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800365}
366
367void BufferHubChannel::ClearAvailable() {
368 ATRACE_NAME("BufferHubChannel::ClearAvailable");
Corey Tabaka3079cb72017-01-19 15:07:26 -0800369 ALOGD_IF(TRACE,
370 "BufferHubChannel::ClearAvailable: channel_id=%d buffer_id=%d",
371 channel_id(), buffer_id());
Jiwen 'Steve' Cai2f260332018-02-15 18:39:47 -0800372 signaled_ = false;
373 const auto status = service_->ModifyChannelEvents(channel_id_, POLLIN, 0);
374 ALOGE_IF(!status,
375 "BufferHubChannel::ClearAvailable: failed to clear availability "
376 "channel_id=%d: %s",
377 channel_id_, status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800378}
379
380void BufferHubChannel::Hangup() {
381 ATRACE_NAME("BufferHubChannel::Hangup");
Corey Tabaka3079cb72017-01-19 15:07:26 -0800382 ALOGD_IF(TRACE, "BufferHubChannel::Hangup: channel_id=%d buffer_id=%d",
383 channel_id(), buffer_id());
Jiwen 'Steve' Cai2f260332018-02-15 18:39:47 -0800384 const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLHUP);
385 ALOGE_IF(
386 !status,
387 "BufferHubChannel::Hangup: failed to signal hangup channel_id=%d: %s",
388 channel_id_, status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800389}
390
391} // namespace dvr
392} // namespace android