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:
NativeBufferHandle()21   NativeBufferHandle() { Clear(); }
NativeBufferHandle(const IonBuffer & buffer,int id)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.
Import(IonBuffer * buffer)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 
id()69   int id() const { return id_; }
IntCount()70   size_t IntCount() const { return opaque_ints_.size(); }
FdCount()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 
Clear()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;
BufferDescription(const IonBuffer & buffer,const IonBuffer & metadata,int id,int buffer_cid,uint32_t client_state_mask,const FileHandleType & acquire_fence_fd,const FileHandleType & release_fence_fd)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.
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.
buffer_cid()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.
client_state_mask()126   uint32_t client_state_mask() const { return client_state_mask_; }
take_acquire_fence()127   FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
take_release_fence()128   FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
129 
ImportBuffer(IonBuffer * buffer)130   int ImportBuffer(IonBuffer* buffer) { return buffer_.Import(buffer); }
ImportMetadata(IonBuffer * metadata)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;
FenceHandle(int fence)160   explicit FenceHandle(int fence) : fence_{fence} {}
FenceHandle(FileHandleType && 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 
get()167   const FileHandleType& get() const { fence_; }
take()168   FileHandleType&& take() { return std::move(fence_); }
169 
get_fd()170   int get_fd() const { return fence_.Get(); }
close()171   void close() { fence_.Close(); }
172 
borrow()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.
Build()219   ProducerQueueConfig Build() {
220     return {is_async_, default_width_, default_height_, default_format_,
221             user_metadata_size_};
222   }
223 
SetIsAsync(bool is_async)224   ProducerQueueConfigBuilder& SetIsAsync(bool is_async) {
225     is_async_ = is_async;
226     return *this;
227   }
228 
SetDefaultWidth(uint32_t width)229   ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) {
230     default_width_ = width;
231     return *this;
232   }
233 
SetDefaultHeight(uint32_t height)234   ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) {
235     default_height_ = height;
236     return *this;
237   }
238 
SetDefaultFormat(uint32_t format)239   ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) {
240     default_format_ = format;
241     return *this;
242   }
243 
244   template <typename Meta>
SetMetadata()245   ProducerQueueConfigBuilder& SetMetadata() {
246     user_metadata_size_ = sizeof(Meta);
247     return *this;
248   }
249 
SetMetadataSize(size_t user_metadata_size)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