Skip performance hint for the end of scene transition

Currently, the transition from convertFromTranslucent is like to
commit visibility from client side. As it is usually called for
ending the scene transition, there won't have any animation effect.
e.g. A starts B
  > B convertsToTranslucent (B->translucent)
   > Play scene transition ~ animation finish
    > B convertFromTranslucent  (B->opaque so A becomes invisible)

The last step only needs to go through the standard procedure of
shell transition for visibility change. Otherwise the early-wakeup
sf hint could add a dropped frame that causes the following frames
to be classified as scheduling jank.

Bug: 314261955
Test: UiBenchActivityTransitionsAnimationMicrobenchmark
Change-Id: I1eafd69ccb95816e4f4b7d5f62c4999d9f04d20d
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index f620a97..2accf9a 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -2841,6 +2841,19 @@
         }
     }
 
+    /** Returns {@code true} if the display should use high performance hint for this transition. */
+    boolean shouldUsePerfHint(@NonNull DisplayContent dc) {
+        if (mOverrideOptions != null
+                && mOverrideOptions.getType() == ActivityOptions.ANIM_SCENE_TRANSITION
+                && mType == TRANSIT_TO_BACK && mParticipants.size() == 1) {
+            // This should be from convertFromTranslucent that makes the occluded activity invisible
+            // without animation. So do not use perf hint (especially early-wakeup) that may disturb
+            // SurfaceFlinger scheduling around the last frame.
+            return false;
+        }
+        return mTargetDisplays.contains(dc);
+    }
+
     /**
      * Returns {@code true} if the transition and the corresponding transaction should be applied
      * on display thread. Currently, this only checks for display rotation change because the order
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 708d63e..59e3350 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -1237,8 +1237,15 @@
             // enableHighPerfTransition(true) is also called in Transition#recordDisplay.
             for (int i = mAtm.mRootWindowContainer.getChildCount() - 1; i >= 0; i--) {
                 final DisplayContent dc = mAtm.mRootWindowContainer.getChildAt(i);
-                if (isTransitionOnDisplay(dc)) {
+                if (mCollectingTransition != null && mCollectingTransition.shouldUsePerfHint(dc)) {
                     dc.enableHighPerfTransition(true);
+                    continue;
+                }
+                for (int j = mPlayingTransitions.size() - 1; j >= 0; j--) {
+                    if (mPlayingTransitions.get(j).shouldUsePerfHint(dc)) {
+                        dc.enableHighPerfTransition(true);
+                        break;
+                    }
                 }
             }
             // Usually transitions put quite a load onto the system already (with all the things