am 533e6790: am c554b77b: Skip first frame for app transitions when possible

* commit '533e67900d2ff8b3aec50c1fd5438495606ddf6e':
  Skip first frame for app transitions when possible
This commit is contained in:
Jorim Jaggi
2015-06-05 22:24:24 +00:00
committed by Android Git Automerger
3 changed files with 34 additions and 4 deletions

View File

@@ -950,6 +950,16 @@ public class AppTransition implements Dump {
return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
}
/**
* @return true if and only if the first frame of the transition can be skipped, i.e. the first
* frame of the transition doesn't change the visuals on screen, so we can start
* directly with the second one
*/
boolean canSkipFirstFrame() {
return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
&& mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
&& mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL;
}
Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,

View File

@@ -24,6 +24,7 @@ import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
import android.graphics.Matrix;
import android.util.Slog;
import android.util.TimeUtils;
import android.view.Choreographer;
import android.view.Display;
import android.view.SurfaceControl;
import android.view.WindowManagerPolicy;
@@ -89,6 +90,8 @@ public class AppWindowAnimator {
* See {@link #transferCurrentAnimation}*/
boolean usingTransferredAnimation = false;
private boolean mSkipFirstFrame = false;
static final Animation sDummyAnimation = new DummyAnimation();
public AppWindowAnimator(final AppWindowToken atoken) {
@@ -97,7 +100,7 @@ public class AppWindowAnimator {
mAnimator = atoken.mAnimator;
}
public void setAnimation(Animation anim, int width, int height) {
public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame) {
if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
+ ": " + anim + " wxh=" + width + "x" + height
+ " isVisible=" + mAppToken.isVisible());
@@ -125,6 +128,8 @@ public class AppWindowAnimator {
transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
hasTransformation = true;
this.mSkipFirstFrame = skipFirstFrame;
if (!mAppToken.appFullscreen) {
anim.setBackgroundColor(0);
}
@@ -271,6 +276,18 @@ public class AppWindowAnimator {
return hasMoreFrames;
}
private long getStartTimeCorrection() {
if (mSkipFirstFrame) {
// If the transition is an animation in which the first frame doesn't change the screen
// contents at all, we can just skip it and start at the second frame. So we shift the
// start time of the animation forward by minus the frame duration.
return -Choreographer.getInstance().getFrameIntervalNanos() / TimeUtils.NANOS_PER_MS;
} else {
return 0;
}
}
// This must be called while inside a transaction.
boolean stepAnimationLocked(long currentTime, final int displayId) {
if (mService.okToDisplay()) {
@@ -292,12 +309,14 @@ public class AppWindowAnimator {
" @ " + currentTime + " scale="
+ mService.getTransitionAnimationScaleLocked()
+ " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
animation.setStartTime(currentTime);
long correction = getStartTimeCorrection();
animation.setStartTime(currentTime + correction);
animating = true;
if (thumbnail != null) {
thumbnail.show();
thumbnailAnimation.setStartTime(currentTime);
thumbnailAnimation.setStartTime(currentTime + correction);
}
mSkipFirstFrame = false;
}
if (stepAnimation(currentTime)) {
// animation isn't over, step any thumbnail and that's

View File

@@ -3489,7 +3489,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
}
atoken.mAppAnimator.setAnimation(a, width, height);
atoken.mAppAnimator.setAnimation(a, width, height,
mAppTransition.canSkipFirstFrame());
}
} else {
atoken.mAppAnimator.clearAnimation();