1#ifndef ANDROID_DVR_BUFFERHUB_RPC_H_
2#define ANDROID_DVR_BUFFERHUB_RPC_H_
3
4#include <cutils/native_handle.h>
5#include <gui/BufferQueueDefs.h>
6#include <sys/types.h>
7
8#include <pdx/channel_handle.h>
9#include <pdx/file_handle.h>
10#include <pdx/rpc/remote_method.h>
11#include <pdx/rpc/serializable.h>
12#include <private/dvr/ion_buffer.h>
13
14namespace android {
15namespace dvr {
16
17template <typename FileHandleType>
18class NativeBufferHandle {
19 public:
20  NativeBufferHandle() { Clear(); }
21  NativeBufferHandle(const IonBuffer& buffer, int id)
22      : id_(id),
23        stride_(buffer.stride()),
24        width_(buffer.width()),
25        height_(buffer.height()),
26        layer_count_(buffer.layer_count()),
27        format_(buffer.format()),
28        usage_(buffer.usage()) {
29    // Populate the fd and int vectors: native_handle->data[] is an array of fds
30    // followed by an array of opaque ints.
31    const int fd_count = buffer.handle()->numFds;
32    const int int_count = buffer.handle()->numInts;
33    for (int i = 0; i < fd_count; i++) {
34      fds_.emplace_back(FileHandleType::AsDuplicate(buffer.handle()->data[i]));
35    }
36    for (int i = 0; i < int_count; i++) {
37      opaque_ints_.push_back(buffer.handle()->data[fd_count + i]);
38    }
39  }
40  NativeBufferHandle(NativeBufferHandle&& other) = default;
41  NativeBufferHandle& operator=(NativeBufferHandle&& other) = default;
42
43  // Imports the native handle into the given IonBuffer instance.
44  int Import(IonBuffer* buffer) {
45    // This is annoying, but we need to convert the vector of FileHandles into a
46    // vector of ints for the Import API.
47    std::vector<int> fd_ints;
48    for (const auto& fd : fds_)
49      fd_ints.push_back(fd.Get());
50
51    const int ret =
52        buffer->Import(fd_ints.data(), fd_ints.size(), opaque_ints_.data(),
53                       opaque_ints_.size(), width_, height_, layer_count_,
54                       stride_, format_, usage_);
55    if (ret < 0)
56      return ret;
57
58    // Import succeeded, release the file handles which are now owned by the
59    // IonBuffer and clear members.
60    for (auto& fd : fds_)
61      fd.Release();
62    opaque_ints_.clear();
63    Clear();
64
65    return 0;
66  }
67
68  int id() const { return id_; }
69  size_t IntCount() const { return opaque_ints_.size(); }
70  size_t FdCount() const { return fds_.size(); }
71
72 private:
73  int id_;
74  uint32_t stride_;
75  uint32_t width_;
76  uint32_t height_;
77  uint32_t layer_count_;
78  uint32_t format_;
79  uint64_t usage_;
80  std::vector<int> opaque_ints_;
81  std::vector<FileHandleType> fds_;
82
83  void Clear() {
84    id_ = -1;
85    stride_ = width_ = height_ = format_ = usage_ = 0;
86  }
87
88  PDX_SERIALIZABLE_MEMBERS(NativeBufferHandle<FileHandleType>, id_, stride_,
89                           width_, height_, layer_count_, format_, usage_,
90                           opaque_ints_, fds_);
91
92  NativeBufferHandle(const NativeBufferHandle&) = delete;
93  void operator=(const NativeBufferHandle&) = delete;
94};
95
96using BorrowedNativeBufferHandle = NativeBufferHandle<pdx::BorrowedHandle>;
97using LocalNativeBufferHandle = NativeBufferHandle<pdx::LocalHandle>;
98
99template <typename FileHandleType>
100class FenceHandle {
101 public:
102  FenceHandle() = default;
103  explicit FenceHandle(int fence) : fence_{fence} {}
104  explicit FenceHandle(FileHandleType&& fence) : fence_{std::move(fence)} {}
105  FenceHandle(FenceHandle&&) = default;
106  FenceHandle& operator=(FenceHandle&&) = default;
107
108  explicit operator bool() const { return fence_.IsValid(); }
109
110  const FileHandleType& get() const { fence_; }
111  FileHandleType&& take() { return std::move(fence_); }
112
113  int get_fd() const { return fence_.Get(); }
114  void close() { fence_.Close(); }
115
116  FenceHandle<pdx::BorrowedHandle> borrow() const {
117    return FenceHandle<pdx::BorrowedHandle>(fence_.Borrow());
118  }
119
120 private:
121  FileHandleType fence_;
122
123  PDX_SERIALIZABLE_MEMBERS(FenceHandle<FileHandleType>, fence_);
124
125  FenceHandle(const FenceHandle&) = delete;
126  void operator=(const FenceHandle&) = delete;
127};
128
129using LocalFence = FenceHandle<pdx::LocalHandle>;
130using BorrowedFence = FenceHandle<pdx::BorrowedHandle>;
131
132struct QueueInfo {
133  size_t meta_size_bytes;
134  int id;
135
136 private:
137  PDX_SERIALIZABLE_MEMBERS(QueueInfo, meta_size_bytes, id);
138};
139
140struct UsagePolicy {
141  uint64_t usage_set_mask;
142  uint64_t usage_clear_mask;
143  uint64_t usage_deny_set_mask;
144  uint64_t usage_deny_clear_mask;
145
146 private:
147  PDX_SERIALIZABLE_MEMBERS(UsagePolicy, usage_set_mask, usage_clear_mask,
148                           usage_deny_set_mask, usage_deny_clear_mask);
149};
150
151// BufferHub Service RPC interface. Defines the endpoints, op codes, and method
152// type signatures supported by bufferhubd.
153struct BufferHubRPC {
154  // Service path.
155  static constexpr char kClientPath[] = "system/buffer_hub/client";
156
157  // |BufferHubQueue| will keep track of at most this value of buffers.
158  // Attempts at runtime to increase the number of buffers past this
159  // will fail. Note that the value is in sync with |android::BufferQueue|, so
160  // that slot id can be shared between |android::dvr::BufferHubQueueProducer|
161  // and |android::BufferQueueProducer| which both implements the same
162  // interface: |android::IGraphicBufferProducer|.
163  static constexpr size_t kMaxQueueCapacity =
164      android::BufferQueueDefs::NUM_BUFFER_SLOTS;
165
166  // Op codes.
167  enum {
168    kOpCreateBuffer = 0,
169    kOpCreatePersistentBuffer,
170    kOpGetPersistentBuffer,
171    kOpGetBuffer,
172    kOpNewConsumer,
173    kOpProducerMakePersistent,
174    kOpProducerRemovePersistence,
175    kOpProducerPost,
176    kOpProducerGain,
177    kOpConsumerAcquire,
178    kOpConsumerRelease,
179    kOpConsumerSetIgnore,
180    kOpCreateProducerQueue,
181    kOpCreateConsumerQueue,
182    kOpGetQueueInfo,
183    kOpProducerQueueAllocateBuffers,
184    kOpProducerQueueDetachBuffer,
185    kOpConsumerQueueImportBuffers,
186  };
187
188  // Aliases.
189  using MetaData = pdx::rpc::BufferWrapper<std::uint8_t*>;
190  using LocalChannelHandle = pdx::LocalChannelHandle;
191  using LocalHandle = pdx::LocalHandle;
192  using Void = pdx::rpc::Void;
193
194  // Methods.
195  PDX_REMOTE_METHOD(CreateBuffer, kOpCreateBuffer,
196                    void(uint32_t width, uint32_t height, uint32_t format,
197                         uint64_t usage, size_t meta_size_bytes));
198  PDX_REMOTE_METHOD(CreatePersistentBuffer, kOpCreatePersistentBuffer,
199                    void(const std::string& name, int user_id, int group_id,
200                         uint32_t width, uint32_t height, uint32_t format,
201                         uint64_t usage, size_t meta_size_bytes));
202  PDX_REMOTE_METHOD(GetPersistentBuffer, kOpGetPersistentBuffer,
203                    void(const std::string& name));
204  PDX_REMOTE_METHOD(GetBuffer, kOpGetBuffer,
205                    NativeBufferHandle<LocalHandle>(Void));
206  PDX_REMOTE_METHOD(NewConsumer, kOpNewConsumer, LocalChannelHandle(Void));
207  PDX_REMOTE_METHOD(ProducerMakePersistent, kOpProducerMakePersistent,
208                    void(const std::string& name, int user_id, int group_id));
209  PDX_REMOTE_METHOD(ProducerRemovePersistence, kOpProducerRemovePersistence,
210                    void(Void));
211  PDX_REMOTE_METHOD(ProducerPost, kOpProducerPost,
212                    void(LocalFence acquire_fence, MetaData));
213  PDX_REMOTE_METHOD(ProducerGain, kOpProducerGain, LocalFence(Void));
214  PDX_REMOTE_METHOD(ConsumerAcquire, kOpConsumerAcquire,
215                    std::pair<LocalFence, MetaData>(std::size_t metadata_size));
216  PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease,
217                    void(LocalFence release_fence));
218  PDX_REMOTE_METHOD(ConsumerSetIgnore, kOpConsumerSetIgnore, void(bool ignore));
219
220  // Buffer Queue Methods.
221  PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
222                    QueueInfo(size_t meta_size_bytes,
223                              const UsagePolicy& usage_policy));
224  PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue,
225                    LocalChannelHandle(Void));
226  PDX_REMOTE_METHOD(GetQueueInfo, kOpGetQueueInfo, QueueInfo(Void));
227  PDX_REMOTE_METHOD(ProducerQueueAllocateBuffers,
228                    kOpProducerQueueAllocateBuffers,
229                    std::vector<std::pair<LocalChannelHandle, size_t>>(
230                        uint32_t width, uint32_t height, uint32_t layer_count,
231                        uint32_t format, uint64_t usage, size_t buffer_count));
232  PDX_REMOTE_METHOD(ProducerQueueDetachBuffer, kOpProducerQueueDetachBuffer,
233                    void(size_t slot));
234  PDX_REMOTE_METHOD(ConsumerQueueImportBuffers, kOpConsumerQueueImportBuffers,
235                    std::vector<std::pair<LocalChannelHandle, size_t>>(Void));
236};
237
238}  // namespace dvr
239}  // namespace android
240
241#endif  // ANDROID_DVR_BUFFERHUB_RPC_H_
242