Merge "Support repeatMode = reverse in AVD" into nyc-mr1-dev
This commit is contained in:
@@ -83,11 +83,13 @@ static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr,
|
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);
|
PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
|
||||||
PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr);
|
PropertyValuesHolder* holder = reinterpret_cast<PropertyValuesHolder*>(propertyHolderPtr);
|
||||||
Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
|
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) {
|
static jlong createAnimatorSet(JNIEnv*, jobject) {
|
||||||
@@ -185,7 +187,7 @@ static void reset(JNIEnv*, jobject, jlong animatorSetPtr) {
|
|||||||
static const JNINativeMethod gMethods[] = {
|
static const JNINativeMethod gMethods[] = {
|
||||||
{"nCreateAnimatorSet", "()J", (void*)createAnimatorSet},
|
{"nCreateAnimatorSet", "()J", (void*)createAnimatorSet},
|
||||||
{"nSetVectorDrawableTarget", "(JJ)V", (void*)setVectorDrawableTarget},
|
{"nSetVectorDrawableTarget", "(JJ)V", (void*)setVectorDrawableTarget},
|
||||||
{"nAddAnimator", "(JJJJJI)V", (void*)addAnimator},
|
{"nAddAnimator", "(JJJJJII)V", (void*)addAnimator},
|
||||||
{"nCreateGroupPropertyHolder", "!(JIFF)J", (void*)createGroupPropertyHolder},
|
{"nCreateGroupPropertyHolder", "!(JIFF)J", (void*)createGroupPropertyHolder},
|
||||||
{"nCreatePathDataPropertyHolder", "!(JJJ)J", (void*)createPathDataPropertyHolder},
|
{"nCreatePathDataPropertyHolder", "!(JJJ)J", (void*)createPathDataPropertyHolder},
|
||||||
{"nCreatePathColorPropertyHolder", "!(JIII)J", (void*)createPathColorPropertyHolder},
|
{"nCreatePathColorPropertyHolder", "!(JIII)J", (void*)createPathColorPropertyHolder},
|
||||||
|
|||||||
@@ -1358,7 +1358,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
|
|||||||
|
|
||||||
mStartDelays.add(startDelay);
|
mStartDelays.add(startDelay);
|
||||||
nAddAnimator(mSetPtr, propertyPtr, nativeInterpolator, startDelay, duration,
|
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 long nCreateAnimatorSet();
|
||||||
private static native void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr);
|
private static native void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr);
|
||||||
private static native void nAddAnimator(long setPtr, long propertyValuesHolder,
|
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,
|
private static native long nCreateGroupPropertyHolder(long nativePtr, int propertyId,
|
||||||
float startValue, float endValue);
|
float startValue, float endValue);
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ protected:
|
|||||||
ANDROID_API virtual ~AnimationListener() {}
|
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 {
|
class BaseRenderNodeAnimator : public VirtualLightRefBase {
|
||||||
PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator);
|
PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator);
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ namespace android {
|
|||||||
namespace uirenderer {
|
namespace uirenderer {
|
||||||
|
|
||||||
void PropertyValuesAnimatorSet::addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder,
|
void PropertyValuesAnimatorSet::addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder,
|
||||||
Interpolator* interpolator, nsecs_t startDelay,
|
Interpolator* interpolator, nsecs_t startDelay, nsecs_t duration, int repeatCount,
|
||||||
nsecs_t duration, int repeatCount) {
|
RepeatMode repeatMode) {
|
||||||
|
|
||||||
PropertyAnimator* animator = new PropertyAnimator(propertyValuesHolder,
|
PropertyAnimator* animator = new PropertyAnimator(propertyValuesHolder,
|
||||||
interpolator, startDelay, duration, repeatCount);
|
interpolator, startDelay, duration, repeatCount, repeatMode);
|
||||||
mAnimators.emplace_back(animator);
|
mAnimators.emplace_back(animator);
|
||||||
|
|
||||||
// Check whether any child animator is infinite after adding it them to the set.
|
// Check whether any child animator is infinite after adding it them to the set.
|
||||||
@@ -66,12 +66,7 @@ void PropertyValuesAnimatorSet::onPlayTimeChanged(nsecs_t playTime) {
|
|||||||
// Note that this set may containing animators modifying the same property, so when we
|
// 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
|
// 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.
|
// 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) {
|
for (auto& anim : mAnimators) {
|
||||||
@@ -124,7 +119,8 @@ uint32_t PropertyValuesAnimatorSet::dirtyMask() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PropertyAnimator::PropertyAnimator(PropertyValuesHolder* holder, Interpolator* interpolator,
|
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),
|
: mPropertyValuesHolder(holder), mInterpolator(interpolator), mStartDelay(startDelay),
|
||||||
mDuration(duration) {
|
mDuration(duration) {
|
||||||
if (repeatCount < 0) {
|
if (repeatCount < 0) {
|
||||||
@@ -132,24 +128,44 @@ PropertyAnimator::PropertyAnimator(PropertyValuesHolder* holder, Interpolator* i
|
|||||||
} else {
|
} else {
|
||||||
mRepeatCount = repeatCount;
|
mRepeatCount = repeatCount;
|
||||||
}
|
}
|
||||||
|
mRepeatMode = repeatMode;
|
||||||
mTotalDuration = ((nsecs_t) mRepeatCount + 1) * mDuration + mStartDelay;
|
mTotalDuration = ((nsecs_t) mRepeatCount + 1) * mDuration + mStartDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyAnimator::setCurrentPlayTime(nsecs_t playTime) {
|
void PropertyAnimator::setCurrentPlayTime(nsecs_t playTime) {
|
||||||
if (playTime >= mStartDelay && playTime < mTotalDuration) {
|
if (playTime < mStartDelay) {
|
||||||
nsecs_t currentIterationPlayTime = (playTime - mStartDelay) % mDuration;
|
return;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyAnimator::setFraction(float fraction) {
|
float currentIterationFraction;
|
||||||
mLatestFraction = fraction;
|
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, 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);
|
float interpolatedFraction = mInterpolator->interpolate(fraction);
|
||||||
mPropertyValuesHolder->setFraction(interpolatedFraction);
|
mPropertyValuesHolder->setFraction(interpolatedFraction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,13 @@ namespace uirenderer {
|
|||||||
class PropertyAnimator {
|
class PropertyAnimator {
|
||||||
public:
|
public:
|
||||||
PropertyAnimator(PropertyValuesHolder* holder, Interpolator* interpolator, nsecs_t startDelay,
|
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);
|
void setCurrentPlayTime(nsecs_t playTime);
|
||||||
nsecs_t getTotalDuration() {
|
nsecs_t getTotalDuration() {
|
||||||
return mTotalDuration;
|
return mTotalDuration;
|
||||||
}
|
}
|
||||||
void setFraction(float fraction);
|
// fraction range: [0, 1], iteration range [0, repeatCount]
|
||||||
|
void setFraction(float fraction, long iteration);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<PropertyValuesHolder> mPropertyValuesHolder;
|
std::unique_ptr<PropertyValuesHolder> mPropertyValuesHolder;
|
||||||
@@ -40,7 +41,8 @@ private:
|
|||||||
nsecs_t mDuration;
|
nsecs_t mDuration;
|
||||||
uint32_t mRepeatCount;
|
uint32_t mRepeatCount;
|
||||||
nsecs_t mTotalDuration;
|
nsecs_t mTotalDuration;
|
||||||
float mLatestFraction = 0.0f;
|
RepeatMode mRepeatMode;
|
||||||
|
double mLatestFraction = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: This class should really be named VectorDrawableAnimator
|
// TODO: This class should really be named VectorDrawableAnimator
|
||||||
@@ -56,7 +58,7 @@ public:
|
|||||||
|
|
||||||
void addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder,
|
void addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder,
|
||||||
Interpolator* interpolators, int64_t startDelays,
|
Interpolator* interpolators, int64_t startDelays,
|
||||||
nsecs_t durations, int repeatCount);
|
nsecs_t durations, int repeatCount, RepeatMode repeatMode);
|
||||||
virtual uint32_t dirtyMask();
|
virtual uint32_t dirtyMask();
|
||||||
bool isInfinite() { return mIsInfinite; }
|
bool isInfinite() { return mIsInfinite; }
|
||||||
void setVectorDrawable(VectorDrawableRoot* vd) { mVectorDrawable = vd; }
|
void setVectorDrawable(VectorDrawableRoot* vd) { mVectorDrawable = vd; }
|
||||||
|
|||||||
Reference in New Issue
Block a user