PropertyValuesAnimatorSet.cpp revision 67ce99b66ebc816ae8bbc222db8f3695fb15495b
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "PropertyValuesAnimatorSet.h" 18#include "RenderNode.h" 19 20#include <algorithm> 21 22namespace android { 23namespace uirenderer { 24 25void PropertyValuesAnimatorSet::addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder, 26 Interpolator* interpolator, nsecs_t startDelay, 27 nsecs_t duration, int repeatCount) { 28 29 PropertyAnimator* animator = new PropertyAnimator(propertyValuesHolder, 30 interpolator, startDelay, duration, repeatCount); 31 mAnimators.emplace_back(animator); 32 setListener(new PropertyAnimatorSetListener(this)); 33 34 // Check whether any child animator is infinite after adding it them to the set. 35 if (repeatCount == -1) { 36 mIsInfinite = true; 37 } 38} 39 40PropertyValuesAnimatorSet::PropertyValuesAnimatorSet() 41 : BaseRenderNodeAnimator(1.0f) { 42 setStartValue(0); 43 mLastFraction = 0.0f; 44 setInterpolator(new LinearInterpolator()); 45} 46 47void PropertyValuesAnimatorSet::onFinished(BaseRenderNodeAnimator* animator) { 48 if (mOneShotListener.get()) { 49 mOneShotListener->onAnimationFinished(animator); 50 mOneShotListener = nullptr; 51 } 52} 53 54float PropertyValuesAnimatorSet::getValue(RenderNode* target) const { 55 return mLastFraction; 56} 57 58void PropertyValuesAnimatorSet::setValue(RenderNode* target, float value) { 59 mLastFraction = value; 60} 61 62void PropertyValuesAnimatorSet::onPlayTimeChanged(nsecs_t playTime) { 63 if (playTime == 0 && mDuration > 0) { 64 // Reset all the animators 65 for (auto it = mAnimators.rbegin(); it != mAnimators.rend(); it++) { 66 // Note that this set may containing animators modifying the same property, so when we 67 // reset the animators, we need to make sure the animators that end the first will 68 // have the final say on what the property value should be. 69 (*it)->setFraction(0); 70 } 71 } else if (playTime >= mDuration) { 72 // Skip all the animators to end 73 for (auto& anim : mAnimators) { 74 anim->setFraction(1); 75 } 76 } else { 77 for (auto& anim : mAnimators) { 78 anim->setCurrentPlayTime(playTime); 79 } 80 } 81} 82 83void PropertyValuesAnimatorSet::start(AnimationListener* listener) { 84 init(); 85 mOneShotListener = listener; 86 mRequestId++; 87 BaseRenderNodeAnimator::start(); 88} 89 90void PropertyValuesAnimatorSet::reverse(AnimationListener* listener) { 91 init(); 92 mOneShotListener = listener; 93 mRequestId++; 94 BaseRenderNodeAnimator::reverse(); 95} 96 97void PropertyValuesAnimatorSet::reset() { 98 mRequestId++; 99 BaseRenderNodeAnimator::reset(); 100} 101 102void PropertyValuesAnimatorSet::end() { 103 mRequestId++; 104 BaseRenderNodeAnimator::end(); 105} 106 107void PropertyValuesAnimatorSet::init() { 108 if (mInitialized) { 109 return; 110 } 111 112 // Sort the animators by their total duration. Note that all the animators in the set start at 113 // the same time, so the ones with longer total duration (which includes start delay) will 114 // be the ones that end later. 115 std::sort(mAnimators.begin(), mAnimators.end(), [](auto& a, auto&b) { 116 return a->getTotalDuration() < b->getTotalDuration(); 117 }); 118 mDuration = mAnimators[mAnimators.size() - 1]->getTotalDuration(); 119 mInitialized = true; 120} 121 122uint32_t PropertyValuesAnimatorSet::dirtyMask() { 123 return RenderNode::DISPLAY_LIST; 124} 125 126PropertyAnimator::PropertyAnimator(PropertyValuesHolder* holder, Interpolator* interpolator, 127 nsecs_t startDelay, nsecs_t duration, int repeatCount) 128 : mPropertyValuesHolder(holder), mInterpolator(interpolator), mStartDelay(startDelay), 129 mDuration(duration) { 130 if (repeatCount < 0) { 131 mRepeatCount = UINT32_MAX; 132 } else { 133 mRepeatCount = repeatCount; 134 } 135 mTotalDuration = ((nsecs_t) mRepeatCount + 1) * mDuration + mStartDelay; 136} 137 138void PropertyAnimator::setCurrentPlayTime(nsecs_t playTime) { 139 if (playTime >= mStartDelay && playTime < mTotalDuration) { 140 nsecs_t currentIterationPlayTime = (playTime - mStartDelay) % mDuration; 141 float fraction = currentIterationPlayTime / (float) mDuration; 142 setFraction(fraction); 143 } else if (mLatestFraction < 1.0f && playTime >= mTotalDuration) { 144 // This makes sure we only set the fraction = 1 once. It is needed because there might 145 // be another animator modifying the same property after this animator finishes, we need 146 // to make sure we don't set conflicting values on the same property within one frame. 147 setFraction(1.0f); 148 } 149} 150 151void PropertyAnimator::setFraction(float fraction) { 152 mLatestFraction = fraction; 153 float interpolatedFraction = mInterpolator->interpolate(fraction); 154 mPropertyValuesHolder->setFraction(interpolatedFraction); 155} 156 157void PropertyAnimatorSetListener::onAnimationFinished(BaseRenderNodeAnimator* animator) { 158 mSet->onFinished(animator); 159} 160 161} 162} 163