Migrate buffers during surface change

Migrate graphic buffers during surface change in order to avoid
BufferQueue handling complexity later on.

Test: Manually using Chrome and google photo app
Bug: 132302078
Bug: 130862880
Change-Id: Ifb348b5d6a8f5a89dcc10a9f0be075057a5d3a6d
diff --git a/media/codec2/vndk/internal/C2BlockInternal.h b/media/codec2/vndk/internal/C2BlockInternal.h
index 84ce70a..4ae946a 100644
--- a/media/codec2/vndk/internal/C2BlockInternal.h
+++ b/media/codec2/vndk/internal/C2BlockInternal.h
@@ -206,23 +206,19 @@
      *
      *   - GetBufferQueueData(): Returns generation, bqId and bqSlot.
      *   - HoldBlockFromBufferQueue(): Sets "held" status to true.
-     *   - YieldBlockToBufferQueue(): Sets "held" status to false.
-     *   - AssignBlockToBufferQueue(): Sets the bufferqueue assignment and
-     *     "held" status.
+     *   - BeginTransferBlockToClient()/EndTransferBlockToClient():
+     *     Clear "held" status to false if transfer was successful,
+     *     otherwise "held" status remains true.
+     *   - BeginAttachBlockToBufferQueue()/EndAttachBlockToBufferQueue():
+     *     The will keep "held" status true if attach was eligible.
+     *     Otherwise, "held" status is cleared to false. In that case,
+     *     ownership of buffer should be transferred to bufferqueue.
+     *   - DisplayBlockToBufferQueue()
+     *     This will clear "held" status to false.
      *
      * All these functions operate on _C2BlockPoolData, which can be obtained by
      * calling GetGraphicBlockPoolData().
      *
-     * HoldBlockFromBufferQueue() will mark the block as held, while
-     * YieldBlockToBufferQueue() will do the opposite. These two functions do
-     * not modify the bufferqueue assignment, so it is not wrong to call
-     * HoldBlockFromBufferQueue() after YieldBlockToBufferQueue() if it can be
-     * guaranteed that the block is not destroyed during the period between the
-     * two calls.
-     *
-     * AssingBlockToBufferQueue() has a "held" status as an optional argument.
-     * The default value is true.
-     *
      * Maintaining Consistency with IGraphicBufferProducer Operations
      * ==============================================================
      *
@@ -232,16 +228,20 @@
      *     information for _C2BlockPoolData, with "held" status set to true.
      *
      * queueBuffer()
-     *   - After queueBuffer() is called, YieldBlockToBufferQueue() should be
-     *     called.
+     *   - Before queueBuffer() is called, DisplayBlockToBufferQueue() should be
+     *     called to test eligibility. If it's not eligible, do not call
+     *     queueBuffer().
      *
-     * attachBuffer()
-     *   - After attachBuffer() is called, AssignBlockToBufferQueue() should be
-     *     called with "held" status set to true.
+     * attachBuffer() - remote migration only.
+     *   - Local migration on blockpool side will be done automatically by
+     *     blockpool.
+     *   - Before attachBuffer(), BeginAttachBlockToBufferQueue() should be called
+     *     to test eligiblity.
+     *   - After attachBuffer() is called, EndAttachBlockToBufferQueue() should
+     *     be called. This will set "held" status to true. If it returned
+     *     false, cancelBuffer() should be called.
      *
