Home | History | Annotate | Download | only in libdisplay
      1 #include "include/private/dvr/display_client.h"
      2 
      3 #include <cutils/native_handle.h>
      4 #include <log/log.h>
      5 #include <pdx/default_transport/client_channel.h>
      6 #include <pdx/default_transport/client_channel_factory.h>
      7 #include <pdx/status.h>
      8 
      9 #include <mutex>
     10 
     11 #include <private/dvr/display_protocol.h>
     12 #include <private/dvr/native_buffer.h>
     13 
     14 using android::pdx::ErrorStatus;
     15 using android::pdx::LocalHandle;
     16 using android::pdx::LocalChannelHandle;
     17 using android::pdx::Status;
     18 using android::pdx::Transaction;
     19 using android::pdx::rpc::IfAnyOf;
     20 
     21 namespace android {
     22 namespace dvr {
     23 namespace display {
     24 
     25 Surface::Surface(LocalChannelHandle channel_handle, int* error)
     26     : BASE{pdx::default_transport::ClientChannel::Create(
     27           std::move(channel_handle))} {
     28   auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>();
     29   if (!status) {
     30     ALOGE("Surface::Surface: Failed to get surface info: %s",
     31           status.GetErrorMessage().c_str());
     32     Close(status.error());
     33     if (error)
     34       *error = status.error();
     35   }
     36 
     37   surface_id_ = status.get().surface_id;
     38   z_order_ = status.get().z_order;
     39   visible_ = status.get().visible;
     40 }
     41 
     42 Surface::Surface(const SurfaceAttributes& attributes, int* error)
     43     : BASE{pdx::default_transport::ClientChannelFactory::Create(
     44                DisplayProtocol::kClientPath),
     45            kInfiniteTimeout} {
     46   auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes);
     47   if (!status) {
     48     ALOGE("Surface::Surface: Failed to create display surface: %s",
     49           status.GetErrorMessage().c_str());
     50     Close(status.error());
     51     if (error)
     52       *error = status.error();
     53   }
     54 
     55   surface_id_ = status.get().surface_id;
     56   z_order_ = status.get().z_order;
     57   visible_ = status.get().visible;
     58 }
     59 
     60 Status<void> Surface::SetVisible(bool visible) {
     61   return SetAttributes(
     62       {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
     63 }
     64 
     65 Status<void> Surface::SetZOrder(int z_order) {
     66   return SetAttributes(
     67       {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
     68 }
     69 
     70 Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
     71   auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
     72   if (!status) {
     73     ALOGE(
     74         "Surface::SetAttributes: Failed to set display surface "
     75         "attributes: %s",
     76         status.GetErrorMessage().c_str());
     77     return status.error_status();
     78   }
     79 
     80   // Set the local cached copies of the attributes we care about from the full
     81   // set of attributes sent to the display service.
     82   for (const auto& attribute : attributes) {
     83     const auto& key = attribute.first;
     84     const auto* variant = &attribute.second;
     85     bool invalid_value = false;
     86     switch (key) {
     87       case SurfaceAttribute::Visible:
     88         invalid_value =
     89             !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
     90         break;
     91       case SurfaceAttribute::ZOrder:
     92         invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
     93         break;
     94     }
     95 
     96     if (invalid_value) {
     97       ALOGW(
     98           "Surface::SetAttributes: Failed to set display surface "
     99           "attribute %d because of incompatible type: %d",
    100           key, variant->index());
    101     }
    102   }
    103 
    104   return {};
    105 }
    106 
    107 Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue() {
    108   ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
    109   auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(0);
    110   if (!status) {
    111     ALOGE("Surface::CreateQueue: Failed to create queue: %s",
    112           status.GetErrorMessage().c_str());
    113     return status.error_status();
    114   }
    115 
    116   auto producer_queue = ProducerQueue::Import(status.take());
    117   if (!producer_queue) {
    118     ALOGE("Surface::CreateQueue: Failed to import producer queue!");
    119     return ErrorStatus(ENOMEM);
    120   }
    121 
    122   return {std::move(producer_queue)};
    123 }
    124 
    125 Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
    126     uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
    127     uint64_t usage, size_t capacity) {
    128   ALOGD_IF(TRACE,
    129            "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u "
    130            "usage=%" PRIx64 " capacity=%zu",
    131            width, height, layer_count, format, usage, capacity);
    132   auto status = CreateQueue();
    133   if (!status)
    134     return status.error_status();
    135 
    136   auto producer_queue = status.take();
    137 
    138   ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
    139   for (size_t i = 0; i < capacity; i++) {
    140     size_t slot;
    141     const int ret = producer_queue->AllocateBuffer(width, height, layer_count,
    142                                                    format, usage, &slot);
    143     if (ret < 0) {
    144       ALOGE(
    145           "Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
    146           producer_queue->id(), strerror(-ret));
    147       return ErrorStatus(ENOMEM);
    148     }
    149     ALOGD_IF(
    150         TRACE,
    151         "Surface::CreateQueue: Allocated buffer at slot=%zu of capacity=%zu",
    152         slot, capacity);
    153   }
    154 
    155   return {std::move(producer_queue)};
    156 }
    157 
    158 DisplayClient::DisplayClient(int* error)
    159     : BASE(pdx::default_transport::ClientChannelFactory::Create(
    160                DisplayProtocol::kClientPath),
    161            kInfiniteTimeout) {
    162   if (error)
    163     *error = Client::error();
    164 }
    165 
    166 Status<Metrics> DisplayClient::GetDisplayMetrics() {
    167   return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
    168 }
    169 
    170 Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
    171     const SurfaceAttributes& attributes) {
    172   int error;
    173   if (auto client = Surface::Create(attributes, &error))
    174     return {std::move(client)};
    175   else
    176     return ErrorStatus(error);
    177 }
    178 
    179 Status<std::unique_ptr<IonBuffer>> DisplayClient::GetNamedBuffer(
    180     const std::string& name) {
    181   auto status = InvokeRemoteMethod<DisplayProtocol::GetNamedBuffer>(name);
    182   if (!status) {
    183     ALOGE(
    184         "DisplayClient::GetNamedBuffer: Failed to get named buffer: name=%s; "
    185         "error=%s",
    186         name.c_str(), status.GetErrorMessage().c_str());
    187     return status.error_status();
    188   }
    189 
    190   auto ion_buffer = std::make_unique<IonBuffer>();
    191   auto native_buffer_handle = status.take();
    192   const int ret = native_buffer_handle.Import(ion_buffer.get());
    193   if (ret < 0) {
    194     ALOGE(
    195         "DisplayClient::GetNamedBuffer: Failed to import named buffer: "
    196         "name=%s; error=%s",
    197         name.c_str(), strerror(-ret));
    198     return ErrorStatus(-ret);
    199   }
    200 
    201   return {std::move(ion_buffer)};
    202 }
    203 
    204 Status<bool> DisplayClient::IsVrAppRunning() {
    205   return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
    206 }
    207 
    208 }  // namespace display
    209 }  // namespace dvr
    210 }  // namespace android
    211