Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26d4ab07 authored by Doris Liu's avatar Doris Liu Committed by Android (Google) Code Review
Browse files

Merge "Support repeatMode = reverse in AVD" into nyc-mr1-dev

parents f861b916 f7167e8f
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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) {
@@ -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},
+3 −2
Original line number Diff line number Diff line
@@ -1358,7 +1358,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {

            mStartDelays.add(startDelay);
            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 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);
+6 −0
Original line number Diff line number Diff line
@@ -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:
+38 −22
Original line number Diff line number Diff line
@@ -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.
@@ -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) {
@@ -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) {
@@ -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);
}
+6 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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; }