SF: Move/Refactor doComposition and doDisplayComposition to CompositionEngine

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Test: atest CtsColorModeTestCases
Test: atest CtsDisplayTestCases
Test: atest CtsGraphicsTestCases
Test: atest CtsUiRenderingTestCases
Test: atest CtsViewTestCases
Test: atest android.media.cts.EncodeVirtualDisplayWithCompositionTest
Bug: 121291683

Change-Id: I6c796ec613ce163764a403bcd669dab38300f437
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 6cd392e..cabbc08 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -16,6 +16,7 @@
 
 #include <android-base/stringprintf.h>
 #include <compositionengine/CompositionEngine.h>
+#include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayCreationArgs.h>
 #include <compositionengine/DisplaySurface.h>
 #include <compositionengine/impl/Display.h>
@@ -259,4 +260,19 @@
     }
 }
 
+void Display::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs) {
+    // We only need to actually compose the display if:
+    // 1) It is being handled by hardware composer, which may need this to
+    //    keep its virtual display state machine in sync, or
+    // 2) There is work to be done (the dirty region isn't empty)
+    if (!mId) {
+        if (getDirtyRegion(refreshArgs.repaintEverything).isEmpty()) {
+            ALOGV("Skipping display composition");
+            return;
+        }
+    }
+
+    impl::Output::finishFrame(refreshArgs);
+}
+
 } // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 10534f4..8b156f8 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -313,7 +313,7 @@
         if (!dirtyRegion.isEmpty()) {
             base::unique_fd readyFence;
             // redraw the whole screen
-            composeSurfaces(dirtyRegion, &readyFence);
+            static_cast<void>(composeSurfaces(dirtyRegion));
 
             mRenderSurface->queueBuffer(std::move(readyFence));
         }
@@ -326,14 +326,35 @@
     prepareFrame();
 }
 
-bool Output::composeSurfaces(const Region& debugRegion, base::unique_fd* readyFence) {
+void Output::finishFrame(const compositionengine::CompositionRefreshArgs&) {
+    ATRACE_CALL();
+    ALOGV(__FUNCTION__);
+
+    if (!mState.isEnabled) {
+        return;
+    }
+
+    // Repaint the framebuffer (if needed), getting the optional fence for when
+    // the composition completes.
+    auto optReadyFence = composeSurfaces(Region::INVALID_REGION);
+    if (!optReadyFence) {
+        return;
+    }
+
+    // swap buffers (presentation)
+    mRenderSurface->queueBuffer(std::move(*optReadyFence));
+}
+
+std::optional<base::unique_fd> Output::composeSurfaces(const Region& debugRegion) {
     ATRACE_CALL();
     ALOGV(__FUNCTION__);
 
     const TracedOrdinal<bool> hasClientComposition = {"hasClientComposition",
                                                       mState.usesClientComposition};
+    base::unique_fd readyFence;
+
     if (!hasClientComposition) {
-        return true;
+        return readyFence;
     }
 
     ALOGV("hasClientComposition");
@@ -389,7 +410,7 @@
         ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
               "client composition for this frame",
               mName.c_str());
-        return false;
+        return std::nullopt;
     }
 
     // We boost GPU frequency here because there will be color spaces conversion
@@ -404,13 +425,13 @@
 
     renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayers,
                             buf->getNativeBuffer(), /*useFramebufferCache=*/true, std::move(fd),
-                            readyFence);
+                            &readyFence);
 
     if (expensiveRenderingExpected) {
         setExpensiveRenderingExpected(false);
     }
 
-    return true;
+    return readyFence;
 }
 
 std::vector<renderengine::LayerSettings> Output::generateClientCompositionRequests(
@@ -507,6 +528,9 @@
         return;
     }
 
+    mState.dirtyRegion.clear();
+    mRenderSurface->flip();
+
     auto frame = presentAndGetFrameFences();
 
     mRenderSurface->onPresentDisplayCompleted();