am c554b77b: Skip first frame for app transitions when possible
* commit 'c554b77b7392b97e0f455d8276b739e16147d6df': Skip first frame for app transitions when possible
This commit is contained in:
@@ -950,6 +950,16 @@ public class AppTransition implements Dump {
|
|||||||
return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
|
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,
|
Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
|
||||||
int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
|
int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
|
|||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.TimeUtils;
|
import android.util.TimeUtils;
|
||||||
|
import android.view.Choreographer;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.view.WindowManagerPolicy;
|
import android.view.WindowManagerPolicy;
|
||||||
@@ -89,6 +90,8 @@ public class AppWindowAnimator {
|
|||||||
* See {@link #transferCurrentAnimation}*/
|
* See {@link #transferCurrentAnimation}*/
|
||||||
boolean usingTransferredAnimation = false;
|
boolean usingTransferredAnimation = false;
|
||||||
|
|
||||||
|
private boolean mSkipFirstFrame = false;
|
||||||
|
|
||||||
static final Animation sDummyAnimation = new DummyAnimation();
|
static final Animation sDummyAnimation = new DummyAnimation();
|
||||||
|
|
||||||
public AppWindowAnimator(final AppWindowToken atoken) {
|
public AppWindowAnimator(final AppWindowToken atoken) {
|
||||||
@@ -97,7 +100,7 @@ public class AppWindowAnimator {
|
|||||||
mAnimator = atoken.mAnimator;
|
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
|
if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
|
||||||
+ ": " + anim + " wxh=" + width + "x" + height
|
+ ": " + anim + " wxh=" + width + "x" + height
|
||||||
+ " isVisible=" + mAppToken.isVisible());
|
+ " isVisible=" + mAppToken.isVisible());
|
||||||
@@ -125,6 +128,8 @@ public class AppWindowAnimator {
|
|||||||
transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
|
transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
|
||||||
hasTransformation = true;
|
hasTransformation = true;
|
||||||
|
|
||||||
|
this.mSkipFirstFrame = skipFirstFrame;
|
||||||
|
|
||||||
if (!mAppToken.appFullscreen) {
|
if (!mAppToken.appFullscreen) {
|
||||||
anim.setBackgroundColor(0);
|
anim.setBackgroundColor(0);
|
||||||
}
|
}
|
||||||
@@ -271,6 +276,18 @@ public class AppWindowAnimator {
|
|||||||
return hasMoreFrames;
|
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.
|
// This must be called while inside a transaction.
|
||||||
boolean stepAnimationLocked(long currentTime, final int displayId) {
|
boolean stepAnimationLocked(long currentTime, final int displayId) {
|
||||||
if (mService.okToDisplay()) {
|
if (mService.okToDisplay()) {
|
||||||
@@ -292,12 +309,14 @@ public class AppWindowAnimator {
|
|||||||
" @ " + currentTime + " scale="
|
" @ " + currentTime + " scale="
|
||||||
+ mService.getTransitionAnimationScaleLocked()
|
+ mService.getTransitionAnimationScaleLocked()
|
||||||
+ " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
|
+ " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
|
||||||
animation.setStartTime(currentTime);
|
long correction = getStartTimeCorrection();
|
||||||
|
animation.setStartTime(currentTime + correction);
|
||||||
animating = true;
|
animating = true;
|
||||||
if (thumbnail != null) {
|
if (thumbnail != null) {
|
||||||
thumbnail.show();
|
thumbnail.show();
|
||||||
thumbnailAnimation.setStartTime(currentTime);
|
thumbnailAnimation.setStartTime(currentTime + correction);
|
||||||
}
|
}
|
||||||
|
mSkipFirstFrame = false;
|
||||||
}
|
}
|
||||||
if (stepAnimation(currentTime)) {
|
if (stepAnimation(currentTime)) {
|
||||||
// animation isn't over, step any thumbnail and that's
|
// animation isn't over, step any thumbnail and that's
|
||||||
|
|||||||
@@ -3489,7 +3489,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
}
|
}
|
||||||
Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
|
Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
|
||||||
}
|
}
|
||||||
atoken.mAppAnimator.setAnimation(a, width, height);
|
atoken.mAppAnimator.setAnimation(a, width, height,
|
||||||
|
mAppTransition.canSkipFirstFrame());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
atoken.mAppAnimator.clearAnimation();
|
atoken.mAppAnimator.clearAnimation();
|
||||||
|
|||||||
Reference in New Issue
Block a user