-     * detachBuffer()
-     *   - After detachBuffer() is called, HoldBlockFromBufferQueue() should be
-     *     called.
+     * detachBuffer() - no-op.
      */
 
     /**
@@ -261,43 +261,12 @@
      */
     static
     bool GetBufferQueueData(
-            const std::shared_ptr<_C2BlockPoolData>& poolData,
+            const std::shared_ptr<const _C2BlockPoolData>& poolData,
             uint32_t* generation = nullptr,
             uint64_t* bqId = nullptr,
             int32_t* bqSlot = nullptr);
 
     /**
-     * Set bufferqueue assignment and "held" status to a block created by a
-     * bufferqueue-based blockpool.
-     *
-     * \param poolData blockpool data associated to the block.
-     * \param igbp       \c IGraphicBufferProducer instance from the designated
-     *                   bufferqueue.
-     * \param generation Generation number that the buffer belongs to.
-     * \param bqId       Id of the bufferqueue that will own the buffer (block).
-     * \param bqSlot     Slot number of the buffer.
-     * \param held       Whether the block is held. This "held" status can be
-     *                   changed later by calling YieldBlockToBufferQueue() or
-     *                   HoldBlockFromBufferQueue().
-     *
-     * \return \c true if \p poolData is valid bufferqueue data;
-     *         \c false otherwise.
-     *
-     * Note: \p generation should match the latest generation number set on the
-     * bufferqueue, and \p bqId should match the unique id for the bufferqueue
-     * (obtainable by calling igbp->getUniqueId()).
-     */
-    static
-    bool AssignBlockToBufferQueue(
-            const std::shared_ptr<_C2BlockPoolData>& poolData,
-            const ::android::sp<::android::hardware::graphics::bufferqueue::
-                                V2_0::IGraphicBufferProducer>& igbp,
-            uint32_t generation,
-            uint64_t bqId,
-            int32_t bqSlot,
-            bool held = true);
-
-    /**
      * Hold a block from the designated bufferqueue. This causes the destruction
      * of the block to trigger a call to cancelBuffer().
      *
@@ -305,6 +274,9 @@
      * block. It does not check if that is the case.
      *
      * \param poolData blockpool data associated to the block.
+     * \param owner    block owner from client bufferqueue manager.
+     *                 If this is expired, the block is not owned by client
+     *                 anymore.
      * \param igbp     \c IGraphicBufferProducer instance to be assigned to the
      *                 block. This is not needed when the block is local.
      *
@@ -313,24 +285,96 @@
     static
     bool HoldBlockFromBufferQueue(
             const std::shared_ptr<_C2BlockPoolData>& poolData,
+            const std::shared_ptr<int>& owner,
             const ::android::sp<::android::hardware::graphics::bufferqueue::
                                 V2_0::IGraphicBufferProducer>& igbp = nullptr);
 
     /**
-     * Yield a block to the designated bufferqueue. This causes the destruction
-     * of the block not to trigger a call to cancelBuffer();
+     * Prepare a block to be transferred to other process. This blocks
+     * bufferqueue migration from happening. The block should be in held.
      *
      * This function assumes that \p poolData comes from a bufferqueue-based
      * block. It does not check if that is the case.
      *
      * \param poolData blockpool data associated to the block.
      *
-     * \return The previous held status.
+     * \return true if transfer is eligible, false otherwise.
      */
     static
-    bool YieldBlockToBufferQueue(
+    bool BeginTransferBlockToClient(
             const std::shared_ptr<_C2BlockPoolData>& poolData);
 
+    /**
+     * Called after transferring the specified block is finished. Make sure
+     * that BeginTransferBlockToClient() was called before this call.
+     *
+     * This will unblock bufferqueue migration. If transfer result was
+     * successful, this causes the destruction of the block not to trigger a
+     * call to cancelBuffer().
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if transfer began before, false otherwise.
+     */
+    static
+    bool EndTransferBlockToClient(
+            const std::shared_ptr<_C2BlockPoolData>& poolData,
+            bool transferred);
+
+    /**
+     * Prepare a block to be migrated to another bufferqueue. This blocks
+     * rendering until migration has been finished.  The block should be in
+     * held.
+     *
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if migration is eligible, false otherwise.
+     */
+    static
+    bool BeginAttachBlockToBufferQueue(
+            const std::shared_ptr<_C2BlockPoolData>& poolData);
+
+    /**
+     * Called after migration of the specified block is finished. Make sure
+     * that BeginAttachBlockToBufferQueue() was called before this call.
+     *
+     * This will unblock rendering. if redering is tried during migration,
+     * this returns false. In that case, cancelBuffer() should be called.
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if migration is eligible, false otherwise.
+     */
+    static
+    bool EndAttachBlockToBufferQueue(
+            const std::shared_ptr<_C2BlockPoolData>& poolData,
+            const std::shared_ptr<int>& owner,
+            const ::android::sp<::android::hardware::graphics::bufferqueue::
+                                V2_0::IGraphicBufferProducer>& igbp,
+            uint32_t generation,
+            uint64_t bqId,
+            int32_t bqSlot);
+
+    /**
+     * Indicates a block to be rendered very soon.
+     *
+     * This function assumes that \p poolData comes from a bufferqueue-based
+     * block. It does not check if that is the case.
+     *
+     * \param poolData blockpool data associated to the block.
+     *
+     * \return true if migration is eligible, false otherwise.
+     */
+    static
+    bool DisplayBlockToBufferQueue(
+            const std::shared_ptr<_C2BlockPoolData>& poolData);
 };
 
 #endif // ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_