SF: change acquired buffers based on the current refresh rate

BLASTBufferQueue set the max acquired buffers based on SF
vsync configuration (sf.duration and app.duration). This is calculated
based on the max supported refresh rate on the device, and it turn
is propogated to apps via min_undequeued_buffers to the app could
allocate enough buffers for maintaining the pipeline SF expects.

This leads to a higher latency when the device is running in a lower
refresh rate as there are more buffers on the buffer queue then required.
In this change we are holding on the these "extra buffers" and not
releasing them back to the buffer queue so the app would use the number
of buffers it needs based on the current refresh rate, and to avoid having
unnecessary long latency.

Bug: 188553729
Test: Run backpressure based game on 60Hz and 120Hz and collect systraces
Change-Id: I9d4e6278f0ddd28008ac437ab0576aa79d05166a
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index d68a0e0..955c2f8 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -44,12 +44,12 @@
 namespace {
 void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
                                const sp<GraphicBuffer>& buffer, const sp<Fence>& releaseFence,
-                               uint32_t transformHint) {
+                               uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) {
     if (!listener) {
         return;
     }
     listener->onReleaseBuffer(buffer->getId(), releaseFence ? releaseFence : Fence::NO_FENCE,
-                              transformHint);
+                              transformHint, currentMaxAcquiredBufferCount);
 }
 } // namespace
 
@@ -75,7 +75,9 @@
     if (mBufferInfo.mBuffer != nullptr && !isClone()) {
         callReleaseBufferCallback(mDrawingState.releaseBufferListener,
                                   mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFence,
-                                  mTransformHint);
+                                  mTransformHint,
+                                  mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
+                                          mOwnerUid));
     }
 }
 
@@ -199,6 +201,8 @@
     for (const auto& handle : mDrawingState.callbackHandles) {
         handle->transformHint = mTransformHint;
         handle->dequeueReadyTime = dequeueReadyTime;
+        handle->currentMaxAcquiredBufferCount =
+                mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
     }
 
     // If there are multiple transactions in this frame, set the previous id on the earliest
