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
This commit is contained in:
Vishnu Nair
2020-06-17 15:43:13 -07:00
parent 26dfdc587f
commit 2ed39d82db
10 changed files with 79 additions and 30 deletions

View File

@@ -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

View File

@@ -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());

View File

@@ -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();
}

View File

@@ -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);
}
}

View File

@@ -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<SurfaceComposerClient::Transaction*>(transactionObj);
transaction->setExplicitEarlyWakeupStart();
}
static void nativeSetEarlyWakeupEnd(JNIEnv* env, jclass clazz, jlong transactionObj) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
transaction->setExplicitEarlyWakeupEnd();
}
static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jint zorder) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(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",

View File

@@ -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)

View File

@@ -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();
}
}

View File

@@ -293,7 +293,7 @@ public class ActivityLaunchAnimator {
.withCornerRadius(mCornerRadius)
.withVisibility(true)
.build();
mSyncRtTransactionApplier.scheduleApply(true /* earlyWakeup */, params);
mSyncRtTransactionApplier.scheduleApply(params);
}
@Override

View File

@@ -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);
}

View File

@@ -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;