diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index e455155a319e1..aac92709a177e 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, @@ -2775,6 +2777,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 @@ -2783,11 +2787,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 809a9cfde5875..90e1eab09fd67 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;