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