From 2ed39d82db11e88a05baf8f4235b7ae7c6ca6e9d Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Wed, 17 Jun 2020 15:43:13 -0700 Subject: [PATCH] WM: Replace eEarlyWakeup flags with explicit eEarlyWakeup start and end flags eEarlyWakeup flag is used as a hint to SurfaceFlinger to adjust its offsets so it can wakeup earlier and have sufficient time to compose more complex scenes. This flag has been replaced with explicit start and stop flags which ensure the SurfaceFlinger offsets remain consistent during animation. Bug: 158127834 Test: go/wm-smoke Test: systrace to verify new tracepoint and offset behavior Change-Id: Ib9c35c01a6bf02f88ec7cb1778e01909bd2f9055 --- core/java/android/view/SurfaceControl.java | 28 ++++++++++++++ core/java/android/view/SurfaceView.java | 2 +- .../view/SyncRtSurfaceTransactionApplier.java | 12 ++---- .../view/ViewRootInsetsControllerHost.java | 5 +-- core/jni/android_view_SurfaceControl.cpp | 14 +++++++ ...SyncRtSurfaceTransactionApplierCompat.java | 1 - .../shared/system/TransactionCompat.java | 4 +- .../notification/ActivityLaunchAnimator.java | 2 +- .../server/wm/SurfaceAnimationRunner.java | 3 -- .../com/android/server/wm/WindowAnimator.java | 38 ++++++++++++++----- 10 files changed, 79 insertions(+), 30 deletions(-) diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 6f73e8985a8a3..eda2cea4912c2 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -102,6 +102,8 @@ public final class SurfaceControl implements Parcelable { long otherTransactionObj); private static native void nativeSetAnimationTransaction(long transactionObj); private static native void nativeSetEarlyWakeup(long transactionObj); + private static native void nativeSetEarlyWakeupStart(long transactionObj); + private static native void nativeSetEarlyWakeupEnd(long transactionObj); private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder); private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject, @@ -2797,6 +2799,8 @@ public final class SurfaceControl implements Parcelable { } /** + * @deprecated use {@link Transaction#setEarlyWakeupStart()} + * * Indicate that SurfaceFlinger should wake up earlier than usual as a result of this * transaction. This should be used when the caller thinks that the scene is complex enough * that it's likely to hit GL composition, and thus, SurfaceFlinger needs to more time in @@ -2805,11 +2809,35 @@ public final class SurfaceControl implements Parcelable { * Corresponds to setting ISurfaceComposer::eEarlyWakeup * @hide */ + @Deprecated public Transaction setEarlyWakeup() { nativeSetEarlyWakeup(mNativeObject); return this; } + /** + * Provides a hint to SurfaceFlinger to change its offset so that SurfaceFlinger wakes up + * earlier to compose surfaces. The caller should use this as a hint to SurfaceFlinger + * when the scene is complex enough to use GPU composition. The hint will remain active + * until until the client calls {@link Transaction#setEarlyWakeupEnd}. + * + * @hide + */ + public Transaction setEarlyWakeupStart() { + nativeSetEarlyWakeupStart(mNativeObject); + return this; + } + + /** + * Removes the early wake up hint set by {@link Transaction#setEarlyWakeupStart}. + * + * @hide + */ + public Transaction setEarlyWakeupEnd() { + nativeSetEarlyWakeupEnd(mNativeObject); + return this; + } + /** * Sets an arbitrary piece of metadata on the surface. This is a helper for int data. * @hide diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index c098fae11b8c6..a0a9842312656 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -640,7 +640,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mTmpRect.set(0, 0, mSurfaceWidth, mSurfaceHeight); } SyncRtSurfaceTransactionApplier applier = new SyncRtSurfaceTransactionApplier(this); - applier.scheduleApply(false /* earlyWakeup */, + applier.scheduleApply( new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(mSurfaceControl) .withWindowCrop(mTmpRect) .build()); diff --git a/core/java/android/view/SyncRtSurfaceTransactionApplier.java b/core/java/android/view/SyncRtSurfaceTransactionApplier.java index 9c97f3e5b503c..062285ff2f5dc 100644 --- a/core/java/android/view/SyncRtSurfaceTransactionApplier.java +++ b/core/java/android/view/SyncRtSurfaceTransactionApplier.java @@ -53,11 +53,10 @@ public class SyncRtSurfaceTransactionApplier { /** * Schedules applying surface parameters on the next frame. * - * @param earlyWakeup Whether to set {@link Transaction#setEarlyWakeup()} on transaction. * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into * this method to avoid synchronization issues. */ - public void scheduleApply(boolean earlyWakeup, final SurfaceParams... params) { + public void scheduleApply(final SurfaceParams... params) { if (mTargetViewRootImpl == null) { return; } @@ -67,7 +66,7 @@ public class SyncRtSurfaceTransactionApplier { return; } Transaction t = new Transaction(); - applyParams(t, frame, earlyWakeup, params); + applyParams(t, frame, params); }); // Make sure a frame gets scheduled. @@ -78,12 +77,10 @@ public class SyncRtSurfaceTransactionApplier { * Applies surface parameters on the next frame. * @param t transaction to apply all parameters in. * @param frame frame to synchronize to. Set -1 when sync is not required. - * @param earlyWakeup Whether to set {@link Transaction#setEarlyWakeup()} on transaction. * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into * this method to avoid synchronization issues. */ - void applyParams(Transaction t, long frame, boolean earlyWakeup, - final SurfaceParams... params) { + void applyParams(Transaction t, long frame, final SurfaceParams... params) { for (int i = params.length - 1; i >= 0; i--) { SurfaceParams surfaceParams = params[i]; SurfaceControl surface = surfaceParams.surface; @@ -92,9 +89,6 @@ public class SyncRtSurfaceTransactionApplier { } applyParams(t, surfaceParams, mTmpFloat9); } - if (earlyWakeup) { - t.setEarlyWakeup(); - } t.apply(); } diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java index 686d561a1a5a5..31a44023b0366 100644 --- a/core/java/android/view/ViewRootInsetsControllerHost.java +++ b/core/java/android/view/ViewRootInsetsControllerHost.java @@ -120,13 +120,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { mApplier = new SyncRtSurfaceTransactionApplier(mViewRoot.mView); } if (mViewRoot.mView.isHardwareAccelerated()) { - mApplier.scheduleApply(false /* earlyWakeup */, params); + mApplier.scheduleApply(params); } else { // Window doesn't support hardware acceleration, no synchronization for now. // TODO(b/149342281): use mViewRoot.mSurface.getNextFrameNumber() to sync on every // frame instead. - mApplier.applyParams(new SurfaceControl.Transaction(), -1 /* frame */, - false /* earlyWakeup */, params); + mApplier.applyParams(new SurfaceControl.Transaction(), -1 /* frame */, params); } } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index e553a786da96b..ae36f8a7b30bf 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -395,6 +395,16 @@ static void nativeSetEarlyWakeup(JNIEnv* env, jclass clazz, jlong transactionObj transaction->setEarlyWakeup(); } +static void nativeSetEarlyWakeupStart(JNIEnv* env, jclass clazz, jlong transactionObj) { + auto transaction = reinterpret_cast(transactionObj); + transaction->setExplicitEarlyWakeupStart(); +} + +static void nativeSetEarlyWakeupEnd(JNIEnv* env, jclass clazz, jlong transactionObj) { + auto transaction = reinterpret_cast(transactionObj); + transaction->setExplicitEarlyWakeupEnd(); +} + static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, jint zorder) { auto transaction = reinterpret_cast(transactionObj); @@ -1501,6 +1511,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetAnimationTransaction }, {"nativeSetEarlyWakeup", "(J)V", (void*)nativeSetEarlyWakeup }, + {"nativeSetEarlyWakeupStart", "(J)V", + (void*)nativeSetEarlyWakeupStart }, + {"nativeSetEarlyWakeupEnd", "(J)V", + (void*)nativeSetEarlyWakeupEnd }, {"nativeSetLayer", "(JJI)V", (void*)nativeSetLayer }, {"nativeSetRelativeLayer", "(JJJI)V", diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java index 31fe22e570848..82e6251a4484f 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java @@ -115,7 +115,6 @@ public class SyncRtSurfaceTransactionApplierCompat { t.deferTransactionUntil(surfaceParams.surface, mBarrierSurfaceControl, frame); surfaceParams.applyTo(t); } - t.setEarlyWakeup(); t.apply(); Trace.traceEnd(Trace.TRACE_TAG_VIEW); Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0) diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java index bdb6c063521f5..b966f9356849c 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java @@ -99,8 +99,8 @@ public class TransactionCompat { return this; } + @Deprecated public TransactionCompat setEarlyWakeup() { - mTransaction.setEarlyWakeup(); return this; } @@ -114,7 +114,7 @@ public class TransactionCompat { t.deferTransactionUntil(surfaceControl, barrier, frameNumber); } + @Deprecated public static void setEarlyWakeup(Transaction t) { - t.setEarlyWakeup(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java index 6a3302473e63e..382715a3fb77d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java @@ -293,7 +293,7 @@ public class ActivityLaunchAnimator { .withCornerRadius(mCornerRadius) .withVisibility(true) .build(); - mSyncRtTransactionApplier.scheduleApply(true /* earlyWakeup */, params); + mSyncRtTransactionApplier.scheduleApply(params); } @Override diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index 5633b6be87b94..837f1b523b687 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -239,9 +239,6 @@ class SurfaceAnimationRunner { } private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) { - if (a.mAnimSpec.needsEarlyWakeup()) { - t.setEarlyWakeup(); - } a.mAnimSpec.apply(t, a.mLeash, currentPlayTime); } diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 92a9e30c2f0a8..9d0bac9dd2905 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -17,6 +17,10 @@ package com.android.server.wm; import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; @@ -52,6 +56,9 @@ public class WindowAnimator { /** Is any window animating? */ private boolean mLastRootAnimating; + /** True if we are running any animations that require expensive composition. */ + private boolean mRunningExpensiveAnimations; + final Choreographer.FrameCallback mAnimationFrameCallback; /** Time of current animation step. Reset on each iteration */ @@ -165,12 +172,8 @@ public class WindowAnimator { mService.mWatermark.drawIfNeeded(); } - SurfaceControl.mergeToGlobalTransaction(mTransaction); } catch (RuntimeException e) { Slog.wtf(TAG, "Unhandled exception in Window Manager", e); - } finally { - mService.closeSurfaceTransaction("WindowAnimator"); - ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate"); } final boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this); @@ -179,21 +182,36 @@ public class WindowAnimator { mService.mWindowPlacerLocked.requestTraversal(); } - final boolean rootAnimating = mService.mRoot.isAnimating(TRANSITION | CHILDREN); + final boolean rootAnimating = mService.mRoot.isAnimating(TRANSITION | CHILDREN /* flags */, + ANIMATION_TYPE_ALL /* typesToCheck */); if (rootAnimating && !mLastRootAnimating) { - // Usually app transitions but quite a load onto the system already (with all the things - // happening in app), so pause task snapshot persisting to not increase the load. - mService.mTaskSnapshotController.setPersisterPaused(true); Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0); } if (!rootAnimating && mLastRootAnimating) { mService.mWindowPlacerLocked.requestTraversal(); - mService.mTaskSnapshotController.setPersisterPaused(false); Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "animating", 0); } - mLastRootAnimating = rootAnimating; + final boolean runningExpensiveAnimations = + mService.mRoot.isAnimating(TRANSITION | CHILDREN /* flags */, + ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_SCREEN_ROTATION + | ANIMATION_TYPE_RECENTS /* typesToCheck */); + if (runningExpensiveAnimations && !mRunningExpensiveAnimations) { + // Usually app transitions put quite a load onto the system already (with all the things + // happening in app), so pause task snapshot persisting to not increase the load. + mService.mTaskSnapshotController.setPersisterPaused(true); + mTransaction.setEarlyWakeupStart(); + } else if (!runningExpensiveAnimations && mRunningExpensiveAnimations) { + mService.mTaskSnapshotController.setPersisterPaused(false); + mTransaction.setEarlyWakeupEnd(); + } + mRunningExpensiveAnimations = runningExpensiveAnimations; + + SurfaceControl.mergeToGlobalTransaction(mTransaction); + mService.closeSurfaceTransaction("WindowAnimator"); + ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate"); + if (mRemoveReplacedWindows) { mService.mRoot.removeReplacedWindows(); mRemoveReplacedWindows = false;