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