VectorDrawable native rendering - Step 5 of MANY
This is reverting the revert of what reverts the revert of the original
implementation. Fourth revert is a charm!
This reverts commit df7fdb1e0bdb5c289bbc08047e5c710185503309.
Change-Id: I6fc3a5accfd8b79c3da31bbc101ad9e9b4d6e7dd
diff --git a/libs/hwui/PropertyValuesAnimatorSet.cpp b/libs/hwui/PropertyValuesAnimatorSet.cpp
index eca1afcc..b29f91f 100644
--- a/libs/hwui/PropertyValuesAnimatorSet.cpp
+++ b/libs/hwui/PropertyValuesAnimatorSet.cpp
@@ -17,6 +17,8 @@
#include "PropertyValuesAnimatorSet.h"
#include "RenderNode.h"
+#include <algorithm>
+
namespace android {
namespace uirenderer {
@@ -53,16 +55,26 @@
}
void PropertyValuesAnimatorSet::onPlayTimeChanged(nsecs_t playTime) {
- for (size_t i = 0; i < mAnimators.size(); i++) {
- mAnimators[i]->setCurrentPlayTime(playTime);
+ if (playTime == 0 && mDuration > 0) {
+ // Reset all the animators
+ for (auto it = mAnimators.rbegin(); it != mAnimators.rend(); it++) {
+ // 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);
+ }
+ } else {
+ for (auto& anim : mAnimators) {
+ anim->setCurrentPlayTime(playTime);
+ }
}
}
-void PropertyValuesAnimatorSet::reset() {
- // TODO: implement reset through adding a play state because we need to support reset() even
- // during an animation run.
-}
-
void PropertyValuesAnimatorSet::start(AnimationListener* listener) {
init();
mOneShotListener = listener;
@@ -70,20 +82,23 @@
}
void PropertyValuesAnimatorSet::reverse(AnimationListener* listener) {
-// TODO: implement reverse
+ init();
+ mOneShotListener = listener;
+ BaseRenderNodeAnimator::reverse();
}
void PropertyValuesAnimatorSet::init() {
if (mInitialized) {
return;
}
- nsecs_t maxDuration = 0;
- for (size_t i = 0; i < mAnimators.size(); i++) {
- if (maxDuration < mAnimators[i]->getTotalDuration()) {
- maxDuration = mAnimators[i]->getTotalDuration();
- }
- }
- mDuration = maxDuration;
+
+ // Sort the animators by their total duration. Note that all the animators in the set start at
+ // the same time, so the ones with longer total duration (which includes start delay) will
+ // be the ones that end later.
+ std::sort(mAnimators.begin(), mAnimators.end(), [](auto& a, auto&b) {
+ return a->getTotalDuration() < b->getTotalDuration();
+ });
+ mDuration = mAnimators[mAnimators.size() - 1]->getTotalDuration();
mInitialized = true;
}
@@ -106,18 +121,19 @@
void PropertyAnimator::setCurrentPlayTime(nsecs_t playTime) {
if (playTime >= mStartDelay && playTime < mTotalDuration) {
nsecs_t currentIterationPlayTime = (playTime - mStartDelay) % mDuration;
- mLatestFraction = currentIterationPlayTime / (float) mDuration;
+ float fraction = currentIterationPlayTime / (float) mDuration;
+ setFraction(fraction);
} else if (mLatestFraction < 1.0f && playTime >= mTotalDuration) {
- mLatestFraction = 1.0f;
- } else {
- return;
+ // 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);
}
-
- setFraction(mLatestFraction);
}
void PropertyAnimator::setFraction(float fraction) {
- float interpolatedFraction = mInterpolator->interpolate(mLatestFraction);
+ mLatestFraction = fraction;
+ float interpolatedFraction = mInterpolator->interpolate(fraction);
mPropertyValuesHolder->setFraction(interpolatedFraction);
}