SF: Move doDebugFlashRegions to CompositionEngine

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: I0ea71e6c86231d6fedca7309889001cea3ecf47b
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
index 20f131e..b329f76 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
@@ -16,6 +16,9 @@
 
 #pragma once
 
+#include <chrono>
+#include <optional>
+
 #include <compositionengine/Display.h>
 #include <compositionengine/Layer.h>
 
@@ -35,6 +38,12 @@
     // the layers is important, and should be in traversal order from back to
     // front.
     Layers layers;
+
+    // If true, forces the entire display to be considered dirty and repainted
+    bool repaintEverything{false};
+
+    // If set, causes the dirty regions to flash with the delay
+    std::optional<std::chrono::microseconds> devOptFlashDirtyRegionsDelay;
 };
 
 } // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index f73304d..df7add2 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -43,6 +43,8 @@
 class RenderSurface;
 class OutputLayer;
 
+struct CompositionRefreshArgs;
+
 namespace impl {
 struct OutputCompositionState;
 } // namespace impl
@@ -157,6 +159,9 @@
     // Prepares a frame for display
     virtual void prepareFrame() = 0;
 
+    // Performs any debug related screen flashing due to the update
+    virtual void devOptRepaintFlash(const CompositionRefreshArgs&) = 0;
+
     // Performs client composition as needed for layers on the output. The
     // output fence is set to a fence to signal when client composition is
     // finished.
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 3972f2b..36d6a69 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -77,6 +77,7 @@
 
     void beginFrame() override;
     void prepareFrame() override;
+    void devOptRepaintFlash(const compositionengine::CompositionRefreshArgs&) override;
     bool composeSurfaces(const Region&, base::unique_fd*) override;
     void postFramebuffer() override;
 
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index c944bec..b9e1c9c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayColorProfile.h>
 #include <compositionengine/Layer.h>
 #include <compositionengine/LayerFE.h>
@@ -77,6 +78,8 @@
     MOCK_METHOD0(prepareFrame, void());
     MOCK_METHOD0(chooseCompositionStrategy, void());
 
+    MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
+
     MOCK_METHOD2(composeSurfaces, bool(const Region&, base::unique_fd*));
     MOCK_CONST_METHOD0(getSkipColorTransform, bool());
 
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 2483c06..10534f4 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
+#include <thread>
+
 #include <android-base/stringprintf.h>
 #include <compositionengine/CompositionEngine.h>
+#include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayColorProfile.h>
 #include <compositionengine/Layer.h>
 #include <compositionengine/LayerFE.h>
@@ -299,6 +302,30 @@
     mRenderSurface->prepareFrame(mState.usesClientComposition, mState.usesDeviceComposition);
 }
 
+void Output::devOptRepaintFlash(const compositionengine::CompositionRefreshArgs& refreshArgs) {
+    if (CC_LIKELY(!refreshArgs.devOptFlashDirtyRegionsDelay)) {
+        return;
+    }
+
+    if (mState.isEnabled) {
+        // transform the dirty region into this screen's coordinate space
+        const Region dirtyRegion = getDirtyRegion(refreshArgs.repaintEverything);
+        if (!dirtyRegion.isEmpty()) {
+            base::unique_fd readyFence;
+            // redraw the whole screen
+            composeSurfaces(dirtyRegion, &readyFence);
+
+            mRenderSurface->queueBuffer(std::move(readyFence));
+        }
+    }
+
+    postFramebuffer();
+
+    std::this_thread::sleep_for(*refreshArgs.devOptFlashDirtyRegionsDelay);
+
+    prepareFrame();
+}
+
 bool Output::composeSurfaces(const Region& debugRegion, base::unique_fd* readyFence) {
     ATRACE_CALL();
     ALOGV(__FUNCTION__);