diff options
Diffstat (limited to 'libs/hwui/PropertyValuesAnimatorSet.cpp')
| -rw-r--r-- | libs/hwui/PropertyValuesAnimatorSet.cpp | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/libs/hwui/PropertyValuesAnimatorSet.cpp b/libs/hwui/PropertyValuesAnimatorSet.cpp index b29f91ff34aa..38fb70a92e43 100644 --- a/libs/hwui/PropertyValuesAnimatorSet.cpp +++ b/libs/hwui/PropertyValuesAnimatorSet.cpp @@ -23,13 +23,17 @@ 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); - setListener(new PropertyAnimatorSetListener(this)); + + // Check whether any child animator is infinite after adding it them to the set. + if (repeatCount == -1) { + mIsInfinite = true; + } } PropertyValuesAnimatorSet::PropertyValuesAnimatorSet() @@ -37,6 +41,7 @@ PropertyValuesAnimatorSet::PropertyValuesAnimatorSet() setStartValue(0); mLastFraction = 0.0f; setInterpolator(new LinearInterpolator()); + setListener(new PropertyAnimatorSetListener(this)); } void PropertyValuesAnimatorSet::onFinished(BaseRenderNodeAnimator* animator) { @@ -61,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); - } - } else if (playTime >= mDuration) { - // Skip all the animators to end - for (auto& anim : mAnimators) { - anim->setFraction(1); + (*it)->setFraction(0, 0); } - } else { + } else { for (auto& anim : mAnimators) { anim->setCurrentPlayTime(playTime); } @@ -78,15 +78,27 @@ void PropertyValuesAnimatorSet::onPlayTimeChanged(nsecs_t playTime) { void PropertyValuesAnimatorSet::start(AnimationListener* listener) { init(); mOneShotListener = listener; + mRequestId++; BaseRenderNodeAnimator::start(); } void PropertyValuesAnimatorSet::reverse(AnimationListener* listener) { init(); mOneShotListener = listener; + mRequestId++; BaseRenderNodeAnimator::reverse(); } +void PropertyValuesAnimatorSet::reset() { + mRequestId++; + BaseRenderNodeAnimator::reset(); +} + +void PropertyValuesAnimatorSet::end() { + mRequestId++; + BaseRenderNodeAnimator::end(); +} + void PropertyValuesAnimatorSet::init() { if (mInitialized) { return; @@ -98,7 +110,7 @@ void PropertyValuesAnimatorSet::init() { std::sort(mAnimators.begin(), mAnimators.end(), [](auto& a, auto&b) { return a->getTotalDuration() < b->getTotalDuration(); }); - mDuration = mAnimators[mAnimators.size() - 1]->getTotalDuration(); + mDuration = mAnimators.empty() ? 0 : mAnimators[mAnimators.size() - 1]->getTotalDuration(); mInitialized = true; } @@ -107,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) { @@ -115,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.0) && (totalFraction >= mRepeatCount + 1.0)) { + 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); } |
