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 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 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 55 static inline bool IsBufferAcquired(uint64_t state) { 56 return (state & kProducerStateBit) && (state & kConsumerStateMask); 57 } 58 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: 86 NativeBufferHandle() { Clear(); } 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. 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 134 int id() const { return id_; } 135 size_t IntCount() const { return opaque_ints_.size(); } 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 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; 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. 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. 187 uint64_t buffer_state_bit() const { return buffer_state_bit_; } 188 FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); } 189 FileHandleType take_release_fence() { return std::move(release_fence_fd_); } 190 191 int ImportBuffer(IonBuffer* buffer) { return buffer_.Import(buffer); } 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; 220 explicit FenceHandle(int fence) : fence_{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 227 const FileHandleType& get() const { fence_; } 228 FileHandleType&& take() { return std::move(fence_); } 229 230 int get_fd() const { return fence_.Get(); } 231 void close() { fence_.Close(); } 232 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. 279 ProducerQueueConfig Build() { 280 return {is_async_, default_width_, default_height_, default_format_, 281 user_metadata_size_}; 282 } 283 284 ProducerQueueConfigBuilder& SetIsAsync(bool is_async) { 285 is_async_ = is_async; 286 return *this; 287 } 288 289 ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) { 290 default_width_ = width; 291 return *this; 292 } 293 294 ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) { 295 default_height_ = height; 296 return *this; 297 } 298 299 ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) { 300 default_format_ = format; 301 return *this; 302 } 303 304 template <typename Meta> 305 ProducerQueueConfigBuilder& SetMetadata() { 306 user_metadata_size_ = sizeof(Meta); 307 return *this; 308 } 309 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