Support repeatMode = reverse in AVD am: f7167e8f28

am: 113a8c63d4

Change-Id: I1872a2e6187956bf72337832f106b9fd833c4834
This commit is contained in:
Doris Liu
2016-08-06 01:15:51 +00:00
committed by android-build-merger
5 changed files with 58 additions and 31 deletions

View File

@@ -83,11 +83,13 @@ static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishLis
}
static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr,
jlong interpolatorPtr, jlong startDelay, jlong duration, jint repeatCount) {
jlong interpolatorPtr, jlong startDelay, jlong duration, jint repeatCount,
jint repeatMode) {
PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr);
Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
set->addPropertyAnimator(holder, interpolator, startDelay, duration, repeatCount);
RepeatMode mode = static_cast<RepeatMode>(repeatMode);
set->addPropertyAnimator(holder, interpolator, startDelay, duration, repeatCount, mode);
}
static jlong createAnimatorSet(JNIEnv*, jobject) {
@@ -185,7 +187,7 @@ static void reset(JNIEnv*, jobject, jlong animatorSetPtr) {
static const JNINativeMethod gMethods[] = {
{"nCreateAnimatorSet", "()J", (void*)createAnimatorSet},
{"nSetVectorDrawableTarget", "(JJ)V", (void*)setVectorDrawableTarget},
{"nAddAnimator", "(JJJJJI)V", (void*)addAnimator},
{"nAddAnimator", "(JJJJJII)V", (void*)addAnimator},
{"nCreateGroupPropertyHolder", "!(JIFF)J", (void*)createGroupPropertyHolder},
{"nCreatePathDataPropertyHolder", "!(JJJ)J", (void*)createPathDataPropertyHolder},
{"nCreatePathColorPropertyHolder", "!(JIII)J", (void*)createPathColorPropertyHolder},

View File

@@ -1358,7 +1358,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
mStartDelays.add(startDelay);
nAddAnimator(mSetPtr, propertyPtr, nativeInterpolator, startDelay, duration,
repeatCount);
repeatCount, animator.getRepeatMode());
}
/**
@@ -1625,7 +1625,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
private static native long nCreateAnimatorSet();
private static native void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr);
private static native void nAddAnimator(long setPtr, long propertyValuesHolder,
long nativeInterpolator, long startDelay, long duration, int repeatCount);
long nativeInterpolator, long startDelay, long duration, int repeatCount,
int repeatMode);
private static native long nCreateGroupPropertyHolder(long nativePtr, int propertyId,
float startValue, float endValue);

View File

@@ -44,6 +44,12 @@ protected:
ANDROID_API virtual ~AnimationListener() {}
};
enum class RepeatMode {
// These are the same values as the RESTART and REVERSE in ValueAnimator.java.
Restart = 1,
Reverse = 2
};
class BaseRenderNodeAnimator : public VirtualLightRefBase {
PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator);
public:

View File

@@ -23,11 +23,11 @@ namespace android {
namespace uirenderer {
void PropertyValuesAnimatorSet::addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder,
Interpolator* interpolator, nsecs_t startDelay,
nsecs_t duration, int repeatCount) {
Interpolator* interpolator, nsecs_t startDelay, nsecs_t duration, int repeatCount,
RepeatMode repeatMode) {
PropertyAnimator* animator = new PropertyAnimator(propertyValuesHolder,
interpolator, startDelay, duration, repeatCount);
interpolator, startDelay, duration, repeatCount, repeatMode);
mAnimators.emplace_back(animator);
// Check whether any child animator is infinite after adding it them to the set.
@@ -66,14 +66,9 @@ void PropertyValuesAnimatorSet::onPlayTimeChanged(nsecs_t playTime) {
// Note that this set may containing animators modifying the same property, so when we
// reset the animators, we need to make sure the animators that end the first will
// have the final say on what the property value should be.
(*it)->setFraction(0);
(*it)->setFraction(0, 0);
}
} else if (playTime >= mDuration) {
// Skip all the animators to end
for (auto& anim : mAnimators) {
anim->setFraction(1);
}
} else {
} else {
for (auto& anim : mAnimators) {
anim->setCurrentPlayTime(playTime);
}
@@ -124,7 +119,8 @@ uint32_t PropertyValuesAnimatorSet::dirtyMask() {
}
PropertyAnimator::PropertyAnimator(PropertyValuesHolder* holder, Interpolator* interpolator,
nsecs_t startDelay, nsecs_t duration, int repeatCount)
nsecs_t startDelay, nsecs_t duration, int repeatCount,
RepeatMode repeatMode)
: mPropertyValuesHolder(holder), mInterpolator(interpolator), mStartDelay(startDelay),
mDuration(duration) {
if (repeatCount < 0) {
@@ -132,24 +128,44 @@ PropertyAnimator::PropertyAnimator(PropertyValuesHolder* holder, Interpolator* i
} else {
mRepeatCount = repeatCount;
}
mRepeatMode = repeatMode;
mTotalDuration = ((nsecs_t) mRepeatCount + 1) * mDuration + mStartDelay;
}
void PropertyAnimator::setCurrentPlayTime(nsecs_t playTime) {
if (playTime >= mStartDelay && playTime < mTotalDuration) {
nsecs_t currentIterationPlayTime = (playTime - mStartDelay) % mDuration;
float fraction = currentIterationPlayTime / (float) mDuration;
setFraction(fraction);
} else if (mLatestFraction < 1.0f && playTime >= mTotalDuration) {
// This makes sure we only set the fraction = 1 once. It is needed because there might
// be another animator modifying the same property after this animator finishes, we need
// to make sure we don't set conflicting values on the same property within one frame.
setFraction(1.0f);
if (playTime < mStartDelay) {
return;
}
float currentIterationFraction;
long iteration;
if (playTime >= mTotalDuration) {
// Reached the end of the animation.
iteration = mRepeatCount;
currentIterationFraction = 1.0f;
} else {
// play time here is in range [mStartDelay, mTotalDuration)
iteration = (playTime - mStartDelay) / mDuration;
currentIterationFraction = ((playTime - mStartDelay) % mDuration) / (float) mDuration;
}
setFraction(currentIterationFraction, iteration);
}
void PropertyAnimator::setFraction(float fraction) {
mLatestFraction = fraction;
void PropertyAnimator::setFraction(float fraction, long iteration) {
double totalFraction = fraction + iteration;
// This makes sure we only set the fraction = repeatCount + 1 once. It is needed because there
// might be another animator modifying the same property after this animator finishes, we need
// to make sure we don't set conflicting values on the same property within one frame.
if ((mLatestFraction == mRepeatCount + 1) && (totalFraction >= mRepeatCount + 1)) {
return;
}
mLatestFraction = totalFraction;
// Check the play direction (i.e. reverse or restart) every other iteration, and calculate the
// fraction based on the play direction.
if (iteration % 2 && mRepeatMode == RepeatMode::Reverse) {
fraction = 1.0f - fraction;
}
float interpolatedFraction = mInterpolator->interpolate(fraction);
mPropertyValuesHolder->setFraction(interpolatedFraction);
}

View File

@@ -26,12 +26,13 @@ namespace uirenderer {
class PropertyAnimator {
public:
PropertyAnimator(PropertyValuesHolder* holder, Interpolator* interpolator, nsecs_t startDelay,
nsecs_t duration, int repeatCount);
nsecs_t duration, int repeatCount, RepeatMode repeatMode);
void setCurrentPlayTime(nsecs_t playTime);
nsecs_t getTotalDuration() {
return mTotalDuration;
}
void setFraction(float fraction);
// fraction range: [0, 1], iteration range [0, repeatCount]
void setFraction(float fraction, long iteration);
private:
std::unique_ptr<PropertyValuesHolder> mPropertyValuesHolder;
@@ -40,7 +41,8 @@ private:
nsecs_t mDuration;
uint32_t mRepeatCount;
nsecs_t mTotalDuration;
float mLatestFraction = 0.0f;
RepeatMode mRepeatMode;
double mLatestFraction = 0;
};
// TODO: This class should really be named VectorDrawableAnimator
@@ -56,7 +58,7 @@ public:
void addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder,
Interpolator* interpolators, int64_t startDelays,
nsecs_t durations, int repeatCount);
nsecs_t durations, int repeatCount, RepeatMode repeatMode);
virtual uint32_t dirtyMask();
bool isInfinite() { return mIsInfinite; }
void setVectorDrawable(VectorDrawableRoot* vd) { mVectorDrawable = vd; }