Fade recents thumbnail to transparent earlier.
- Reduce the gpu load by fading the recents thumbnail to an alpha of
0.0 before the remaining animations are completed. When alpha hits
0 the gpu treats the layer as hidden and can render the remaining
layers faster.
- Refactoring of animations to:
o Remove unused setInterpolator() calls on AnimationSet constituents.
o Remove unnecessary setFillBefore() calls.
o Consolidate setDuration() calls into AnimationSet.
o Create Interpolators once.
o Group animation set calls with their Animations.
o Use same animation timing and Interpolator for all animations.
This is a partial fix for 7729214.
Change-Id: Ic3c47bcf7c84944128effb699efcdd1f89200fc4
diff --git a/services/java/com/android/server/wm/AppTransition.java b/services/java/com/android/server/wm/AppTransition.java
index 92fd68b..7736c93 100644
--- a/services/java/com/android/server/wm/AppTransition.java
+++ b/services/java/com/android/server/wm/AppTransition.java
@@ -30,7 +30,6 @@
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
-import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.ScaleAnimation;
@@ -50,9 +49,14 @@
// made visible or hidden at the next transition.
public class AppTransition implements Dump {
private static final String TAG = "AppTransition";
- private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f;
- private static final boolean DEBUG_APP_TRANSITIONS = WindowManagerService.DEBUG_APP_TRANSITIONS;
- private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_APP_TRANSITIONS;
+ private static final boolean DEBUG_APP_TRANSITIONS =
+ WindowManagerService.DEBUG_APP_TRANSITIONS;
+ private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
+
+ /** Fraction of animation at which the recents thumbnail becomes completely transparent */
+ static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.25f;
+
+ static final long DEFAULT_APP_TRANSITION_DURATION = 250;
final Context mContext;
final Handler mH;
@@ -75,15 +79,26 @@
boolean mAppTransitionTimeout = false;
final int mConfigShortAnimTime;
- final Interpolator mInterpolator;
+ private final Interpolator mDecelerateInterpolator;
+ private final Interpolator mThumbnailFadeoutInterpolator;
AppTransition(Context context, Handler h) {
mContext = context;
mH = h;
mConfigShortAnimTime = context.getResources().getInteger(
com.android.internal.R.integer.config_shortAnimTime);
- mInterpolator = AnimationUtils.loadInterpolator(context,
- com.android.internal.R.interpolator.decelerate_quad);
+ mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.decelerate_cubic);
+ mThumbnailFadeoutInterpolator = new Interpolator() {
+ @Override
+ public float getInterpolation(float input) {
+ // Linear response for first fraction, then complete after that.
+ if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) {
+ return input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
+ }
+ return 1.0f;
+ }
+ };
}
boolean isTransitionSet() {
@@ -99,7 +114,7 @@
}
int getAppTransition() {
- return mNextAppTransition;
+ return mNextAppTransition;
}
void setAppTransition(int transit) {
@@ -229,24 +244,6 @@
return null;
}
- private Animation createExitAnimationLocked(int transit, int duration) {
- if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
- transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
- // If we are on top of the wallpaper, we need an animation that
- // correctly handles the wallpaper staying static behind all of
- // the animated elements. To do this, will just have the existing
- // element fade out.
- Animation a = new AlphaAnimation(1, 0);
- a.setDetachWallpaper(true);
- a.setDuration(duration);
- return a;
- }
- // For normal animations, the exiting element just holds in place.
- Animation a = new AlphaAnimation(1, 1);
- a.setDuration(duration);
- return a;
- }
-
/**
* Compute the pivot point for an animation that is scaling from a small
* rect on screen to a larger rect. The pivot point varies depending on
@@ -268,20 +265,6 @@
private Animation createScaleUpAnimationLocked(int transit, boolean enter,
int appWidth, int appHeight) {
Animation a = null;
- // Pick the desired duration. If this is an inter-activity transition,
- // it is the standard duration for that. Otherwise we use the longer
- // task transition duration.
- int duration;
- switch (transit) {
- case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
- case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
- duration = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_shortAnimTime);
- break;
- default:
- duration = 300;
- break;
- }
if (enter) {
// Entering app zooms out from the center of the initial rect.
float scaleW = mNextAppTransitionStartWidth / (float) appWidth;
@@ -289,22 +272,45 @@
Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
computePivot(mNextAppTransitionStartX, scaleW),
computePivot(mNextAppTransitionStartY, scaleH));
- scale.setDuration(duration);
- AnimationSet set = new AnimationSet(true);
+ scale.setInterpolator(mDecelerateInterpolator);
+
Animation alpha = new AlphaAnimation(0, 1);
- scale.setDuration(duration);
+ alpha.setInterpolator(mThumbnailFadeoutInterpolator);
+
+ AnimationSet set = new AnimationSet(false);
set.addAnimation(scale);
- alpha.setDuration(duration);
set.addAnimation(alpha);
set.setDetachWallpaper(true);
a = set;
+ } else if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
+ transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
+ // If we are on top of the wallpaper, we need an animation that
+ // correctly handles the wallpaper staying static behind all of
+ // the animated elements. To do this, will just have the existing
+ // element fade out.
+ a = new AlphaAnimation(1, 0);
+ a.setDetachWallpaper(true);
} else {
- a = createExitAnimationLocked(transit, duration);
+ // For normal animations, the exiting element just holds in place.
+ a = new AlphaAnimation(1, 1);
}
+
+ // Pick the desired duration. If this is an inter-activity transition,
+ // it is the standard duration for that. Otherwise we use the longer
+ // task transition duration.
+ final long duration;
+ switch (transit) {
+ case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
+ case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
+ duration = mConfigShortAnimTime;
+ break;
+ default:
+ duration = DEFAULT_APP_TRANSITION_DURATION;
+ break;
+ }
+ a.setDuration(duration);
a.setFillAfter(true);
- final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.decelerate_cubic);
- a.setInterpolator(interpolator);
+ a.setInterpolator(mDecelerateInterpolator);
a.initialize(appWidth, appHeight, appWidth, appHeight);
return a;
}
@@ -316,75 +322,43 @@
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
- // Pick the desired duration. If this is an inter-activity transition,
- // it is the standard duration for that. Otherwise we use the longer
- // task transition duration.
- int duration;
- switch (transit) {
- case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
- case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
- duration = mConfigShortAnimTime;
- break;
- default:
- duration = 250;
- break;
- }
if (thumb) {
// Animation for zooming thumbnail from its initial size to
// filling the screen.
if (mNextAppTransitionScaleUp) {
float scaleW = appWidth / thumbWidth;
float scaleH = appHeight / thumbHeight;
-
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
computePivot(mNextAppTransitionStartX, 1 / scaleW),
computePivot(mNextAppTransitionStartY, 1 / scaleH));
- AnimationSet set = new AnimationSet(true);
+ scale.setInterpolator(mDecelerateInterpolator);
+
Animation alpha = new AlphaAnimation(1, 0);
- scale.setDuration(duration);
- scale.setInterpolator(
- new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
+ alpha.setInterpolator(mThumbnailFadeoutInterpolator);
+
+ // This AnimationSet uses the Interpolators assigned above.
+ AnimationSet set = new AnimationSet(false);
set.addAnimation(scale);
- alpha.setDuration(duration);
set.addAnimation(alpha);
- set.setFillBefore(true);
a = set;
} else {
float scaleW = appWidth / thumbWidth;
float scaleH = appHeight / thumbHeight;
-
- Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
+ a = new ScaleAnimation(scaleW, 1, scaleH, 1,
computePivot(mNextAppTransitionStartX, 1 / scaleW),
computePivot(mNextAppTransitionStartY, 1 / scaleH));
- AnimationSet set = new AnimationSet(true);
- Animation alpha = new AlphaAnimation(1, 1);
- scale.setDuration(duration);
- scale.setInterpolator(
- new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
- set.addAnimation(scale);
- alpha.setDuration(duration);
- set.addAnimation(alpha);
- set.setFillBefore(true);
-
- a = set;
}
} else if (enter) {
// Entering app zooms out from the center of the thumbnail.
if (mNextAppTransitionScaleUp) {
float scaleW = thumbWidth / appWidth;
float scaleH = thumbHeight / appHeight;
- Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
+ a = new ScaleAnimation(scaleW, 1, scaleH, 1,
computePivot(mNextAppTransitionStartX, scaleW),
computePivot(mNextAppTransitionStartY, scaleH));
- scale.setDuration(duration);
- scale.setInterpolator(
- new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
- scale.setFillBefore(true);
- a = scale;
} else {
// noop animation
a = new AlphaAnimation(1, 1);
- a.setDuration(duration);
}
} else {
// Exiting app
@@ -398,31 +372,39 @@
// noop animation
a = new AlphaAnimation(1, 1);
}
- a.setDuration(duration);
} else {
float scaleW = thumbWidth / appWidth;
float scaleH = thumbHeight / appHeight;
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
computePivot(mNextAppTransitionStartX, scaleW),
computePivot(mNextAppTransitionStartY, scaleH));
- scale.setDuration(duration);
- scale.setInterpolator(
- new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
- scale.setFillBefore(true);
- AnimationSet set = new AnimationSet(true);
+
Animation alpha = new AlphaAnimation(1, 0);
+
+ AnimationSet set = new AnimationSet(true);
set.addAnimation(scale);
- alpha.setDuration(duration);
- alpha.setInterpolator(new DecelerateInterpolator(
- THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
set.addAnimation(alpha);
- set.setFillBefore(true);
set.setZAdjustment(Animation.ZORDER_TOP);
a = set;
}
}
+
+ // Pick the desired duration. If this is an inter-activity transition,
+ // it is the standard duration for that. Otherwise we use the longer
+ // task transition duration.
+ final long duration;
+ switch (transit) {
+ case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
+ case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
+ duration = mConfigShortAnimTime;
+ break;
+ default:
+ duration = DEFAULT_APP_TRANSITION_DURATION;
+ break;
+ }
+ a.setDuration(duration);
a.setFillAfter(true);
- a.setInterpolator(mInterpolator);
+ a.setInterpolator(mDecelerateInterpolator);
a.initialize(appWidth, appHeight, appWidth, appHeight);
return a;
}