SF: Restructure message refresh

Bug: 112259502
Test: cts -m CtsViewTestCases
      SurfaceFlinger_test
      vrflinger_test

Change-Id: I08091d64114b644edb32504779b3d05185d2f552
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 78edc17..989f545 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -265,6 +265,7 @@
         mForceFullDamage(false),
         mPrimaryHWVsyncEnabled(false),
         mHWVsyncAvailable(false),
+        mRefreshStartTime(0),
         mHasPoweredOff(false),
         mNumLayers(0),
         mVrFlingerRequestsDisplay(false),
@@ -1574,16 +1575,16 @@
 
     mRefreshPending = false;
 
-    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
-
-    preComposition(refreshStartTime);
+    preComposition();
     rebuildLayerStacks();
     calculateWorkingSet();
+    beginFrame();
+    prepareFrame();
     doDebugFlashRegions();
     doTracing("handleRefresh");
     logLayerStats();
     doComposition();
-    postComposition(refreshStartTime);
+    postComposition();
 
     mHadClientComposition = false;
     for (const auto& [token, display] : mDisplays) {
@@ -1599,32 +1600,6 @@
     ATRACE_CALL();
     ALOGV(__FUNCTION__);
 
-    for (const auto& [token, display] : mDisplays) {
-        bool dirty = !display->getDirtyRegion(mRepaintEverything).isEmpty();
-        bool empty = display->getVisibleLayersSortedByZ().size() == 0;
-        bool wasEmpty = !display->lastCompositionHadVisibleLayers;
-
-        // If nothing has changed (!dirty), don't recompose.
-        // If something changed, but we don't currently have any visible layers,
-        //   and didn't when we last did a composition, then skip it this time.
-        // The second rule does two things:
-        // - When all layers are removed from a display, we'll emit one black
-        //   frame, then nothing more until we get new layers.
-        // - When a display is created with a private layer stack, we won't
-        //   emit any black frames until a layer is added to the layer stack.
-        bool mustRecompose = dirty && !(empty && wasEmpty);
-
-        ALOGV_IF(display->isVirtual(), "Display %d: %s composition (%sdirty %sempty %swasEmpty)",
-                 display->getId(), mustRecompose ? "doing" : "skipping", dirty ? "+" : "-",
-                 empty ? "+" : "-", wasEmpty ? "+" : "-");
-
-        display->beginFrame(mustRecompose);
-
-        if (mustRecompose) {
-            display->lastCompositionHadVisibleLayers = !empty;
-        }
-    }
-
     // build the h/w work list
     if (CC_UNLIKELY(mGeometryInvalid)) {
         mGeometryInvalid = false;
@@ -1697,16 +1672,6 @@
     }
 
     mDrawingState.colorMatrixChanged = false;
-
-    for (const auto& [token, display] : mDisplays) {
-        if (!display->isPoweredOn()) {
-            continue;
-        }
-
-        status_t result = display->prepareFrame(*getBE().mHwc);
-        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %d failed: %d (%s)",
-                 display->getId(), result, strerror(-result));
-    }
 }
 
 void SurfaceFlinger::doDebugFlashRegions()
@@ -1773,14 +1738,16 @@
     }
 }
 
-void SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
+void SurfaceFlinger::preComposition()
 {
     ATRACE_CALL();
     ALOGV("preComposition");
 
+    mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
     bool needExtraInvalidate = false;
     mDrawingState.traverseInZOrder([&](Layer* layer) {
-        if (layer->onPreComposition(refreshStartTime)) {
+        if (layer->onPreComposition(mRefreshStartTime)) {
             needExtraInvalidate = true;
         }
     });
@@ -1849,7 +1816,7 @@
     getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
 }
 
-void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
+void SurfaceFlinger::postComposition()
 {
     ATRACE_CALL();
     ALOGV("postComposition");
@@ -1882,11 +1849,11 @@
     nsecs_t vsyncPhase = mPrimaryDispSync->computeNextRefresh(0);
     nsecs_t vsyncInterval = mPrimaryDispSync->getPeriod();
 
-    // We use the refreshStartTime which might be sampled a little later than
+    // We use the mRefreshStartTime which might be sampled a little later than
     // when we started doing work for this frame, but that should be okay
     // since updateCompositorTiming has snapping logic.
     updateCompositorTiming(
-        vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime);
+        vsyncPhase, vsyncInterval, mRefreshStartTime, presentFenceTime);
     CompositorTiming compositorTiming;
     {
         std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
@@ -2108,6 +2075,47 @@
     display->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent);
 }
 
+void SurfaceFlinger::beginFrame()
+{
+    for (const auto& [token, display] : mDisplays) {
+        bool dirty = !display->getDirtyRegion(mRepaintEverything).isEmpty();
+        bool empty = display->getVisibleLayersSortedByZ().size() == 0;
+        bool wasEmpty = !display->lastCompositionHadVisibleLayers;
+
+        // If nothing has changed (!dirty), don't recompose.
+        // If something changed, but we don't currently have any visible layers,
+        //   and didn't when we last did a composition, then skip it this time.
+        // The second rule does two things:
+        // - When all layers are removed from a display, we'll emit one black
+        //   frame, then nothing more until we get new layers.
+        // - When a display is created with a private layer stack, we won't
+        //   emit any black frames until a layer is added to the layer stack.
+        bool mustRecompose = dirty && !(empty && wasEmpty);
+
+        ALOGV_IF(display->isVirtual(), "Display %d: %s composition (%sdirty %sempty %swasEmpty)",
+                 display->getId(), mustRecompose ? "doing" : "skipping", dirty ? "+" : "-",
+                 empty ? "+" : "-", wasEmpty ? "+" : "-");
+
+        display->beginFrame(mustRecompose);
+
+        if (mustRecompose) {
+            display->lastCompositionHadVisibleLayers = !empty;
+        }
+    }
+}
+
+void SurfaceFlinger::prepareFrame()
+{
+    for (const auto& [token, display] : mDisplays) {
+        if (!display->isPoweredOn()) {
+            continue;
+        }
+
+        status_t result = display->prepareFrame(*getBE().mHwc);
+        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %d failed: %d (%s)",
+                 display->getId(), result, strerror(-result));
+    }
+}
 
 void SurfaceFlinger::doComposition() {
     ATRACE_CALL();