SF: Add composition strategy prediction stats

Track number of frames we attempted to predict
the composition strategy and the number of
frames it was successful. This should only be used
as a convenient way to debug locally. Composition
strategy prediction hit and misses are also tracked
via trace tags and can be extracted for metrics.

Enable stats: adb shell su root dumpsys SurfaceFlinger --timestats -enable
Dump stats: adb shell su root dumpsys SurfaceFlinger --timestats -dump -maxlayers 0
Clear stats: adb shell su root dumpsys SurfaceFlinger --timestats -clear

Test: adb shell
Bug: 220031739
Change-Id: Ifc35efa7ce110e82041f529b58acebfa1c325f36
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 77c7973..7a159b8 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -45,7 +45,7 @@
     virtual ~TimeStats() = default;
 
     // Process a pull request from statsd.
-    virtual bool onPullAtom(const int atomId, std::string* pulledData);
+    virtual bool onPullAtom(const int atomId, std::string* pulledData) = 0;
 
     virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
     virtual bool isEnabled() = 0;
@@ -53,14 +53,8 @@
 
     virtual void incrementTotalFrames() = 0;
     virtual void incrementMissedFrames() = 0;
-    virtual void incrementClientCompositionFrames() = 0;
-    virtual void incrementClientCompositionReusedFrames() = 0;
     // Increments the number of times the display refresh rate changed.
     virtual void incrementRefreshRateSwitches() = 0;
-    // Increments the number of changes in composition strategy
-    // The intention is to reflect the number of changes between hwc and gpu
-    // composition, where "gpu composition" may also include mixed composition.
-    virtual void incrementCompositionStrategyChanges() = 0;
     // Records the most up-to-date count of display event connections.
     // The stored count will be the maximum ever recoded.
     virtual void recordDisplayEventConnectionCount(int32_t count) = 0;
@@ -158,6 +152,24 @@
         }
     };
 
+    struct ClientCompositionRecord {
+        // Frame had client composition or mixed composition
+        bool hadClientComposition = false;
+        // Composition changed between hw composition and mixed/client composition
+        bool changed = false;
+        // Frame reused the client composition result from a previous frame
+        bool reused = false;
+        // Composition strategy predicted for frame
+        bool predicted = false;
+        // Composition strategy prediction succeeded
+        bool predictionSucceeded = false;
+
+        // Whether there is data we want to record.
+        bool hasInterestingData() const {
+            return hadClientComposition || changed || reused || predicted;
+        }
+    };
+
     virtual void incrementJankyFrames(const JankyFramesInfo& info) = 0;
     // Clean up the layer record
     virtual void onDestroy(int32_t layerId) = 0;
@@ -169,6 +181,7 @@
     // Source of truth is RefrehRateStats.
     virtual void recordRefreshRate(uint32_t fps, nsecs_t duration) = 0;
     virtual void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) = 0;
+    virtual void pushCompositionStrategyState(const ClientCompositionRecord&) = 0;
 };
 
 namespace impl {
@@ -236,10 +249,7 @@
 
     void incrementTotalFrames() override;
     void incrementMissedFrames() override;
-    void incrementClientCompositionFrames() override;
-    void incrementClientCompositionReusedFrames() override;
     void incrementRefreshRateSwitches() override;
-    void incrementCompositionStrategyChanges() override;
     void recordDisplayEventConnectionCount(int32_t count) override;
 
     void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) override;
@@ -275,6 +285,8 @@
     void recordRefreshRate(uint32_t fps, nsecs_t duration) override;
     void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) override;
 
+    void pushCompositionStrategyState(const ClientCompositionRecord&) override;
+
     static const size_t MAX_NUM_TIME_RECORDS = 64;
 
 private: