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