1 /* 2 * Copyright (C) 2014 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 #include "AnimationContext.h" 17 18 #include "Animator.h" 19 #include "RenderNode.h" 20 #include "renderthread/TimeLord.h" 21 22 namespace android { 23 namespace uirenderer { 24 25 AnimationContext::AnimationContext(renderthread::TimeLord& clock) 26 : mClock(clock) 27 , mCurrentFrameAnimations(*this) 28 , mNextFrameAnimations(*this) 29 , mFrameTimeMs(0) {} 30 31 AnimationContext::~AnimationContext() {} 32 33 void AnimationContext::destroy() { 34 startFrame(TreeInfo::MODE_RT_ONLY); 35 while (mCurrentFrameAnimations.mNextHandle) { 36 AnimationHandle* current = mCurrentFrameAnimations.mNextHandle; 37 AnimatorManager& animators = current->mRenderNode->animators(); 38 animators.endAllActiveAnimators(); 39 LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current, 40 "endAllAnimators failed to remove from current frame list!"); 41 } 42 } 43 44 void AnimationContext::addAnimatingRenderNode(RenderNode& node) { 45 if (!node.animators().hasAnimationHandle()) { 46 AnimationHandle* handle = new AnimationHandle(node, *this); 47 addAnimationHandle(handle); 48 } 49 } 50 51 void AnimationContext::addAnimationHandle(AnimationHandle* handle) { 52 handle->insertAfter(&mNextFrameAnimations); 53 } 54 55 void AnimationContext::startFrame(TreeInfo::TraversalMode mode) { 56 LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle, 57 "Missed running animations last frame!"); 58 AnimationHandle* head = mNextFrameAnimations.mNextHandle; 59 if (head) { 60 mNextFrameAnimations.mNextHandle = nullptr; 61 mCurrentFrameAnimations.mNextHandle = head; 62 head->mPreviousHandle = &mCurrentFrameAnimations; 63 } 64 mFrameTimeMs = ns2ms(mClock.latestVsync()); 65 } 66 67 void AnimationContext::runRemainingAnimations(TreeInfo& info) { 68 while (mCurrentFrameAnimations.mNextHandle) { 69 AnimationHandle* current = mCurrentFrameAnimations.mNextHandle; 70 AnimatorManager& animators = current->mRenderNode->animators(); 71 animators.pushStaging(); 72 animators.animateNoDamage(info); 73 LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current, 74 "Animate failed to remove from current frame list!"); 75 } 76 } 77 78 void AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator, 79 AnimationListener* listener) { 80 listener->onAnimationFinished(animator); 81 } 82 83 AnimationHandle::AnimationHandle(AnimationContext& context) 84 : mContext(context), mPreviousHandle(nullptr), mNextHandle(nullptr) {} 85 86 AnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context) 87 : mRenderNode(&animatingNode) 88 , mContext(context) 89 , mPreviousHandle(nullptr) 90 , mNextHandle(nullptr) { 91 mRenderNode->animators().setAnimationHandle(this); 92 } 93 94 AnimationHandle::~AnimationHandle() { 95 LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle, 96 "AnimationHandle destroyed while still animating!"); 97 } 98 99 void AnimationHandle::notifyAnimationsRan() { 100 removeFromList(); 101 if (mRenderNode->animators().hasAnimators()) { 102 mContext.addAnimationHandle(this); 103 } else { 104 release(); 105 } 106 } 107 108 void AnimationHandle::release() { 109 LOG_ALWAYS_FATAL_IF(mRenderNode->animators().hasAnimators(), 110 "Releasing the handle for an RenderNode with outstanding animators!"); 111 removeFromList(); 112 mRenderNode->animators().setAnimationHandle(nullptr); 113 delete this; 114 } 115 116 void AnimationHandle::insertAfter(AnimationHandle* prev) { 117 removeFromList(); 118 mNextHandle = prev->mNextHandle; 119 if (mNextHandle) { 120 mNextHandle->mPreviousHandle = this; 121 } 122 prev->mNextHandle = this; 123 mPreviousHandle = prev; 124 } 125 126 void AnimationHandle::removeFromList() { 127 if (mPreviousHandle) { 128 mPreviousHandle->mNextHandle = mNextHandle; 129 } 130 if (mNextHandle) { 131 mNextHandle->mPreviousHandle = mPreviousHandle; 132 } 133 mPreviousHandle = nullptr; 134 mNextHandle = nullptr; 135 } 136 137 } /* namespace uirenderer */ 138 } /* namespace android */ 139