Home | History | Annotate | Download | only in dvr
      1 #ifndef ANDROID_DVR_BUFFERHUB_RPC_H_
      2 #define ANDROID_DVR_BUFFERHUB_RPC_H_
      3 
      4 #include "buffer_hub_defs.h"
      5 
      6 #include <cutils/native_handle.h>
      7 #include <ui/BufferQueueDefs.h>
      8 
      9 #include <pdx/channel_handle.h>
     10 #include <pdx/file_handle.h>
     11 #include <pdx/rpc/remote_method.h>
     12 #include <pdx/rpc/serializable.h>
     13 #include <private/dvr/ion_buffer.h>
     14 
     15 namespace android {
     16 namespace dvr {
     17 
     18 template <typename FileHandleType>
     19 class NativeBufferHandle {
     20  public:
     21   NativeBufferHandle() { Clear(); }
     22   NativeBufferHandle(const IonBuffer& buffer, int id)
     23       : id_(id),
     24         stride_(buffer.stride()),
     25         width_(buffer.width()),
     26         height_(buffer.height()),
     27         layer_count_(buffer.layer_count()),
     28         format_(buffer.format()),
     29         usage_(buffer.usage()) {
     30     // Populate the fd and int vectors: native_handle->data[] is an array of fds
     31     // followed by an array of opaque ints.
     32     const int fd_count = buffer.handle()->numFds;
     33     const int int_count = buffer.handle()->numInts;
     34     for (int i = 0; i < fd_count; i++) {
     35       fds_.emplace_back(FileHandleType::AsDuplicate(buffer.handle()->data[i]));
     36     }
     37     for (int i = 0; i < int_count; i++) {
     38       opaque_ints_.push_back(buffer.handle()->data[fd_count + i]);
     39     }
     40   }
     41   NativeBufferHandle(NativeBufferHandle&& other) noexcept = default;
     42   NativeBufferHandle& operator=(NativeBufferHandle&& other) noexcept = default;
     43 
     44   // Imports the native handle into the given IonBuffer instance.
     45   int Import(IonBuffer* buffer) {
     46     // This is annoying, but we need to convert the vector of FileHandles into a
     47     // vector of ints for the Import API.
     48     std::vector<int> fd_ints;
     49     for (const auto& fd : fds_)
     50       fd_ints.push_back(fd.Get());
     51 
     52     const int ret =
     53         buffer->Import(fd_ints.data(), fd_ints.size(), opaque_ints_.data(),
     54                        opaque_ints_.size(), width_, height_, layer_count_,
     55                        stride_, format_, usage_);
     56     if (ret < 0)
     57       return ret;
     58 
     59     // Import succeeded, release the file handles which are now owned by the
     60     // IonBuffer and clear members.
     61     for (auto& fd : fds_)
     62       fd.Release();
     63     opaque_ints_.clear();
     64     Clear();
     65 
     66     return 0;
     67   }
     68 
     69   int id() const { return id_; }
     70   size_t IntCount() const { return opaque_ints_.size(); }
     71   size_t FdCount() const { return fds_.size(); }
     72 
     73  private:
     74   int id_;
     75   uint32_t stride_;
     76   uint32_t width_;
     77   uint32_t height_;
     78   uint32_t layer_count_;
     79   uint32_t format_;
     80   uint64_t usage_;
     81   std::vector<int> opaque_ints_;
     82   std::vector<FileHandleType> fds_;
     83 
     84   void Clear() {
     85     id_ = -1;
     86     stride_ = width_ = height_ = format_ = usage_ = 0;
     87   }
     88 
     89   PDX_SERIALIZABLE_MEMBERS(NativeBufferHandle<FileHandleType>, id_, stride_,
     90                            width_, height_, layer_count_, format_, usage_,
     91                            opaque_ints_, fds_);
     92 
     93   NativeBufferHandle(const NativeBufferHandle&) = delete;
     94   void operator=(const NativeBufferHandle&) = delete;
     95 };
     96 
     97 template <typename FileHandleType>
     98 class BufferDescription {
     99  public:
    100   BufferDescription() = default;
    101   BufferDescription(const IonBuffer& buffer, const IonBuffer& metadata, int id,
    102                     int buffer_cid, uint32_t client_state_mask,
    103                     const FileHandleType& acquire_fence_fd,
    104                     const FileHandleType& release_fence_fd)
    105       : id_(id),
    106         buffer_cid_(buffer_cid),
    107         client_state_mask_(client_state_mask),
    108         buffer_(buffer, id),
    109         metadata_(metadata, id),
    110         acquire_fence_fd_(acquire_fence_fd.Borrow()),
    111         release_fence_fd_(release_fence_fd.Borrow()) {}
    112 
    113   BufferDescription(BufferDescription&& other) noexcept = default;
    114   BufferDescription& operator=(BufferDescription&& other) noexcept = default;
    115 
    116   // ID of the buffer client. All BufferHub clients derived from the same buffer
    117   // in bufferhubd share the same buffer id.
    118   int id() const { return id_; }
    119 
    120   // Channel ID of the buffer client. Each BufferHub client has its system
    121   // unique channel id.
    122   int buffer_cid() const { return buffer_cid_; }
    123 
    124   // State mask of the buffer client. Each BufferHub client backed by the
    125   // same buffer channel has uniqued state bit among its siblings.
    126   uint32_t client_state_mask() const { return client_state_mask_; }
    127   FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
    128   FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
    129 
    130   int ImportBuffer(IonBuffer* buffer) { return buffer_.Import(buffer); }
    131   int ImportMetadata(IonBuffer* metadata) { return metadata_.Import(metadata); }
    132 
    133  private:
    134   int id_{-1};
    135   int buffer_cid_{-1};
    136   uint32_t client_state_mask_{0U};
    137   // Two IonBuffers: one for the graphic buffer and one for metadata.
    138   NativeBufferHandle<FileHandleType> buffer_;
    139   NativeBufferHandle<FileHandleType> metadata_;
    140 
    141   // Pamameters for shared fences.
    142   FileHandleType acquire_fence_fd_;
    143   FileHandleType release_fence_fd_;
    144 
    145   PDX_SERIALIZABLE_MEMBERS(BufferDescription<FileHandleType>, id_, buffer_cid_,
    146                            client_state_mask_, buffer_, metadata_,
    147                            acquire_fence_fd_, release_fence_fd_);
    148 
    149   BufferDescription(const BufferDescription&) = delete;
    150   void operator=(const BufferDescription&) = delete;
    151 };
    152 
    153 using BorrowedNativeBufferHandle = NativeBufferHandle<pdx::BorrowedHandle>;
    154 using LocalNativeBufferHandle = NativeBufferHandle<pdx::LocalHandle>;
    155 
    156 template <typename FileHandleType>
    157 class FenceHandle {
    158  public:
    159   FenceHandle() = default;
    160   explicit FenceHandle(int fence) : fence_{fence} {}
    161   explicit FenceHandle(FileHandleType&& fence) : fence_{std::move(fence)} {}
    162   FenceHandle(FenceHandle&&) noexcept = default;
    163   FenceHandle& operator=(FenceHandle&&) noexcept = default;
    164 
    165   explicit operator bool() const { return fence_.IsValid(); }
    166 
    167   const FileHandleType& get() const { fence_; }
    168   FileHandleType&& take() { return std::move(fence_); }
    169 
    170   int get_fd() const { return fence_.Get(); }
    171   void close() { fence_.Close(); }
    172 
    173   FenceHandle<pdx::BorrowedHandle> borrow() const {
    174     return FenceHandle<pdx::BorrowedHandle>(fence_.Borrow());
    175   }
    176 
    177  private:
    178   FileHandleType fence_;
    179 
    180   PDX_SERIALIZABLE_MEMBERS(FenceHandle<FileHandleType>, fence_);
    181 
    182   FenceHandle(const FenceHandle&) = delete;
    183   void operator=(const FenceHandle&) = delete;
    184 };
    185 
    186 using LocalFence = FenceHandle<pdx::LocalHandle>;
    187 using BorrowedFence = FenceHandle<pdx::BorrowedHandle>;
    188 
    189 struct ProducerQueueConfig {
    190   // Whether the buffer queue is operating in Async mode.
    191   // From GVR's perspective of view, this means a buffer can be acquired
    192   // asynchronously by the compositor.
    193   // From Android Surface's perspective of view, this is equivalent to
    194   // IGraphicBufferProducer's async mode. When in async mode, a producer
    195   // will never block even if consumer is running slow.
    196   bool is_async;
    197 
    198   // Default buffer width that is set during ProducerQueue's creation.
    199   uint32_t default_width;
    200 
    201   // Default buffer height that is set during ProducerQueue's creation.
    202   uint32_t default_height;
    203 
    204   // Default buffer format that is set during ProducerQueue's creation.
    205   uint32_t default_format;
    206 
    207   // Size of the meta data associated with all the buffers allocated from the
    208   // queue.
    209   size_t user_metadata_size;
    210 
    211  private:
    212   PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, is_async, default_width,
    213                            default_height, default_format, user_metadata_size);
    214 };
    215 
    216 class ProducerQueueConfigBuilder {
    217  public:
    218   // Build a ProducerQueueConfig object.
    219   ProducerQueueConfig Build() {
    220     return {is_async_, default_width_, default_height_, default_format_,
    221             user_metadata_size_};
    222   }
    223 
    224   ProducerQueueConfigBuilder& SetIsAsync(bool is_async) {
    225     is_async_ = is_async;
    226     return *this;
    227   }
    228 
    229   ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) {
    230     default_width_ = width;
    231     return *this;
    232   }
    233 
    234   ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) {
    235     default_height_ = height;
    236     return *this;
    237   }
    238 
    239   ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) {
    240     default_format_ = format;
    241     return *this;
    242   }
    243 
    244   template <typename Meta>
    245   ProducerQueueConfigBuilder& SetMetadata() {
    246     user_metadata_size_ = sizeof(Meta);
    247     return *this;
    248   }
    249 
    250   ProducerQueueConfigBuilder& SetMetadataSize(size_t user_metadata_size) {
    251     user_metadata_size_ = user_metadata_size;
    252     return *this;
    253   }
    254 
    255  private:
    256   bool is_async_{false};
    257   uint32_t default_width_{1};
    258   uint32_t default_height_{1};
    259   uint32_t default_format_{1};  // PIXEL_FORMAT_RGBA_8888
    260   size_t user_metadata_size_{0};
    261 };
    262 
    263 // Explicit specializations of ProducerQueueConfigBuilder::Build for void
    264 // metadata type.
    265 template <>
    266 inline ProducerQueueConfigBuilder&
    267 ProducerQueueConfigBuilder::SetMetadata<void>() {
    268   user_metadata_size_ = 0;
    269   return *this;
    270 }
    271 
    272 struct QueueInfo {
    273   ProducerQueueConfig producer_config;
    274   int id;
    275 
    276  private:
    277   PDX_SERIALIZABLE_MEMBERS(QueueInfo, producer_config, id);
    278 };
    279 
    280 struct UsagePolicy {
    281   uint64_t usage_set_mask{0};
    282   uint64_t usage_clear_mask{0};
    283   uint64_t usage_deny_set_mask{0};
    284   uint64_t usage_deny_clear_mask{0};
    285 
    286  private:
    287   PDX_SERIALIZABLE_MEMBERS(UsagePolicy, usage_set_mask, usage_clear_mask,
    288                            usage_deny_set_mask, usage_deny_clear_mask);
    289 };
    290 
    291 // BufferHub Service RPC interface. Defines the endpoints, op codes, and method
    292 // type signatures supported by bufferhubd.
    293 struct BufferHubRPC {
    294   // Service path.
    295   static constexpr char kClientPath[] = "system/buffer_hub/client";
    296 
    297   // |BufferHubQueue| will keep track of at most this value of buffers.
    298   // Attempts at runtime to increase the number of buffers past this
    299   // will fail. Note that the value is in sync with |android::BufferQueue|, so
    300   // that slot id can be shared between |android::dvr::BufferHubQueueProducer|
    301   // and |android::BufferQueueProducer| which both implements the same
    302   // interface: |android::IGraphicBufferProducer|.
    303   static constexpr size_t kMaxQueueCapacity =
    304       android::BufferQueueDefs::NUM_BUFFER_SLOTS;
    305 
    306   // Op codes.
    307   enum {
    308     kOpCreateBuffer = 0,
    309     kOpGetBuffer,
    310     kOpNewConsumer,
    311     kOpProducerPost,
    312     kOpProducerGain,
    313     kOpConsumerAcquire,
    314     kOpConsumerRelease,
    315     kOpConsumerBufferDetach,
    316     kOpCreateProducerQueue,
    317     kOpCreateConsumerQueue,
    318     kOpGetQueueInfo,
    319     kOpProducerQueueAllocateBuffers,
    320     kOpProducerQueueInsertBuffer,
    321     kOpProducerQueueRemoveBuffer,
    322     kOpConsumerQueueImportBuffers,
    323     // TODO(b/77153033): Separate all those RPC operations into subclasses.
    324   };
    325 
    326   // Aliases.
    327   using LocalChannelHandle = pdx::LocalChannelHandle;
    328   using LocalHandle = pdx::LocalHandle;
    329   using Void = pdx::rpc::Void;
    330 
    331   // Methods.
    332   PDX_REMOTE_METHOD(CreateBuffer, kOpCreateBuffer,
    333                     void(uint32_t width, uint32_t height, uint32_t format,
    334                          uint64_t usage, size_t user_metadata_size));
    335   PDX_REMOTE_METHOD(GetBuffer, kOpGetBuffer,
    336                     BufferDescription<LocalHandle>(Void));
    337   PDX_REMOTE_METHOD(NewConsumer, kOpNewConsumer, LocalChannelHandle(Void));
    338   PDX_REMOTE_METHOD(ProducerPost, kOpProducerPost,
    339                     void(LocalFence acquire_fence));
    340   PDX_REMOTE_METHOD(ProducerGain, kOpProducerGain, LocalFence(Void));
    341   PDX_REMOTE_METHOD(ConsumerAcquire, kOpConsumerAcquire, LocalFence(Void));
    342   PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease,
    343                     void(LocalFence release_fence));
    344 
    345   // Detaches a ConsumerBuffer from an existing producer/consumer set. Can only
    346   // be called when the consumer is the only consumer and it has exclusive
    347   // access to the buffer (i.e. in the acquired'ed state). On the successful
    348   // return of the IPC call, a new DetachedBufferChannel handle will be returned
    349   // and all existing producer and consumer channels will be closed. Further
    350   // IPCs towards those channels will return error.
    351   PDX_REMOTE_METHOD(ConsumerBufferDetach, kOpConsumerBufferDetach,
    352                     LocalChannelHandle(Void));
    353 
    354   // Buffer Queue Methods.
    355   PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
    356                     QueueInfo(const ProducerQueueConfig& producer_config,
    357                               const UsagePolicy& usage_policy));
    358   PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue,
    359                     LocalChannelHandle(bool silent_queue));
    360   PDX_REMOTE_METHOD(GetQueueInfo, kOpGetQueueInfo, QueueInfo(Void));
    361   PDX_REMOTE_METHOD(ProducerQueueAllocateBuffers,
    362                     kOpProducerQueueAllocateBuffers,
    363                     std::vector<std::pair<LocalChannelHandle, size_t>>(
    364                         uint32_t width, uint32_t height, uint32_t layer_count,
    365                         uint32_t format, uint64_t usage, size_t buffer_count));
    366   PDX_REMOTE_METHOD(ProducerQueueInsertBuffer, kOpProducerQueueInsertBuffer,
    367                     size_t(int buffer_cid));
    368   PDX_REMOTE_METHOD(ProducerQueueRemoveBuffer, kOpProducerQueueRemoveBuffer,
    369                     void(size_t slot));
    370   PDX_REMOTE_METHOD(ConsumerQueueImportBuffers, kOpConsumerQueueImportBuffers,
    371                     std::vector<std::pair<LocalChannelHandle, size_t>>(Void));
    372 };
    373 
    374 }  // namespace dvr
    375 }  // namespace android
    376 
    377 #endif  // ANDROID_DVR_BUFFERHUB_RPC_H_
    378