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 <dvr/dvr_api.h>
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 namespace BufferHubDefs {
19
20 static constexpr uint32_t kMetadataFormat = HAL_PIXEL_FORMAT_BLOB;
21 static constexpr uint32_t kMetadataUsage =
22 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
23
24 // Single producuer multiple (up to 63) consumers ownership signal.
25 // 64-bit atomic unsigned int.
26 //
27 // MSB LSB
28 // | |
29 // v v
30 // [P|C62|...|C1|C0]
31 // Gain'ed state: [0|..|0|0] -> Exclusively Writable.
32 // Post'ed state: [1|..|0|0]
33 // Acquired'ed state: [1|..|X|X] -> At least one bit is set in lower 63 bits
34 // Released'ed state: [0|..|X|X] -> At least one bit is set in lower 63 bits
35 static constexpr uint64_t kProducerStateBit = 1ULL << 63;
36 static constexpr uint64_t kConsumerStateMask = (1ULL << 63) - 1;
37
ModifyBufferState(std::atomic<uint64_t> * buffer_state,uint64_t clear_mask,uint64_t set_mask)38 static inline void ModifyBufferState(std::atomic<uint64_t>* buffer_state,
39 uint64_t clear_mask, uint64_t set_mask) {
40 uint64_t old_state;
41 uint64_t new_state;
42 do {
43 old_state = buffer_state->load();
44 new_state = (old_state & ~clear_mask) | set_mask;
45 } while (!buffer_state->compare_exchange_weak(old_state, new_state));
46 }
47
IsBufferGained(uint64_t state)48 static inline bool IsBufferGained(uint64_t state) { return state == 0; }
49
50 static inline bool IsBufferPosted(uint64_t state,
51 uint64_t consumer_bit = kConsumerStateMask) {
52 return (state & kProducerStateBit) && !(state & consumer_bit);
53 }
54
IsBufferAcquired(uint64_t state)55 static inline bool IsBufferAcquired(uint64_t state) {
56 return (state & kProducerStateBit) && (state & kConsumerStateMask);
57 }
58
IsBufferReleased(uint64_t state)59 static inline bool IsBufferReleased(uint64_t state) {
60 return !(state & kProducerStateBit) && (state & kConsumerStateMask);
61 }
62
63 struct __attribute__((packed, aligned(8))) MetadataHeader {
64 // Internal data format, which can be updated as long as the size, padding and
65 // field alignment of the struct is consistent within the same ABI. As this
66 // part is subject for future updates, it's not stable cross Android version,
67 // so don't have it visible from outside of the Android platform (include Apps
68 // and vendor HAL).
69 std::atomic<uint64_t> buffer_state;
70 std::atomic<uint64_t> fence_state;
71 uint64_t queue_index;
72
73 // Public data format, which should be updated with caution. See more details
74 // in dvr_api.h
75 DvrNativeBufferMetadata metadata;
76 };
77
78 static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size");
79 static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);
80
81 } // namespace BufferHubDefs
82
83 template <typename FileHandleType>
84 class NativeBufferHandle {
85 public:
NativeBufferHandle()86 NativeBufferHandle() { Clear(); }
NativeBufferHandle(const IonBuffer & buffer,int id)87 NativeBufferHandle(const IonBuffer& buffer, int id)
88 : id_(id),
89 stride_(buffer.stride()),
90 width_(buffer.width()),
91 height_(buffer.height()),
92 layer_count_(buffer.layer_count()),
93 format_(buffer.format()),
94 usage_(buffer.usage()) {
95 // Populate the fd and int vectors: native_handle->data[] is an array of fds
96 // followed by an array of opaque ints.
97 const int fd_count = buffer.handle()->numFds;
98 const int int_count = buffer.handle()->numInts;
99 for (int i = 0; i < fd_count; i++) {
100 fds_.emplace_back(FileHandleType::AsDuplicate(buffer.handle()->data[i]));
101 }
102 for (int i = 0; i < int_count; i++) {
103 opaque_ints_.push_back(buffer.handle()->data[fd_count + i]);
104 }
105 }
106 NativeBufferHandle(NativeBufferHandle&& other) = default;
107 NativeBufferHandle& operator=(NativeBufferHandle&& other) = default;
108
109 // Imports the native handle into the given IonBuffer instance.
Import(IonBuffer * buffer)110 int Import(IonBuffer* buffer) {
111 // This is annoying, but we need to convert the vector of FileHandles into a
112 // vector of ints for the Import API.
113 std::vector<int> fd_ints;
114 for (const auto& fd : fds_)
115 fd_ints.push_back(fd.Get());
116
117 const int ret =
118 buffer->Import(fd_ints.data(), fd_ints.size(), opaque_ints_.data(),
119 opaque_ints_.size(), width_, height_, layer_count_,
120 stride_, format_, usage_);
121 if (ret < 0)
122 return ret;
123
124 // Import succeeded, release the file handles which are now owned by the
125 // IonBuffer and clear members.
126 for (auto& fd : fds_)
127 fd.Release();
128 opaque_ints_.clear();
129 Clear();
130
131 return 0;
132 }
133
id()134 int id() const { return id_; }
IntCount()135 size_t IntCount() const { return opaque_ints_.size(); }
FdCount()136 size_t FdCount() const { return fds_.size(); }
137
138 private:
139 int id_;
140 uint32_t stride_;
141 uint32_t width_;
142 uint32_t height_;
143 uint32_t layer_count_;
144 uint32_t format_;
145 uint64_t usage_;
146 std::vector<int> opaque_ints_;
147 std::vector<FileHandleType> fds_;
148
Clear()149 void Clear() {
150 id_ = -1;
151 stride_ = width_ = height_ = format_ = usage_ = 0;
152 }
153
154 PDX_SERIALIZABLE_MEMBERS(NativeBufferHandle<FileHandleType>, id_, stride_,
155 width_, height_, layer_count_, format_, usage_,
156 opaque_ints_, fds_);
157
158 NativeBufferHandle(const NativeBufferHandle&) = delete;
159 void operator=(const NativeBufferHandle&) = delete;
160 };
161
162 template <typename FileHandleType>
163 class BufferDescription {
164 public:
165 BufferDescription() = default;
BufferDescription(const IonBuffer & buffer,const IonBuffer & metadata,int id,uint64_t buffer_state_bit,const FileHandleType & acquire_fence_fd,const FileHandleType & release_fence_fd)166 BufferDescription(const IonBuffer& buffer, const IonBuffer& metadata, int id,
167 uint64_t buffer_state_bit,
168 const FileHandleType& acquire_fence_fd,
169 const FileHandleType& release_fence_fd)
170 : id_(id),
171 buffer_state_bit_(buffer_state_bit),
172 buffer_(buffer, id),
173 metadata_(metadata, id),
174 acquire_fence_fd_(acquire_fence_fd.Borrow()),
175 release_fence_fd_(release_fence_fd.Borrow()) {}
176
177 BufferDescription(BufferDescription&& other) = default;
178 BufferDescription& operator=(BufferDescription&& other) = default;
179
180 // ID of the buffer client. All BufferHubBuffer clients derived from the same
181 // buffer in bufferhubd share the same buffer id.
id()182 int id() const { return id_; }
183 // State mask of the buffer client. Each BufferHubBuffer client backed by the
184 // same buffer channel has uniqued state bit among its siblings. For a
185 // producer buffer the bit must be kProducerStateBit; for a consumer the bit
186 // must be one of the kConsumerStateMask.
buffer_state_bit()187 uint64_t buffer_state_bit() const { return buffer_state_bit_; }
take_acquire_fence()188 FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
take_release_fence()189 FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
190
ImportBuffer(IonBuffer * buffer)191 int ImportBuffer(IonBuffer* buffer) { return buffer_.Import(buffer); }
ImportMetadata(IonBuffer * metadata)192 int ImportMetadata(IonBuffer* metadata) { return metadata_.Import(metadata); }
193
194 private:
195 int id_{-1};
196 uint64_t buffer_state_bit_{0};
197 // Two IonBuffers: one for the graphic buffer and one for metadata.
198 NativeBufferHandle<FileHandleType> buffer_;
199 NativeBufferHandle<FileHandleType> metadata_;
200
201 // Pamameters for shared fences.
202 FileHandleType acquire_fence_fd_;
203 FileHandleType release_fence_fd_;
204
205 PDX_SERIALIZABLE_MEMBERS(BufferDescription<FileHandleType>, id_,
206 buffer_state_bit_, buffer_, metadata_,
207 acquire_fence_fd_, release_fence_fd_);
208
209 BufferDescription(const BufferDescription&) = delete;
210 void operator=(const BufferDescription&) = delete;
211 };
212
213 using BorrowedNativeBufferHandle = NativeBufferHandle<pdx::BorrowedHandle>;
214 using LocalNativeBufferHandle = NativeBufferHandle<pdx::LocalHandle>;
215
216 template <typename FileHandleType>
217 class FenceHandle {
218 public:
219 FenceHandle() = default;
FenceHandle(int fence)220 explicit FenceHandle(int fence) : fence_{fence} {}
FenceHandle(FileHandleType && fence)221 explicit FenceHandle(FileHandleType&& fence) : fence_{std::move(fence)} {}
222 FenceHandle(FenceHandle&&) = default;
223 FenceHandle& operator=(FenceHandle&&) = default;
224
225 explicit operator bool() const { return fence_.IsValid(); }
226
get()227 const FileHandleType& get() const { fence_; }
take()228 FileHandleType&& take() { return std::move(fence_); }
229
get_fd()230 int get_fd() const { return fence_.Get(); }
close()231 void close() { fence_.Close(); }
232
borrow()233 FenceHandle<pdx::BorrowedHandle> borrow() const {
234 return FenceHandle<pdx::BorrowedHandle>(fence_.Borrow());
235 }
236
237 private:
238 FileHandleType fence_;
239
240 PDX_SERIALIZABLE_MEMBERS(FenceHandle<FileHandleType>, fence_);
241
242 FenceHandle(const FenceHandle&) = delete;
243 void operator=(const FenceHandle&) = delete;
244 };
245
246 using LocalFence = FenceHandle<pdx::LocalHandle>;
247 using BorrowedFence = FenceHandle<pdx::BorrowedHandle>;
248
249 struct ProducerQueueConfig {
250 // Whether the buffer queue is operating in Async mode.
251 // From GVR's perspective of view, this means a buffer can be acquired
252 // asynchronously by the compositor.
253 // From Android Surface's perspective of view, this is equivalent to
254 // IGraphicBufferProducer's async mode. When in async mode, a producer
255 // will never block even if consumer is running slow.
256 bool is_async;
257
258 // Default buffer width that is set during ProducerQueue's creation.
259 uint32_t default_width;
260
261 // Default buffer height that is set during ProducerQueue's creation.
262 uint32_t default_height;
263
264 // Default buffer format that is set during ProducerQueue's creation.
265 uint32_t default_format;
266
267 // Size of the meta data associated with all the buffers allocated from the
268 // queue.
269 size_t user_metadata_size;
270
271 private:
272 PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, is_async, default_width,
273 default_height, default_format, user_metadata_size);
274 };
275
276 class ProducerQueueConfigBuilder {
277 public:
278 // Build a ProducerQueueConfig object.
Build()279 ProducerQueueConfig Build() {
280 return {is_async_, default_width_, default_height_, default_format_,
281 user_metadata_size_};
282 }
283
SetIsAsync(bool is_async)284 ProducerQueueConfigBuilder& SetIsAsync(bool is_async) {
285 is_async_ = is_async;
286 return *this;
287 }
288
SetDefaultWidth(uint32_t width)289 ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) {
290 default_width_ = width;
291 return *this;
292 }
293
SetDefaultHeight(uint32_t height)294 ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) {
295 default_height_ = height;
296 return *this;
297 }
298
SetDefaultFormat(uint32_t format)299 ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) {
300 default_format_ = format;
301 return *this;
302 }
303
304 template <typename Meta>
SetMetadata()305 ProducerQueueConfigBuilder& SetMetadata() {
306 user_metadata_size_ = sizeof(Meta);
307 return *this;
308 }
309
SetMetadataSize(size_t user_metadata_size)310 ProducerQueueConfigBuilder& SetMetadataSize(size_t user_metadata_size) {
311 user_metadata_size_ = user_metadata_size;
312 return *this;
313 }
314
315 private:
316 bool is_async_{false};
317 uint32_t default_width_{1};
318 uint32_t default_height_{1};
319 uint32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888
320 size_t user_metadata_size_{0};
321 };
322
323 // Explicit specializations of ProducerQueueConfigBuilder::Build for void
324 // metadata type.
325 template <>
326 inline ProducerQueueConfigBuilder&
327 ProducerQueueConfigBuilder::SetMetadata<void>() {
328 user_metadata_size_ = 0;
329 return *this;
330 }
331
332 struct QueueInfo {
333 ProducerQueueConfig producer_config;
334 int id;
335
336 private:
337 PDX_SERIALIZABLE_MEMBERS(QueueInfo, producer_config, id);
338 };
339
340 struct UsagePolicy {
341 uint64_t usage_set_mask{0};
342 uint64_t usage_clear_mask{0};
343 uint64_t usage_deny_set_mask{0};
344 uint64_t usage_deny_clear_mask{0};
345
346 private:
347 PDX_SERIALIZABLE_MEMBERS(UsagePolicy, usage_set_mask, usage_clear_mask,
348 usage_deny_set_mask, usage_deny_clear_mask);
349 };
350
351 // BufferHub Service RPC interface. Defines the endpoints, op codes, and method
352 // type signatures supported by bufferhubd.
353 struct BufferHubRPC {
354 // Service path.
355 static constexpr char kClientPath[] = "system/buffer_hub/client";
356
357 // |BufferHubQueue| will keep track of at most this value of buffers.
358 // Attempts at runtime to increase the number of buffers past this
359 // will fail. Note that the value is in sync with |android::BufferQueue|, so
360 // that slot id can be shared between |android::dvr::BufferHubQueueProducer|
361 // and |android::BufferQueueProducer| which both implements the same
362 // interface: |android::IGraphicBufferProducer|.
363 static constexpr size_t kMaxQueueCapacity =
364 android::BufferQueueDefs::NUM_BUFFER_SLOTS;
365
366 // Op codes.
367 enum {
368 kOpCreateBuffer = 0,
369 kOpCreatePersistentBuffer,
370 kOpGetPersistentBuffer,
371 kOpGetBuffer,
372 kOpNewConsumer,
373 kOpProducerMakePersistent,
374 kOpProducerRemovePersistence,
375 kOpProducerPost,
376 kOpProducerGain,
377 kOpConsumerAcquire,
378 kOpConsumerRelease,
379 kOpConsumerSetIgnore,
380 kOpCreateProducerQueue,
381 kOpCreateConsumerQueue,
382 kOpGetQueueInfo,
383 kOpProducerQueueAllocateBuffers,
384 kOpProducerQueueRemoveBuffer,
385 kOpConsumerQueueImportBuffers,
386 };
387
388 // Aliases.
389 using LocalChannelHandle = pdx::LocalChannelHandle;
390 using LocalHandle = pdx::LocalHandle;
391 using Void = pdx::rpc::Void;
392
393 // Methods.
394 PDX_REMOTE_METHOD(CreateBuffer, kOpCreateBuffer,
395 void(uint32_t width, uint32_t height, uint32_t format,
396 uint64_t usage, size_t user_metadata_size));
397 PDX_REMOTE_METHOD(CreatePersistentBuffer, kOpCreatePersistentBuffer,
398 void(const std::string& name, int user_id, int group_id,
399 uint32_t width, uint32_t height, uint32_t format,
400 uint64_t usage, size_t user_metadata_size));
401 PDX_REMOTE_METHOD(GetPersistentBuffer, kOpGetPersistentBuffer,
402 void(const std::string& name));
403 PDX_REMOTE_METHOD(GetBuffer, kOpGetBuffer,
404 BufferDescription<LocalHandle>(Void));
405 PDX_REMOTE_METHOD(NewConsumer, kOpNewConsumer, LocalChannelHandle(Void));
406 PDX_REMOTE_METHOD(ProducerMakePersistent, kOpProducerMakePersistent,
407 void(const std::string& name, int user_id, int group_id));
408 PDX_REMOTE_METHOD(ProducerRemovePersistence, kOpProducerRemovePersistence,
409 void(Void));
410 PDX_REMOTE_METHOD(ProducerPost, kOpProducerPost,
411 void(LocalFence acquire_fence));
412 PDX_REMOTE_METHOD(ProducerGain, kOpProducerGain, LocalFence(Void));
413 PDX_REMOTE_METHOD(ConsumerAcquire, kOpConsumerAcquire, LocalFence(Void));
414 PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease,
415 void(LocalFence release_fence));
416 PDX_REMOTE_METHOD(ConsumerSetIgnore, kOpConsumerSetIgnore, void(bool ignore));
417
418 // Buffer Queue Methods.
419 PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
420 QueueInfo(const ProducerQueueConfig& producer_config,
421 const UsagePolicy& usage_policy));
422 PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue,
423 LocalChannelHandle(bool silent_queue));
424 PDX_REMOTE_METHOD(GetQueueInfo, kOpGetQueueInfo, QueueInfo(Void));
425 PDX_REMOTE_METHOD(ProducerQueueAllocateBuffers,
426 kOpProducerQueueAllocateBuffers,
427 std::vector<std::pair<LocalChannelHandle, size_t>>(
428 uint32_t width, uint32_t height, uint32_t layer_count,
429 uint32_t format, uint64_t usage, size_t buffer_count));
430 PDX_REMOTE_METHOD(ProducerQueueRemoveBuffer, kOpProducerQueueRemoveBuffer,
431 void(size_t slot));
432 PDX_REMOTE_METHOD(ConsumerQueueImportBuffers, kOpConsumerQueueImportBuffers,
433 std::vector<std::pair<LocalChannelHandle, size_t>>(Void));
434 };
435
436 } // namespace dvr
437 } // namespace android
438
439 #endif // ANDROID_DVR_BUFFERHUB_RPC_H_
440