summaryrefslogtreecommitdiff
path: root/libs/hwui/PropertyValuesAnimatorSet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/PropertyValuesAnimatorSet.cpp')
-rw-r--r--libs/hwui/PropertyValuesAnimatorSet.cpp81
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);
}