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