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