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&
SetMetadata()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