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