Loading core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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}, Loading graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +3 −2 Original line number Diff line number Diff line Loading @@ -1358,7 +1358,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { mStartDelays.add(startDelay); nAddAnimator(mSetPtr, propertyPtr, nativeInterpolator, startDelay, duration, repeatCount); repeatCount, animator.getRepeatMode()); } /** Loading Loading @@ -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); Loading libs/hwui/Animator.h +6 −0 Original line number Diff line number Diff line Loading @@ -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: Loading libs/hwui/PropertyValuesAnimatorSet.cpp +38 −22 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -66,12 +66,7 @@ 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); } } else if (playTime >= mDuration) { // Skip all the animators to end for (auto& anim : mAnimators) { anim->setFraction(1); (*it)->setFraction(0, 0); } } else { for (auto& anim : mAnimators) { Loading Loading @@ -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) { Loading @@ -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, 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; } void PropertyAnimator::setFraction(float fraction) { mLatestFraction = fraction; 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); } Loading libs/hwui/PropertyValuesAnimatorSet.h +6 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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; } Loading Loading
core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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}, Loading
graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +3 −2 Original line number Diff line number Diff line Loading @@ -1358,7 +1358,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { mStartDelays.add(startDelay); nAddAnimator(mSetPtr, propertyPtr, nativeInterpolator, startDelay, duration, repeatCount); repeatCount, animator.getRepeatMode()); } /** Loading Loading @@ -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); Loading
libs/hwui/Animator.h +6 −0 Original line number Diff line number Diff line Loading @@ -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: Loading
libs/hwui/PropertyValuesAnimatorSet.cpp +38 −22 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -66,12 +66,7 @@ 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); } } else if (playTime >= mDuration) { // Skip all the animators to end for (auto& anim : mAnimators) { anim->setFraction(1); (*it)->setFraction(0, 0); } } else { for (auto& anim : mAnimators) { Loading Loading @@ -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) { Loading @@ -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, 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; } void PropertyAnimator::setFraction(float fraction) { mLatestFraction = fraction; 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); } Loading
libs/hwui/PropertyValuesAnimatorSet.h +6 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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; } Loading