summaryrefslogtreecommitdiffstats
path: root/graphics
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2014-09-05 16:53:25 -0700
committerChet Haase <chet@google.com>2014-09-10 21:21:53 +0000
commit6f6578e81c1df207da47e2e1337382341f271206 (patch)
treed6ce571eb3ce3a5997e05e4624c3364a593a9cb1 /graphics
parent9da6c905772c6ba1d7dff91593ba9f9cf85d2483 (diff)
downloadframeworks_base-6f6578e81c1df207da47e2e1337382341f271206.zip
frameworks_base-6f6578e81c1df207da47e2e1337382341f271206.tar.gz
frameworks_base-6f6578e81c1df207da47e2e1337382341f271206.tar.bz2
Use constant state in AnimatedVectorDrawable
Complex animated vector drawables can be expensive to load due to sub-optimal parsing of the String-based pathData. Suffering that penalty every time the same drawable is loaded (such as material-themed ProgressBars) is painful. The new approach caches constant state of both the VectorDrawable (including the pathData geometry) and the animators (which includes potentially expensive path-based interpolators). issue #17366831 Material ProgressBar taking 200+ms to inflate Change-Id: Iba3b541e24cfce8c07f5aa9fe6aa7d7b92b2fe1c
Diffstat (limited to 'graphics')
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java47
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java17
2 files changed, 55 insertions, 9 deletions
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index e5e2f18..49e8b9d 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -27,6 +27,7 @@ import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.PorterDuff;
import android.graphics.Rect;
+import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
@@ -131,7 +132,9 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
- private final AnimatedVectorDrawableState mAnimatedVectorState;
+ private AnimatedVectorDrawableState mAnimatedVectorState;
+
+ private boolean mMutated;
public AnimatedVectorDrawable() {
mAnimatedVectorState = new AnimatedVectorDrawableState(
@@ -140,7 +143,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
private AnimatedVectorDrawable(AnimatedVectorDrawableState state, Resources res,
Theme theme) {
- // TODO: Correctly handle the constant state for AVD.
mAnimatedVectorState = new AnimatedVectorDrawableState(state);
if (theme != null && canApplyTheme()) {
applyTheme(theme);
@@ -148,8 +150,17 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
}
@Override
+ public Drawable mutate() {
+ if (!mMutated && super.mutate() == this) {
+ mAnimatedVectorState = new AnimatedVectorDrawableState(mAnimatedVectorState);
+ mMutated = true;
+ }
+ return this;
+ }
+
+ @Override
public ConstantState getConstantState() {
- return null;
+ return mAnimatedVectorState;
}
@Override
@@ -311,14 +322,31 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
int mChangingConfigurations;
VectorDrawable mVectorDrawable;
ArrayList<Animator> mAnimators;
+ ArrayMap<Animator, String> mTargetNameMap;
public AnimatedVectorDrawableState(AnimatedVectorDrawableState copy) {
if (copy != null) {
mChangingConfigurations = copy.mChangingConfigurations;
- // TODO: Make sure the constant state are handled correctly.
- mVectorDrawable = new VectorDrawable();
- mVectorDrawable.setAllowCaching(false);
- mAnimators = new ArrayList<Animator>();
+ if (copy.mVectorDrawable != null) {
+ mVectorDrawable = (VectorDrawable) copy.mVectorDrawable.getConstantState().newDrawable();
+ mVectorDrawable.mutate();
+ mVectorDrawable.setAllowCaching(false);
+ mVectorDrawable.setBounds(copy.mVectorDrawable.getBounds());
+ }
+ if (copy.mAnimators != null) {
+ final int numAnimators = copy.mAnimators.size();
+ mAnimators = new ArrayList<Animator>(numAnimators);
+ mTargetNameMap = new ArrayMap<Animator, String>(numAnimators);
+ for (int i = 0; i < numAnimators; ++i) {
+ Animator anim = copy.mAnimators.get(i);
+ Animator animClone = anim.clone();
+ String targetName = copy.mTargetNameMap.get(anim);
+ Object targetObject = mVectorDrawable.getTargetByName(targetName);
+ animClone.setTarget(targetObject);
+ mAnimators.add(animClone);
+ mTargetNameMap.put(animClone, targetName);
+ }
+ }
}
}
@@ -346,7 +374,12 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable {
private void setupAnimatorsForTarget(String name, Animator animator) {
Object target = mAnimatedVectorState.mVectorDrawable.getTargetByName(name);
animator.setTarget(target);
+ if (mAnimatedVectorState.mAnimators == null) {
+ mAnimatedVectorState.mAnimators = new ArrayList<Animator>();
+ mAnimatedVectorState.mTargetNameMap = new ArrayMap<Animator, String>();
+ }
mAnimatedVectorState.mAnimators.add(animator);
+ mAnimatedVectorState.mTargetNameMap.put(animator, name);
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
Log.v(LOGTAG, "add animator for target " + name + " " + animator);
}
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index a07ccc4..65ab454 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -629,6 +629,15 @@ public class VectorDrawable extends Drawable {
mThemeAttrs = copy.mThemeAttrs;
mChangingConfigurations = copy.mChangingConfigurations;
mVPathRenderer = new VPathRenderer(copy.mVPathRenderer);
+ if (copy.mVPathRenderer.mFillPaint != null) {
+ mVPathRenderer.mFillPaint = new Paint(copy.mVPathRenderer.mFillPaint);
+ }
+ if (copy.mVPathRenderer.mStrokePaint != null) {
+ mVPathRenderer.mStrokePaint = new Paint(copy.mVPathRenderer.mStrokePaint);
+ }
+ if (copy.mVPathRenderer.mColorFilter != null) {
+ mVPathRenderer.mColorFilter = copy.mVPathRenderer.mColorFilter;
+ }
mTint = copy.mTint;
mTintMode = copy.mTintMode;
mAutoMirrored = copy.mAutoMirrored;
@@ -700,8 +709,8 @@ public class VectorDrawable extends Drawable {
*/
// Variables that only used temporarily inside the draw() call, so there
// is no need for deep copying.
- private final Path mPath = new Path();
- private final Path mRenderPath = new Path();
+ private final Path mPath;
+ private final Path mRenderPath;
private static final Matrix IDENTITY_MATRIX = new Matrix();
private final Matrix mFinalPathMatrix = new Matrix();
@@ -724,6 +733,8 @@ public class VectorDrawable extends Drawable {
public VPathRenderer() {
mRootGroup = new VGroup();
+ mPath = new Path();
+ mRenderPath = new Path();
}
public void setRootAlpha(int alpha) {
@@ -736,6 +747,8 @@ public class VectorDrawable extends Drawable {
public VPathRenderer(VPathRenderer copy) {
mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
+ mPath = new Path(copy.mPath);
+ mRenderPath = new Path(copy.mRenderPath);
mBaseWidth = copy.mBaseWidth;
mBaseHeight = copy.mBaseHeight;
mViewportWidth = copy.mViewportWidth;