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