Codec2: Re-enable blocking allocator

Handle initial output surface configuration with destruction of old
blockpool.

Bug: 157111613
Test: atest CtsMediaTestCases:android.media.cts.AdaptivePlaybackTest
Change-Id: Ibf16cece0d7191fad24e7c8b64628fdc591e8a59
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index d49141c..71857e0 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -1482,7 +1482,8 @@
 c2_status_t Codec2Client::Component::setOutputSurface(
         C2BlockPool::local_id_t blockPoolId,
         const sp<IGraphicBufferProducer>& surface,
-        uint32_t generation) {
+        uint32_t generation,
+        int maxDequeueCount) {
     uint64_t bqId = 0;
     sp<IGraphicBufferProducer> nullIgbp;
     sp<HGraphicBufferProducer2> nullHgbp;
@@ -1496,14 +1497,15 @@
     std::shared_ptr<SurfaceSyncObj> syncObj;
 
     if (!surface) {
-        mOutputBufferQueue->configure(nullIgbp, generation, 0, nullptr);
+        mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
     } else if (surface->getUniqueId(&bqId) != OK) {
         LOG(ERROR) << "setOutputSurface -- "
                    "cannot obtain bufferqueue id.";
         bqId = 0;
-        mOutputBufferQueue->configure(nullIgbp, generation, 0, nullptr);
+        mOutputBufferQueue->configure(nullIgbp, generation, 0, maxDequeueCount, nullptr);
     } else {
-        mOutputBufferQueue->configure(surface, generation, bqId, nullptr);
+        mOutputBufferQueue->configure(surface, generation, bqId, maxDequeueCount, mBase1_2 ?
+                                      &syncObj : nullptr);
     }
     ALOGD("surface generation remote change %u HAL ver: %s",
           generation, syncObj ? "1.2" : "1.0");
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index eca268e..347e58a 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -384,7 +384,8 @@
     c2_status_t setOutputSurface(
             C2BlockPool::local_id_t blockPoolId,
             const sp<IGraphicBufferProducer>& surface,
-            uint32_t generation);
+            uint32_t generation,
+            int maxDequeueBufferCount);
 
     // Extract a slot number from of the block, then call
     // IGraphicBufferProducer::queueBuffer().
diff --git a/media/codec2/hidl/client/include/codec2/hidl/output.h b/media/codec2/hidl/client/include/codec2/hidl/output.h
index 0f03b36..877148a 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/output.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/output.h
@@ -47,6 +47,7 @@
     bool configure(const sp<IGraphicBufferProducer>& igbp,
                    uint32_t generation,
                    uint64_t bqId,
+                   int maxDequeueBufferCount,
                    std::shared_ptr<V1_2::SurfaceSyncObj> *syncObj);
 
     // Render a graphic block to current surface.
diff --git a/media/codec2/hidl/client/output.cpp b/media/codec2/hidl/client/output.cpp
index 7df0da2..283ed8d 100644
--- a/media/codec2/hidl/client/output.cpp
+++ b/media/codec2/hidl/client/output.cpp
@@ -178,6 +178,7 @@
 bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp,
                                   uint32_t generation,
                                   uint64_t bqId,
+                                  int maxDequeueBufferCount,
                                   std::shared_ptr<V1_2::SurfaceSyncObj> *syncObj) {
     uint64_t consumerUsage = 0;
     if (igbp->getConsumerUsage(&consumerUsage) != OK) {
@@ -219,6 +220,20 @@
     {
         std::scoped_lock<std::mutex> l(mMutex);
         if (generation == mGeneration) {
+            // case of old BlockPool destruction
+            C2SyncVariables *var = mSyncMem ? mSyncMem->mem() : nullptr;
+            if (var) {
+                *syncObj = std::make_shared<V1_2::SurfaceSyncObj>();
+                (*syncObj)->bqId = bqId;
+                (*syncObj)->syncMemory = mSyncMem->handle();
+                (*syncObj)->generationId = generation;
+                (*syncObj)->consumerUsage = consumerUsage;
+                mMaxDequeueBufferCount = maxDequeueBufferCount;
+                var->lock();
+                var->setSyncStatusLocked(C2SyncVariables::STATUS_INIT);
+                var->setInitialDequeueCountLocked(mMaxDequeueBufferCount, 0);
+                var->unlock();
+            }
             return false;
         }
         std::shared_ptr<C2SurfaceSyncMemory> oldMem = mSyncMem;
@@ -238,6 +253,7 @@
         mGeneration = generation;
         mBqId = bqId;
         mOwner = std::make_shared<int>(0);
+        mMaxDequeueBufferCount = maxDequeueBufferCount;
         for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; ++i) {
             if (mBqId == 0 || !mBuffers[i]) {
                 continue;
@@ -288,7 +304,9 @@
             mPoolDatas[i] = poolDatas[i];
         }
         if (newSync) {
-            newSync->setInitialDequeueCount(mMaxDequeueBufferCount, success);
+            newSync->lock();
+            newSync->setInitialDequeueCountLocked(mMaxDequeueBufferCount, success);
+            newSync->unlock();
         }
     }
     ALOGD("remote graphic buffer migration %zu/%zu",
@@ -452,6 +470,7 @@
         syncVar->unlock();
     }
     mMutex.unlock();
+    ALOGD("set max dequeue count %d from update", maxDequeueBufferCount);
 }
 
 }  // namespace c2
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index d0c1357..e33a5ba 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -1189,9 +1189,6 @@
             }
             outputGeneration = output->generation;
         }
