1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_ 18 #define ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_ 19 20 #include <C2Buffer.h> 21 22 #include <utils/RefBase.h> 23 24 namespace android::hardware::graphics::bufferqueue::V2_0 { 25 struct IGraphicBufferProducer; 26 } 27 28 // Note: HIDL-BufferPool and AIDL-BufferPool are not compatible 29 namespace android::hardware::media::bufferpool { 30 31 // BuffePool Data for HIDL-BufferPool 32 struct BufferPoolData; 33 34 } 35 namespace aidl::android::hardware::media::bufferpool2 { 36 37 // BuffePool Data for AIDL-BufferPool 38 struct BufferPoolData; 39 40 } 41 42 namespace aidl::android::hardware::media::c2 { 43 44 // IGraphicBufferAllocator for media.c2 aidl 45 class IGraphicBufferAllocator; 46 } 47 48 typedef struct AHardwareBuffer AHardwareBuffer; 49 50 using bufferpool_BufferPoolData = android::hardware::media::bufferpool::BufferPoolData; 51 using bufferpool2_BufferPoolData = aidl::android::hardware::media::bufferpool2::BufferPoolData; 52 53 /** 54 * Stores informations from C2BlockPool implementations which are required by C2Block. 55 */ 56 struct C2_HIDE _C2BlockPoolData { 57 enum type_t : int { 58 TYPE_BUFFERPOOL = 0, 59 TYPE_BUFFERQUEUE, 60 TYPE_BUFFERPOOL2, // AIDL-BufferPool 61 TYPE_AHWBUFFER, // AHardwareBuffer based block 62 }; 63 64 virtual type_t getType() const = 0; 65 66 protected: 67 _C2BlockPoolData() = default; 68 69 virtual ~_C2BlockPoolData() = default; 70 }; 71 72 struct C2BufferQueueBlockPoolData; 73 74 class C2SurfaceSyncMemory; 75 76 /** 77 * Internal only interface for creating blocks by block pool/buffer passing implementations. 78 * 79 * \todo this must be hidden 80 */ 81 struct _C2BlockFactory { 82 /** 83 * Create a linear block from an allocation for an allotted range. 84 * 85 * \param alloc parent allocation 86 * \param data blockpool data 87 * \param offset allotted range offset 88 * \param size allotted size 89 * 90 * \return shared pointer to the linear block. nullptr if there was not enough memory to 91 * create this block. 92 */ 93 static 94 std::shared_ptr<C2LinearBlock> CreateLinearBlock( 95 const std::shared_ptr<C2LinearAllocation> &alloc, 96 const std::shared_ptr<_C2BlockPoolData> &data = nullptr, 97 size_t offset = 0, 98 size_t size = ~(size_t)0); 99 100 /** 101 * Create a graphic block from an allocation for an allotted section. 102 * 103 * \param alloc parent allocation 104 * \param data blockpool data 105 * \param crop allotted crop region 106 * 107 * \return shared pointer to the graphic block. nullptr if there was not enough memory to 108 * create this block. 109 */ 110 static 111 std::shared_ptr<C2GraphicBlock> CreateGraphicBlock( 112 const std::shared_ptr<C2GraphicAllocation> &alloc, 113 const std::shared_ptr<_C2BlockPoolData> &data = nullptr, 114 const C2Rect &allottedCrop = C2Rect(~0u, ~0u)); 115 116 /** 117 * Return a block pool data from 1D block. 118 * 119 * \param shared pointer to the 1D block which is already created. 120 */ 121 static 122 std::shared_ptr<_C2BlockPoolData> GetLinearBlockPoolData( 123 const C2Block1D& block); 124 125 /** 126 * Return a block pool data from 2D block. 127 * 128 * \param shared pointer to the 2D block which is already created. 129 */ 130 static 131 std::shared_ptr<_C2BlockPoolData> GetGraphicBlockPoolData( 132 const C2Block2D& block); 133 134 /** 135 * Create a linear block from the received native handle. 136 * 137 * \param handle native handle to a linear block 138 * 139 * \return shared pointer to the linear block. nullptr if there was not enough memory to 140 * create this block. 141 */ 142 static 143 std::shared_ptr<C2LinearBlock> CreateLinearBlock( 144 const C2Handle *handle); 145 146 /** 147 * Create a graphic block from the received native handle. 148 * 149 * \param handle native handle to a graphic block 150 * 151 * \return shared pointer to the graphic block. nullptr if there was not enough memory to 152 * create this block. 153 */ 154 static 155 std::shared_ptr<C2GraphicBlock> CreateGraphicBlock( 156 const C2Handle *handle); 157 158 // HIDL-BufferPool 159 /** 160 * Create a linear block from the received bufferpool data. 161 * 162 * \param data bufferpool data to a linear block 163 * 164 * \return shared pointer to the linear block. nullptr if there was not enough memory to 165 * create this block. 166 */ 167 static 168 std::shared_ptr<C2LinearBlock> CreateLinearBlock( 169 const C2Handle *handle, 170 const std::shared_ptr<bufferpool_BufferPoolData> &data); 171 172 /** 173 * Create a graphic block from the received bufferpool data. 174 * 175 * \param data bufferpool data to a graphic block 176 * 177 * \return shared pointer to the graphic block. nullptr if there was not enough memory to 178 * create this block. 179 */ 180 static 181 std::shared_ptr<C2GraphicBlock> CreateGraphicBlock( 182 const C2Handle *handle, 183 const std::shared_ptr<bufferpool_BufferPoolData> &data); 184 185 /** 186 * Create a graphic block from the received AHardwareBuffer. 187 * 188 * \param buffer AHardwareBuffer 189 * 190 * \return shared pointer to the graphic block. nullptr if there was not enough memory to 191 * create this block. 192 */ 193 static 194 std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(AHardwareBuffer *buffer); 195 196 /** 197 * Get bufferpool data from the blockpool data. 198 * 199 * \param poolData blockpool data 200 * \param bufferPoolData pointer to bufferpool data where the bufferpool 201 * data is stored. 202 * 203 * \return {\code true} when there is valid bufferpool data, {\code false} otherwise. 204 */ 205 static 206 bool GetBufferPoolData( 207 const std::shared_ptr<const _C2BlockPoolData> &poolData, 208 std::shared_ptr<bufferpool_BufferPoolData> *bufferPoolData); 209 210 // AIDL-BufferPool 211 /** 212 * Create a linear block from the received bufferpool data. 213 * 214 * \param data bufferpool data to a linear block 215 * 216 * \return shared pointer to the linear block. nullptr if there was not enough memory to 217 * create this block. 218 */ 219 static 220 std::shared_ptr<C2LinearBlock> CreateLinearBlock( 221 const C2Handle *handle, 222 const std::shared_ptr<bufferpool2_BufferPoolData> &data); 223 224 /** 225 * Create a graphic block from the received bufferpool data. 226 * 227 * \param data bufferpool data to a graphic block 228 * 229 * \return shared pointer to the graphic block. nullptr if there was not enough memory to 230 * create this block. 231 */ 232 static 233 std::shared_ptr<C2GraphicBlock> CreateGraphicBlock( 234 const C2Handle *handle, 235 const std::shared_ptr<bufferpool2_BufferPoolData> &data); 236 237 /** 238 * Get bufferpool data from the blockpool data. 239 * 240 * \param poolData blockpool data 241 * \param bufferPoolData pointer to bufferpool data where the bufferpool 242 * data is stored. 243 * 244 * \return {\code true} when there is valid bufferpool data, {\code false} otherwise. 245 */ 246 static 247 bool GetBufferPoolData( 248 const std::shared_ptr<const _C2BlockPoolData> &poolData, 249 std::shared_ptr<bufferpool2_BufferPoolData> *bufferPoolData); 250 251 /* 252 * Life Cycle Management of BufferQueue-Based Blocks 253 * ================================================= 254 * 255 * A block that is created by a bufferqueue-based blockpool requires some 256 * special treatment when it is destroyed. In particular, if the block 257 * corresponds to a held (dequeued/attached) GraphicBuffer in a slot of a 258 * bufferqueue, its destruction should trigger a call to 259 * IGraphicBufferProducer::cancelBuffer(). On the other hand, if the 260 * GraphicBuffer is not held, i.e., if it has been queued or detached, 261 * cancelBuffer() should not be called upon the destruction of the block. 262 * 263 * _C2BlockPoolData created by a bufferqueue-based blockpool includes two 264 * main pieces of information: 265 * - "held" status: Whether cancelBuffer() should be called upon 266 * destruction of the block. 267 * - bufferqueue assignment: The quadruple (igbp, generation, bqId, 268 * bqSlot), where igbp is the IGraphicBufferProducer instance of the 269 * bufferqueue, generation is the latest generation number, of the 270 * bufferqueue, bqId is the globally unique id of the bufferqueue, and 271 * bqSlot is the slot in the bufferqueue. 272 * 273 * igbp is the instance of IGraphicBufferProducer on which cancelBuffer() 274 * will be called if "held" status is true when the block is destroyed. 275 * (bqSlot is an input to cancelBuffer().) However, only generation, bqId 276 * and bqSlot are retained when a block is transferred from one process to 277 * another. It is the responsibility of both the sending and receiving 278 * processes to maintain consistency of "held" status and igbp. Below are 279 * functions provided for this purpose: 280 * 281 * - GetBufferQueueData(): Returns generation, bqId and bqSlot. 282 * - HoldBlockFromBufferQueue(): Sets "held" status to true. 283 * - BeginTransferBlockToClient()/EndTransferBlockToClient(): 284 * Clear "held" status to false if transfer was successful, 285 * otherwise "held" status remains true. 286 * - BeginAttachBlockToBufferQueue()/EndAttachBlockToBufferQueue(): 287 * The will keep "held" status true if attach was eligible. 288 * Otherwise, "held" status is cleared to false. In that case, 289 * ownership of buffer should be transferred to bufferqueue. 290 * - DisplayBlockToBufferQueue() 291 * This will clear "held" status to false. 292 * 293 * All these functions operate on _C2BlockPoolData, which can be obtained by 294 * calling GetGraphicBlockPoolData(). 295 * 296 * Maintaining Consistency with IGraphicBufferProducer Operations 297 * ============================================================== 298 * 299 * dequeueBuffer() 300 * - This function is called by the blockpool. It should not be called 301 * manually. The blockpool will automatically generate the correct 302 * information for _C2BlockPoolData, with "held" status set to true. 303 * 304 * queueBuffer() 305 * - Before queueBuffer() is called, DisplayBlockToBufferQueue() should be 306 * called to test eligibility. If it's not eligible, do not call 307 * queueBuffer(). 308 * 309 * attachBuffer() - remote migration only. 310 * - Local migration on blockpool side will be done automatically by 311 * blockpool. 312 * - Before attachBuffer(), BeginAttachBlockToBufferQueue() should be called 313 * to test eligibility. 314 * - After attachBuffer() is called, EndAttachBlockToBufferQueue() should 315 * be called. This will set "held" status to true. If it returned 316 * false, cancelBuffer() should be called. 317 * 318 * detachBuffer() - no-op. 319 */ 320 321 /** 322 * Get bufferqueue data from the blockpool data. 323 * 324 * Calling this function with \p generation set to nullptr will return 325 * whether the block comes from a bufferqueue-based blockpool, but will not 326 * fill in the values for \p generation, \p bqId or \p bqSlot. 327 * 328 * \param[in] poolData blockpool data. 329 * \param[out] generation Generation number attached to the buffer. 330 * \param[out] bqId Id of the bufferqueue owning the buffer (block). 331 * \param[out] bqSlot Slot number of the buffer. 332 * 333 * \return \c true when there is valid bufferqueue data; 334 * \c false otherwise. 335 */ 336 static 337 bool GetBufferQueueData( 338 const std::shared_ptr<const _C2BlockPoolData>& poolData, 339 uint32_t* generation = nullptr, 340 uint64_t* bqId = nullptr, 341 int32_t* bqSlot = nullptr); 342 343 /** 344 * Hold a block from the designated bufferqueue. This causes the destruction 345 * of the block to trigger a call to cancelBuffer(). 346 * 347 * This function assumes that \p poolData comes from a bufferqueue-based 348 * block. It does not check if that is the case. 349 * 350 * \param poolData blockpool data associated to the block. 351 * \param owner block owner from client bufferqueue manager. 352 * If this is expired, the block is not owned by client 353 * anymore. 354 * \param igbp \c IGraphicBufferProducer instance to be assigned to the 355 * block. This is not needed when the block is local. 356 * \param syncMem Memory block which will support synchronization 357 * between Framework and HAL. 358 * 359 * \return The previous held status. 360 */ 361 static 362 bool HoldBlockFromBufferQueue( 363 const std::shared_ptr<_C2BlockPoolData>& poolData, 364 const std::shared_ptr<int>& owner, 365 const ::android::sp<::android::hardware::graphics::bufferqueue:: 366 V2_0::IGraphicBufferProducer>& igbp = nullptr, 367 std::shared_ptr<C2SurfaceSyncMemory> syncMem = nullptr); 368 369 /** 370 * Prepare a block to be transferred to other process. This blocks 371 * bufferqueue migration from happening. The block should be in held. 372 * 373 * This function assumes that \p poolData comes from a bufferqueue-based 374 * block. It does not check if that is the case. 375 * 376 * \param poolData blockpool data associated to the block. 377 * 378 * \return true if transfer is eligible, false otherwise. 379 */ 380 static 381 bool BeginTransferBlockToClient( 382 const std::shared_ptr<_C2BlockPoolData>& poolData); 383 384 /** 385 * Called after transferring the specified block is finished. Make sure 386 * that BeginTransferBlockToClient() was called before this call. 387 * 388 * This will unblock bufferqueue migration. If transfer result was 389 * successful, this causes the destruction of the block not to trigger a 390 * call to cancelBuffer(). 391 * This function assumes that \p poolData comes from a bufferqueue-based 392 * block. It does not check if that is the case. 393 * 394 * \param poolData blockpool data associated to the block. 395 * 396 * \return true if transfer began before, false otherwise. 397 */ 398 static 399 bool EndTransferBlockToClient( 400 const std::shared_ptr<_C2BlockPoolData>& poolData, 401 bool transferred); 402 403 /** 404 * Prepare a block to be migrated to another bufferqueue. This blocks 405 * rendering until migration has been finished. The block should be in 406 * held. 407 * 408 * This function assumes that \p poolData comes from a bufferqueue-based 409 * block. It does not check if that is the case. 410 * 411 * \param poolData blockpool data associated to the block. 412 * 413 * \return true if migration is eligible, false otherwise. 414 */ 415 static 416 bool BeginAttachBlockToBufferQueue( 417 const std::shared_ptr<_C2BlockPoolData>& poolData); 418 419 /** 420 * Called after migration of the specified block is finished. Make sure 421 * that BeginAttachBlockToBufferQueue() was called before this call. 422 * 423 * This will unblock rendering. if redering is tried during migration, 424 * this returns false. In that case, cancelBuffer() should be called. 425 * This function assumes that \p poolData comes from a bufferqueue-based 426 * block. It does not check if that is the case. 427 * 428 * \param poolData blockpool data associated to the block. 429 * 430 * \return true if migration is eligible, false otherwise. 431 */ 432 static 433 bool EndAttachBlockToBufferQueue( 434 const std::shared_ptr<_C2BlockPoolData>& poolData, 435 const std::shared_ptr<int>& owner, 436 const ::android::sp<::android::hardware::graphics::bufferqueue:: 437 V2_0::IGraphicBufferProducer>& igbp, 438 std::shared_ptr<C2SurfaceSyncMemory>, 439 uint32_t generation, 440 uint64_t bqId, 441 int32_t bqSlot); 442 443 /** 444 * Indicates a block to be rendered very soon. 445 * 446 * This function assumes that \p poolData comes from a bufferqueue-based 447 * block. It does not check if that is the case. 448 * 449 * \param poolData blockpool data associated to the block. 450 * 451 * \return true if migration is eligible, false otherwise. 452 */ 453 static 454 bool DisplayBlockToBufferQueue( 455 const std::shared_ptr<_C2BlockPoolData>& poolData); 456 457 /** 458 * Retrieves a AHardwareBuffer from data of a graphic block which was 459 * allocated via IGBA based blockpool. Retrieved AHardwareBuffer handle 460 * does not have the ownership. poolData still has the ownership. Use 461 * AHardwareBuffer_acquire()/AHardwareBuffer_release if independent 462 * life-cycle/ownership is required. 463 * 464 * \param[in] poolData blockpool data. 465 * \param[out] pBuf ptr to AHardwareBuffer 466 * 467 * \return true if AHardwareBuffer was returned to output parameter, false 468 * otherwise. 469 */ 470 static 471 bool GetAHardwareBuffer( 472 const std::shared_ptr<const _C2BlockPoolData>& poolData, 473 AHardwareBuffer **pBuf); 474 475 /** 476 * Mark a graphic block is not owned by the current process anymore. 477 * (Use this method after transfer is being completed.) 478 */ 479 static void DisownIgbaBlock( 480 const std::shared_ptr<_C2BlockPoolData>& poolData); 481 482 /** 483 * When the client receives a block from HAL, the client needs to store 484 * IGraphicBufferAllocator from which the block was originally allocated. 485 * The stored \p igba will be used in the dtor to deallocate the buffer. 486 * (calling IGraphicBufferAllocator::deallocate to reclaim.) 487 */ 488 static void RegisterIgba( 489 const std::shared_ptr<_C2BlockPoolData>& poolData, 490 std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba); 491 }; 492 493 #endif // ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_ 494 495