Home | History | Annotate | Download | only in bufferhubd
      1 #include <inttypes.h>
      2 #include <poll.h>
      3 
      4 #include <iomanip>
      5 #include <memory>
      6 #include <sstream>
      7 #include <string>
      8 #include <thread>
      9 
     10 #include <log/log.h>
     11 #include <pdx/default_transport/service_endpoint.h>
     12 #include <private/dvr/bufferhub_rpc.h>
     13 #include <private/dvr/buffer_hub.h>
     14 #include <private/dvr/consumer_channel.h>
     15 #include <private/dvr/producer_channel.h>
     16 #include <private/dvr/producer_queue_channel.h>
     17 #include <utils/Trace.h>
     18 
     19 using android::pdx::Channel;
     20 using android::pdx::ErrorStatus;
     21 using android::pdx::Message;
     22 using android::pdx::Status;
     23 using android::pdx::default_transport::Endpoint;
     24 using android::pdx::rpc::DispatchRemoteMethod;
     25 
     26 namespace android {
     27 namespace dvr {
     28 
     29 BufferHubService::BufferHubService()
     30     : BASE("BufferHub", Endpoint::Create(BufferHubRPC::kClientPath)) {}
     31 
     32 BufferHubService::~BufferHubService() {}
     33 
     34 bool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); }
     35 
     36 std::string BufferHubService::DumpState(size_t /*max_length*/) {
     37   std::ostringstream stream;
     38   auto channels = GetChannels<BufferHubChannel>();
     39 
     40   std::sort(channels.begin(), channels.end(),
     41             [](const std::shared_ptr<BufferHubChannel>& a,
     42                const std::shared_ptr<BufferHubChannel>& b) {
     43               return a->buffer_id() < b->buffer_id();
     44             });
     45 
     46   stream << "Active Producer Buffers:\n";
     47   stream << std::right;
     48   stream << std::setw(6) << "Id";
     49   stream << " ";
     50   stream << std::setw(9) << "Consumers";
     51   stream << " ";
     52   stream << std::setw(14) << "Geometry";
     53   stream << " ";
     54   stream << std::setw(6) << "Format";
     55   stream << " ";
     56   stream << std::setw(10) << "Usage";
     57   stream << " ";
     58   stream << std::setw(18) << "State";
     59   stream << " ";
     60   stream << std::setw(18) << "Signaled";
     61   stream << " ";
     62   stream << std::setw(10) << "Index";
     63   stream << std::endl;
     64 
     65   for (const auto& channel : channels) {
     66     if (channel->channel_type() == BufferHubChannel::kProducerType) {
     67       BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
     68 
     69       stream << std::right;
     70       stream << std::setw(6) << info.id;
     71       stream << " ";
     72       stream << std::setw(9) << info.consumer_count;
     73       stream << " ";
     74       if (info.format == HAL_PIXEL_FORMAT_BLOB) {
     75         std::string size = std::to_string(info.width) + " B";
     76         stream << std::setw(14) << size;
     77       } else {
     78         std::string dimensions = std::to_string(info.width) + "x" +
     79                                  std::to_string(info.height) + "x" +
     80                                  std::to_string(info.layer_count);
     81         stream << std::setw(14) << dimensions;
     82       }
     83       stream << " ";
     84       stream << std::setw(6) << info.format;
     85       stream << " ";
     86       stream << "0x" << std::hex << std::setfill('0');
     87       stream << std::setw(8) << info.usage;
     88       stream << std::dec << std::setfill(' ');
     89       stream << " ";
     90       stream << "0x" << std::hex << std::setfill('0');
     91       stream << std::setw(16) << info.state;
     92       stream << " ";
     93       stream << "0x" << std::setw(16) << info.signaled_mask;
     94       stream << std::dec << std::setfill(' ');
     95       stream << " ";
     96       stream << std::setw(8) << info.index;
     97       stream << std::endl;
     98     }
     99 
    100     if (channel->channel_type() == BufferHubChannel::kDetachedBufferType) {
    101       BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
    102 
    103       stream << std::right;
    104       stream << std::setw(6) << info.id;
    105       stream << " ";
    106       stream << std::setw(9) << "N/A";
    107       stream << " ";
    108       if (info.format == HAL_PIXEL_FORMAT_BLOB) {
    109         std::string size = std::to_string(info.width) + " B";
    110         stream << std::setw(14) << size;
    111       } else {
    112         std::string dimensions = std::to_string(info.width) + "x" +
    113                                  std::to_string(info.height) + "x" +
    114                                  std::to_string(info.layer_count);
    115         stream << std::setw(14) << dimensions;
    116       }
    117       stream << " ";
    118       stream << std::setw(6) << info.format;
    119       stream << " ";
    120       stream << "0x" << std::hex << std::setfill('0');
    121       stream << std::setw(8) << info.usage;
    122       stream << std::dec << std::setfill(' ');
    123       stream << " ";
    124       stream << std::setw(9) << "N/A";
    125       stream << " ";
    126       stream << std::hex << std::setfill(' ');
    127       stream << std::setw(18) << "Detached";
    128       stream << " ";
    129       stream << std::setw(18) << "N/A";
    130       stream << " ";
    131       stream << std::setw(10) << "N/A";
    132       stream << std::endl;
    133     }
    134   }
    135 
    136   stream << std::endl;
    137   stream << "Active Producer Queues:\n";
    138   stream << std::right << std::setw(6) << "Id";
    139   stream << std::right << std::setw(12) << " Capacity";
    140   stream << std::right << std::setw(12) << " Consumers";
    141   stream << " UsageSetMask";
    142   stream << " UsageClearMask";
    143   stream << " UsageDenySetMask";
    144   stream << " UsageDenyClearMask";
    145   stream << " ";
    146   stream << std::endl;
    147 
    148   for (const auto& channel : channels) {
    149     if (channel->channel_type() == BufferHubChannel::kProducerQueueType) {
    150       BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
    151 
    152       stream << std::dec << std::setfill(' ');
    153       stream << std::right << std::setw(6) << info.id;
    154       stream << std::right << std::setw(12) << info.capacity;
    155       stream << std::right << std::setw(12) << info.consumer_count;
    156       stream << std::setw(5) << std::setfill(' ') << "0x";
    157       stream << std::hex << std::setfill('0');
    158       stream << std::setw(8) << info.usage_policy.usage_set_mask;
    159       stream << std::setw(7) << std::setfill(' ') << "0x";
    160       stream << std::hex << std::setfill('0');
    161       stream << std::setw(8) << info.usage_policy.usage_clear_mask;
    162       stream << std::setw(9) << std::setfill(' ') << "0x";
    163       stream << std::hex << std::setfill('0');
    164       stream << std::setw(8) << info.usage_policy.usage_deny_set_mask;
    165       stream << std::setw(11) << std::setfill(' ') << "0x";
    166       stream << std::hex << std::setfill('0');
    167       stream << std::setw(8) << info.usage_policy.usage_deny_clear_mask;
    168       stream << std::hex << std::setfill('0');
    169       stream << std::endl;
    170     }
    171   }
    172 
    173   stream << std::endl;
    174   stream << "Active Consumer Queues:\n";
    175   stream << std::dec << std::setfill(' ');
    176   stream << std::right << std::setw(6) << "Id";
    177   stream << std::right << std::setw(12) << " Imported";
    178   stream << " ";
    179   stream << std::endl;
    180 
    181   for (const auto& channel : channels) {
    182     if (channel->channel_type() == BufferHubChannel::kConsumerQueueType) {
    183       BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
    184 
    185       stream << std::right << std::setw(6) << info.id;
    186       stream << std::right << std::setw(12) << info.capacity;
    187       stream << std::endl;
    188     }
    189   }
    190 
    191   stream << std::endl;
    192   stream << "Orphaned Consumer Buffers:\n";
    193   stream << std::right;
    194   stream << std::setw(6) << "Id";
    195   stream << " ";
    196   stream << std::setw(14) << "Info";
    197   stream << std::endl;
    198 
    199   for (const auto& channel : channels) {
    200     BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
    201     // consumer_count is tracked by producer. When it's zero, producer must have
    202     // already hung up and the consumer is orphaned.
    203     if (channel->channel_type() == BufferHubChannel::kConsumerType &&
    204         info.consumer_count == 0) {
    205       stream << std::right;
    206       stream << std::setw(6) << info.id;
    207       stream << " ";
    208 
    209       stream << std::setw(14) << "Orphaned.";
    210       stream << (" channel_id=" + std::to_string(channel->channel_id()));
    211       stream << std::endl;
    212     }
    213   }
    214 
    215   return stream.str();
    216 }
    217 
    218 void BufferHubService::HandleImpulse(Message& message) {
    219   ATRACE_NAME("BufferHubService::HandleImpulse");
    220   if (auto channel = message.GetChannel<BufferHubChannel>())
    221     channel->HandleImpulse(message);
    222 }
    223 
    224 pdx::Status<void> BufferHubService::HandleMessage(Message& message) {
    225   ATRACE_NAME("BufferHubService::HandleMessage");
    226   auto channel = message.GetChannel<BufferHubChannel>();
    227 
    228   ALOGD_IF(
    229       TRACE,
    230       "BufferHubService::HandleMessage: channel=%p channel_id=%d opcode=%d",
    231       channel.get(), message.GetChannelId(), message.GetOp());
    232 
    233   // If the channel is already set up, let it handle the message.
    234   if (channel && !channel->HandleMessage(message))
    235     return DefaultHandleMessage(message);
    236 
    237   // This channel has not been set up yet, the following are valid operations.
    238   switch (message.GetOp()) {
    239     case BufferHubRPC::CreateBuffer::Opcode:
    240       DispatchRemoteMethod<BufferHubRPC::CreateBuffer>(
    241           *this, &BufferHubService::OnCreateBuffer, message);
    242       return {};
    243 
    244     case BufferHubRPC::CreateProducerQueue::Opcode:
    245       DispatchRemoteMethod<BufferHubRPC::CreateProducerQueue>(
    246           *this, &BufferHubService::OnCreateProducerQueue, message);
    247       return {};
    248 
    249     default:
    250       return DefaultHandleMessage(message);
    251   }
    252 }
    253 
    254 Status<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
    255                                               uint32_t height, uint32_t format,
    256                                               uint64_t usage,
    257                                               size_t meta_size_bytes) {
    258   // Use the producer channel id as the global buffer id.
    259   const int buffer_id = message.GetChannelId();
    260   ALOGD_IF(TRACE,
    261            "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
    262            "format=%u usage=%" PRIx64 " meta_size_bytes=%zu",
    263            buffer_id, width, height, format, usage, meta_size_bytes);
    264 
    265   // See if this channel is already attached to a buffer.
    266   if (const auto channel = message.GetChannel<BufferHubChannel>()) {
    267     ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
    268           buffer_id);
    269     return ErrorStatus(EALREADY);
    270   }
    271   const uint32_t kDefaultLayerCount = 1;
    272   auto status = ProducerChannel::Create(this, buffer_id, width, height,
    273                                         kDefaultLayerCount, format, usage,
    274                                         meta_size_bytes);
    275   if (status) {
    276     message.SetChannel(status.take());
    277     return {};
    278   } else {
    279     ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
    280           status.GetErrorMessage().c_str());
    281     return status.error_status();
    282   }
    283 }
    284 
    285 Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
    286     pdx::Message& message, const ProducerQueueConfig& producer_config,
    287     const UsagePolicy& usage_policy) {
    288   // Use the producer channel id as the global queue id.
    289   const int queue_id = message.GetChannelId();
    290   ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
    291            queue_id);
    292 
    293   // See if this channel is already attached to another object.
    294   if (const auto channel = message.GetChannel<BufferHubChannel>()) {
    295     ALOGE("BufferHubService::OnCreateProducerQueue: already created: queue=%d",
    296           queue_id);
    297     return ErrorStatus(EALREADY);
    298   }
    299 
    300   auto status = ProducerQueueChannel::Create(this, queue_id, producer_config,
    301                                              usage_policy);
    302   if (status) {
    303     message.SetChannel(status.take());
    304     return {{producer_config, queue_id}};
    305   } else {
    306     ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
    307     return status.error_status();
    308   }
    309 }
    310 
    311 void BufferHubChannel::SignalAvailable() {
    312   ATRACE_NAME("BufferHubChannel::SignalAvailable");
    313   ALOGD_IF(TRACE,
    314            "BufferHubChannel::SignalAvailable: channel_id=%d buffer_id=%d",
    315            channel_id(), buffer_id());
    316   signaled_ = true;
    317   const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLIN);
    318   ALOGE_IF(!status,
    319            "BufferHubChannel::SignalAvailable: failed to signal availability "
    320            "channel_id=%d: %s",
    321            channel_id_, status.GetErrorMessage().c_str());
    322 }
    323 
    324 void BufferHubChannel::ClearAvailable() {
    325   ATRACE_NAME("BufferHubChannel::ClearAvailable");
    326   ALOGD_IF(TRACE,
    327            "BufferHubChannel::ClearAvailable: channel_id=%d buffer_id=%d",
    328            channel_id(), buffer_id());
    329   signaled_ = false;
    330   const auto status = service_->ModifyChannelEvents(channel_id_, POLLIN, 0);
    331   ALOGE_IF(!status,
    332            "BufferHubChannel::ClearAvailable: failed to clear availability "
    333            "channel_id=%d: %s",
    334            channel_id_, status.GetErrorMessage().c_str());
    335 }
    336 
    337 void BufferHubChannel::Hangup() {
    338   ATRACE_NAME("BufferHubChannel::Hangup");
    339   ALOGD_IF(TRACE, "BufferHubChannel::Hangup: channel_id=%d buffer_id=%d",
    340            channel_id(), buffer_id());
    341   const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLHUP);
    342   ALOGE_IF(
    343       !status,
    344       "BufferHubChannel::Hangup: failed to signal hangup channel_id=%d: %s",
    345       channel_id_, status.GetErrorMessage().c_str());
    346 }
    347 
    348 }  // namespace dvr
    349 }  // namespace android
    350