Home | History | Annotate | Download | only in internal
      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