1766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu/* 2766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * Copyright (C) 2016 The Android Open Source Project 3766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * 4766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * Licensed under the Apache License, Version 2.0 (the "License"); 5766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * you may not use this file except in compliance with the License. 6766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * You may obtain a copy of the License at 7766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * 8766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * http://www.apache.org/licenses/LICENSE-2.0 9766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * 10766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * Unless required by applicable law or agreed to in writing, software 11766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * distributed under the License is distributed on an "AS IS" BASIS, 12766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * See the License for the specific language governing permissions and 14766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * limitations under the License. 15766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu */ 16766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 17766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#include "PropertyValuesAnimatorSet.h" 18766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#include "RenderNode.h" 19766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 20c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu#include <algorithm> 21c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu 22766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liunamespace android { 23766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liunamespace uirenderer { 24766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 25766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyValuesAnimatorSet::addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder, 26f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu Interpolator* interpolator, nsecs_t startDelay, nsecs_t duration, int repeatCount, 27f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu RepeatMode repeatMode) { 28766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 29766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu PropertyAnimator* animator = new PropertyAnimator(propertyValuesHolder, 30f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu interpolator, startDelay, duration, repeatCount, repeatMode); 31766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mAnimators.emplace_back(animator); 32718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu 33718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu // Check whether any child animator is infinite after adding it them to the set. 34718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu if (repeatCount == -1) { 35718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu mIsInfinite = true; 36718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu } 37766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 38766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 39766431aa57c16ece8842287a92b2e7208e3b8ac3Doris LiuPropertyValuesAnimatorSet::PropertyValuesAnimatorSet() 40766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu : BaseRenderNodeAnimator(1.0f) { 41766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu setStartValue(0); 42766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mLastFraction = 0.0f; 43766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu setInterpolator(new LinearInterpolator()); 44c470466d7c89b55d8c5a13d79076fa2f8d624da1Doris Liu setListener(new PropertyAnimatorSetListener(this)); 45766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 46766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 47766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyValuesAnimatorSet::onFinished(BaseRenderNodeAnimator* animator) { 48766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu if (mOneShotListener.get()) { 49679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu sp<AnimationListener> listener = std::move(mOneShotListener); 50679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu // Set the listener to nullptr before the onAnimationFinished callback, rather than after, 51679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu // for two reasons: 52679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu // 1) We need to prevent changes to mOneShotListener during the onAnimationFinished 53679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu // callback (specifically in AnimationListenerBridge::onAnimationFinished(...) from 54679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu // triggering dtor of the bridge and potentially unsafely re-entering 55679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu // AnimationListenerBridge::onAnimationFinished(...). 56679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu // 2) It's possible that there are changes to the listener during the callback, therefore 57679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu // we need to reset the listener before the callback rather than afterwards. 58766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mOneShotListener = nullptr; 59679fe6ab6f4b9252ef414a0c0c5ad9633f3d0294Doris Liu listener->onAnimationFinished(animator); 60766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu } 61766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 62766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 63766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liufloat PropertyValuesAnimatorSet::getValue(RenderNode* target) const { 64766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu return mLastFraction; 65766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 66766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 67766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyValuesAnimatorSet::setValue(RenderNode* target, float value) { 68766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mLastFraction = value; 69766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 70766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 71766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyValuesAnimatorSet::onPlayTimeChanged(nsecs_t playTime) { 72c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu if (playTime == 0 && mDuration > 0) { 73c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu // Reset all the animators 74c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu for (auto it = mAnimators.rbegin(); it != mAnimators.rend(); it++) { 75c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu // Note that this set may containing animators modifying the same property, so when we 76c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu // reset the animators, we need to make sure the animators that end the first will 77c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu // have the final say on what the property value should be. 78f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu (*it)->setFraction(0, 0); 79c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu } 80f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu } else { 81c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu for (auto& anim : mAnimators) { 82c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu anim->setCurrentPlayTime(playTime); 83c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu } 84766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu } 85766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 86766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 87766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyValuesAnimatorSet::start(AnimationListener* listener) { 88766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu init(); 89766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mOneShotListener = listener; 90718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu mRequestId++; 91766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu BaseRenderNodeAnimator::start(); 92766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 93766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 94766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyValuesAnimatorSet::reverse(AnimationListener* listener) { 95c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu init(); 96c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu mOneShotListener = listener; 97718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu mRequestId++; 98c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu BaseRenderNodeAnimator::reverse(); 99766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 100766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 101718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liuvoid PropertyValuesAnimatorSet::reset() { 102718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu mRequestId++; 103718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu BaseRenderNodeAnimator::reset(); 104718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu} 105718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu 106718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liuvoid PropertyValuesAnimatorSet::end() { 107718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu mRequestId++; 108718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu BaseRenderNodeAnimator::end(); 109718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu} 110718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu 111766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyValuesAnimatorSet::init() { 112766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu if (mInitialized) { 113766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu return; 114766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu } 115c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu 116c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu // Sort the animators by their total duration. Note that all the animators in the set start at 117c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu // the same time, so the ones with longer total duration (which includes start delay) will 118c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu // be the ones that end later. 119c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu std::sort(mAnimators.begin(), mAnimators.end(), [](auto& a, auto&b) { 120c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu return a->getTotalDuration() < b->getTotalDuration(); 121c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu }); 122c470466d7c89b55d8c5a13d79076fa2f8d624da1Doris Liu mDuration = mAnimators.empty() ? 0 : mAnimators[mAnimators.size() - 1]->getTotalDuration(); 123766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mInitialized = true; 124766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 125766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 126766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuuint32_t PropertyValuesAnimatorSet::dirtyMask() { 127766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu return RenderNode::DISPLAY_LIST; 128766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 129766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 130766431aa57c16ece8842287a92b2e7208e3b8ac3Doris LiuPropertyAnimator::PropertyAnimator(PropertyValuesHolder* holder, Interpolator* interpolator, 131f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu nsecs_t startDelay, nsecs_t duration, int repeatCount, 132f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu RepeatMode repeatMode) 133766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu : mPropertyValuesHolder(holder), mInterpolator(interpolator), mStartDelay(startDelay), 134766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mDuration(duration) { 135766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu if (repeatCount < 0) { 136766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mRepeatCount = UINT32_MAX; 137766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu } else { 138766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mRepeatCount = repeatCount; 139766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu } 140f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu mRepeatMode = repeatMode; 141766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mTotalDuration = ((nsecs_t) mRepeatCount + 1) * mDuration + mStartDelay; 142766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 143766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 144766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyAnimator::setCurrentPlayTime(nsecs_t playTime) { 145f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu if (playTime < mStartDelay) { 146f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu return; 147766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu } 148f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu 149f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu float currentIterationFraction; 150f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu long iteration; 151f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu if (playTime >= mTotalDuration) { 152f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu // Reached the end of the animation. 153f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu iteration = mRepeatCount; 154f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu currentIterationFraction = 1.0f; 155f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu } else { 156f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu // play time here is in range [mStartDelay, mTotalDuration) 157f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu iteration = (playTime - mStartDelay) / mDuration; 158f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu currentIterationFraction = ((playTime - mStartDelay) % mDuration) / (float) mDuration; 159f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu } 160f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu setFraction(currentIterationFraction, iteration); 161766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 162766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 163f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liuvoid PropertyAnimator::setFraction(float fraction, long iteration) { 164f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu double totalFraction = fraction + iteration; 165f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu // This makes sure we only set the fraction = repeatCount + 1 once. It is needed because there 166f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu // might be another animator modifying the same property after this animator finishes, we need 167f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu // to make sure we don't set conflicting values on the same property within one frame. 16818e08a0170a429929e4b974143ecd0d6603b332cDoris Liu if ((mLatestFraction == mRepeatCount + 1.0) && (totalFraction >= mRepeatCount + 1.0)) { 169f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu return; 170f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu } 171f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu 172f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu mLatestFraction = totalFraction; 173f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu // Check the play direction (i.e. reverse or restart) every other iteration, and calculate the 174f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu // fraction based on the play direction. 175f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu if (iteration % 2 && mRepeatMode == RepeatMode::Reverse) { 176f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu fraction = 1.0f - fraction; 177f7167e8f286cff91dec01fdf617bf568f1d100e6Doris Liu } 178c4bb185d41cfb960ed9a3178a4f8974c351abdb0Doris Liu float interpolatedFraction = mInterpolator->interpolate(fraction); 179766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mPropertyValuesHolder->setFraction(interpolatedFraction); 180766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 181766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 182766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid PropertyAnimatorSetListener::onAnimationFinished(BaseRenderNodeAnimator* animator) { 183766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mSet->onFinished(animator); 184766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 185766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 186766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 187766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 188