-        if (maxDequeueCount > 0) {
-            mComponent->setOutputSurfaceMaxDequeueCount(maxDequeueCount);
-        }
 
         bool graphic = (oStreamFormat.value == C2BufferData::GRAPHIC);
         C2BlockPool::local_id_t outputPoolId_;
@@ -1331,7 +1328,8 @@
             mComponent->setOutputSurface(
                     outputPoolId_,
                     outputSurface,
-                    outputGeneration);
+                    outputGeneration,
+                    maxDequeueCount);
         }
 
         if (oStreamFormat.value == C2BufferData::LINEAR) {
@@ -1947,10 +1945,11 @@
                 & ((1 << 10) - 1));
 
     sp<IGraphicBufferProducer> producer;
+    int maxDequeueCount = mOutputSurface.lock()->maxDequeueBuffers;
     if (newSurface) {
         newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
         newSurface->setDequeueTimeout(kDequeueTimeoutNs);
-        newSurface->setMaxDequeuedBufferCount(mOutputSurface.lock()->maxDequeueBuffers);
+        newSurface->setMaxDequeuedBufferCount(maxDequeueCount);
         producer = newSurface->getIGraphicBufferProducer();
         producer->setGenerationNumber(generation);
     } else {
@@ -1970,7 +1969,8 @@
         if (mComponent->setOutputSurface(
                 outputPoolId,
                 producer,
-                generation) != C2_OK) {
+                generation,
+                maxDequeueCount) != C2_OK) {
             ALOGI("[%s] setSurface: component setOutputSurface failed", mName);
             return INVALID_OPERATION;
         }
diff --git a/media/codec2/vndk/include/C2SurfaceSyncObj.h b/media/codec2/vndk/include/C2SurfaceSyncObj.h
index 16e9a9d..ac87fe4 100644
--- a/media/codec2/vndk/include/C2SurfaceSyncObj.h
+++ b/media/codec2/vndk/include/C2SurfaceSyncObj.h
@@ -53,7 +53,7 @@
      * \param maxDequeueCount           Initial value of # of max dequeued buffer count
      * \param curDequeueCount           Initial value of # of current dequeued buffer count
      */
-    void setInitialDequeueCount(int32_t maxDequeueCount, int32_t curDequeueCount);
+    void setInitialDequeueCountLocked(int32_t maxDequeueCount, int32_t curDequeueCount);
 
     /**
      * Get a waitId which will be used to implement fence.
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index 2944925..169de0c 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -316,12 +316,15 @@
                     }
                     return C2_BLOCKING;
                 }
+                syncVar->notifyDequeuedLocked();
+                syncVar->unlock();
                 c2Status = dequeueBuffer(width, height, format, androidUsage,
                               &slot, &bufferNeedsReallocation, &fence);
-                if (c2Status == C2_OK) {
-                    syncVar->notifyDequeuedLocked();
+                if (c2Status != C2_OK) {
+                    syncVar->lock();
+                    syncVar->notifyQueuedLocked();
+                    syncVar->unlock();
                 }
-                syncVar->unlock();
             } else {
                 c2Status = dequeueBuffer(width, height, format, usage,
                               &slot, &bufferNeedsReallocation, &fence);
@@ -789,7 +792,7 @@
         sp<GraphicBuffer> newBuffer = new GraphicBuffer(
             graphicBuffer->handle, GraphicBuffer::CLONE_HANDLE,
             graphicBuffer->width, graphicBuffer->height, graphicBuffer->format,
-            graphicBuffer->layerCount, toUsage, graphicBuffer->stride);
+            graphicBuffer->layerCount, toUsage | graphicBuffer->getUsage(), graphicBuffer->stride);
         if (newBuffer->initCheck() == android::NO_ERROR) {
             graphicBuffer = std::move(newBuffer);
         } else {
diff --git a/media/codec2/vndk/platform/C2SurfaceSyncObj.cpp b/media/codec2/vndk/platform/C2SurfaceSyncObj.cpp
index 587992e..e55bdc0 100644
--- a/media/codec2/vndk/platform/C2SurfaceSyncObj.cpp
+++ b/media/codec2/vndk/platform/C2SurfaceSyncObj.cpp
@@ -157,12 +157,10 @@
     return 0;
 }
 
-void C2SyncVariables::setInitialDequeueCount(
+void C2SyncVariables::setInitialDequeueCountLocked(
         int32_t maxDequeueCount, int32_t curDequeueCount) {
-    lock();
     mMaxDequeueCount = maxDequeueCount;
     mCurDequeueCount = curDequeueCount;
-    unlock();
 }
 
 uint32_t C2SyncVariables::getWaitIdLocked() {