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