@@ -429,9 +433,10 @@
             // dropped and we should decrement the pending buffer count and
             // call any release buffer callbacks if set.
             callReleaseBufferCallback(mCurrentState.releaseBufferListener,
-                                      mCurrentState.buffer->getBuffer(),
-                                      mCurrentState.acquireFence,
-                                      mTransformHint);
+                                      mCurrentState.buffer->getBuffer(), mCurrentState.acquireFence,
+                                      mTransformHint,
+                                      mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
+                                              mOwnerUid));
             decrementPendingBufferCount();
             if (mCurrentState.bufferSurfaceFrameTX != nullptr) {
                 addSurfaceFrameDroppedForBuffer(mCurrentState.bufferSurfaceFrameTX);
@@ -951,7 +956,9 @@
         // call any release buffer callbacks if set.
         callReleaseBufferCallback(mDrawingState.releaseBufferListener,
                                   mDrawingState.buffer->getBuffer(), mDrawingState.acquireFence,
-                                  mTransformHint);
+                                  mTransformHint,
+                                  mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
+                                          mOwnerUid));
         decrementPendingBufferCount();
     }
 }
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 4b8cbfb..e0b3640 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -205,6 +205,10 @@
 }
 
 std::optional<Fps> Scheduler::getFrameRateOverride(uid_t uid) const {
+    if (!mRefreshRateConfigs.supportsFrameRateOverride()) {
+        return std::nullopt;
+    }
+
     std::lock_guard lock(mFrameRateOverridesMutex);
     {
         const auto iter = mFrameRateOverridesFromBackdoor.find(uid);
@@ -224,10 +228,6 @@
 }
 
 bool Scheduler::isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const {
-    if (!mRefreshRateConfigs.supportsFrameRateOverride()) {
-        return true;
-    }
-
     const auto frameRate = getFrameRateOverride(uid);
     if (!frameRate.has_value()) {
         return true;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c1d28b1..a39ae58 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5247,7 +5247,7 @@
         case CAPTURE_DISPLAY:
         case SET_FRAME_TIMELINE_INFO:
         case GET_GPU_CONTEXT_PRIORITY:
-        case GET_EXTRA_BUFFER_COUNT: {
+        case GET_MAX_ACQUIRED_BUFFER_COUNT: {
             // This is not sensitive information, so should not require permission control.
             return OK;
         }
@@ -6800,25 +6800,38 @@
     return getRenderEngine().getContextPriority();
 }
 
-int SurfaceFlinger::calculateExtraBufferCount(Fps maxSupportedRefreshRate,
-                                              std::chrono::nanoseconds presentLatency) {
-    auto pipelineDepth = presentLatency.count() / maxSupportedRefreshRate.getPeriodNsecs();
-    if (presentLatency.count() % maxSupportedRefreshRate.getPeriodNsecs()) {
+int SurfaceFlinger::calculateMaxAcquiredBufferCount(Fps refreshRate,
+                                                    std::chrono::nanoseconds presentLatency) {
+    auto pipelineDepth = presentLatency.count() / refreshRate.getPeriodNsecs();
+    if (presentLatency.count() % refreshRate.getPeriodNsecs()) {
         pipelineDepth++;
     }
-    return std::max(0ll, pipelineDepth - 2);
+    return std::max(1ll, pipelineDepth - 1);
 }
 
-status_t SurfaceFlinger::getExtraBufferCount(int* extraBuffers) const {
+status_t SurfaceFlinger::getMaxAcquiredBufferCount(int* buffers) const {
     const auto maxSupportedRefreshRate = mRefreshRateConfigs->getSupportedRefreshRateRange().max;
-    const auto vsyncConfig =
-            mVsyncConfiguration->getConfigsForRefreshRate(maxSupportedRefreshRate).late;
-    const auto presentLatency = vsyncConfig.appWorkDuration + vsyncConfig.sfWorkDuration;
-
-    *extraBuffers = calculateExtraBufferCount(maxSupportedRefreshRate, presentLatency);
+    *buffers = getMaxAcquiredBufferCountForRefreshRate(maxSupportedRefreshRate);
     return NO_ERROR;
 }
 
+int SurfaceFlinger::getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const {
+    const auto refreshRate = [&] {
+        const auto frameRateOverride = mScheduler->getFrameRateOverride(uid);
+        if (frameRateOverride.has_value()) {
+            return frameRateOverride.value();
+        }
+        return mRefreshRateConfigs->getCurrentRefreshRate().getFps();
+    }();
+    return getMaxAcquiredBufferCountForRefreshRate(refreshRate);
+}
+
+int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const {
+    const auto vsyncConfig = mVsyncConfiguration->getConfigsForRefreshRate(refreshRate).late;
+    const auto presentLatency = vsyncConfig.appWorkDuration + vsyncConfig.sfWorkDuration;
+    return calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
+}
+
 void SurfaceFlinger::TransactionState::traverseStatesWithBuffers(
         std::function<void(const layer_state_t&)> visitor) {
     for (const auto& state : states) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index a3fa8d6..22d17eb 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -708,7 +708,7 @@
 
     int getGPUContextPriority() override;
 
-    status_t getExtraBufferCount(int* extraBuffers) const override;
+    status_t getMaxAcquiredBufferCount(int* buffers) const override;
 
     // Implements IBinder::DeathRecipient.
     void binderDied(const wp<IBinder>& who) override;
@@ -923,6 +923,8 @@
     size_t getMaxTextureSize() const;
     size_t getMaxViewportDims() const;
 
+    int getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const;
+
     /*
      * Display and layer stack management
      */
@@ -1062,6 +1064,7 @@
 
     // Calculates the expected present time for this frame. For negative offsets, performs a
     // correction using the predicted vsync for the next frame instead.
+
     nsecs_t calculateExpectedPresentTime(DisplayStatInfo) const;
 
     /*
@@ -1177,8 +1180,9 @@
     std::vector<ui::ColorMode> getDisplayColorModes(PhysicalDisplayId displayId)
             REQUIRES(mStateLock);
 
-    static int calculateExtraBufferCount(Fps maxSupportedRefreshRate,
-                                         std::chrono::nanoseconds presentLatency);
+    static int calculateMaxAcquiredBufferCount(Fps refreshRate,
+                                               std::chrono::nanoseconds presentLatency);
+    int getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const;
 
     sp<StartPropertySetThread> mStartPropertySetThread;
     surfaceflinger::Factory& mFactory;
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index 4f4c02b..fdf16a7 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -235,8 +235,9 @@
                                           handle->dequeueReadyTime);
         transactionStats->surfaceStats.emplace_back(surfaceControl, handle->acquireTime,
                                                     handle->previousReleaseFence,
-                                                    handle->transformHint, eventStats, jankData,
-                                                    handle->previousBufferId);
+                                                    handle->transformHint,
+                                                    handle->currentMaxAcquiredBufferCount,
+                                                    eventStats, jankData, handle->previousBufferId);
     }
     return NO_ERROR;
 }
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h
index 184b151..444bec6 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.h
+++ b/services/surfaceflinger/TransactionCallbackInvoker.h
@@ -45,6 +45,7 @@
     nsecs_t acquireTime = -1;
     nsecs_t latchTime = -1;
     uint32_t transformHint = 0;
+    uint32_t currentMaxAcquiredBufferCount = 0;
     std::shared_ptr<FenceTime> gpuCompositionDoneFence{FenceTime::NO_FENCE};
     CompositorTiming compositorTiming;
     nsecs_t refreshStartTime = 0;
diff --git a/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp b/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp
index fb7d41c..5aa809d 100644
--- a/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp
+++ b/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp
@@ -30,7 +30,8 @@
 class ReleaseBufferCallbackHelper {
 public:
     static void function(void* callbackContext, uint64_t graphicsBufferId,
-                         const sp<Fence>& releaseFence) {
+                         const sp<Fence>& releaseFence,
+                         uint32_t /*currentMaxAcquiredBufferCount*/) {
         if (!callbackContext) {
             FAIL() << "failed to get callback context";
         }
@@ -66,7 +67,7 @@
 
     android::ReleaseBufferCallback getCallback() {
         return std::bind(function, static_cast<void*>(this) /* callbackContext */,
-                         std::placeholders::_1, std::placeholders::_2);
+                         std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
     }
 
     std::mutex mMutex;
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 423d0cc..f680d80 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -210,14 +210,14 @@
     EXPECT_CALL(*mEventThread, onModeChanged(_, _, _)).Times(0);
 }
 
-TEST_F(SchedulerTest, calculateExtraBufferCount) {
-    EXPECT_EQ(0, mFlinger.calculateExtraBufferCount(Fps(60), 30ms));
-    EXPECT_EQ(1, mFlinger.calculateExtraBufferCount(Fps(90), 30ms));
-    EXPECT_EQ(2, mFlinger.calculateExtraBufferCount(Fps(120), 30ms));
+TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
+    EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 30ms));
+    EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(Fps(90), 30ms));
+    EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(Fps(120), 30ms));
 
-    EXPECT_EQ(1, mFlinger.calculateExtraBufferCount(Fps(60), 40ms));
+    EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 40ms));
 
-    EXPECT_EQ(0, mFlinger.calculateExtraBufferCount(Fps(60), 10ms));
+    EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(Fps(60), 10ms));
 }
 
 MATCHER(Is120Hz, "") {
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index d78f36c..b363146 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -391,9 +391,9 @@
 
     auto getGPUContextPriority() { return mFlinger->getGPUContextPriority(); }
 
-    auto calculateExtraBufferCount(Fps maxSupportedRefreshRate,
-                                   std::chrono::nanoseconds presentLatency) const {
-        return SurfaceFlinger::calculateExtraBufferCount(maxSupportedRefreshRate, presentLatency);
+    auto calculateMaxAcquiredBufferCount(Fps refreshRate,
+                                         std::chrono::nanoseconds presentLatency) const {
+        return SurfaceFlinger::calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
     }
 
     /* ------------------------------------------------------------------------