• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AnimationContext(renderthread::TimeLord & clock)25 AnimationContext::AnimationContext(renderthread::TimeLord& clock)
26         : mClock(clock)
27         , mCurrentFrameAnimations(*this)
28         , mNextFrameAnimations(*this)
29         , mFrameTimeMs(0) {
30 }
31 
~AnimationContext()32 AnimationContext::~AnimationContext() {
33 }
34 
destroy()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 
addAnimatingRenderNode(RenderNode & node)46 void AnimationContext::addAnimatingRenderNode(RenderNode& node) {
47     if (!node.animators().hasAnimationHandle()) {
48         AnimationHandle* handle = new AnimationHandle(node, *this);
49         addAnimationHandle(handle);
50     }
51 }
52 
addAnimationHandle(AnimationHandle * handle)53 void AnimationContext::addAnimationHandle(AnimationHandle* handle) {
54     handle->insertAfter(&mNextFrameAnimations);
55 }
56 
startFrame(TreeInfo::TraversalMode mode)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 = NULL;
63         mCurrentFrameAnimations.mNextHandle = head;
64         head->mPreviousHandle = &mCurrentFrameAnimations;
65     }
66     mFrameTimeMs = mClock.computeFrameTimeMs();
67 }
68 
runRemainingAnimations(TreeInfo & info)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 
callOnFinished(BaseRenderNodeAnimator * animator,AnimationListener * listener)80 void AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator,
81         AnimationListener* listener) {
82     listener->onAnimationFinished(animator);
83 }
84 
AnimationHandle(AnimationContext & context)85 AnimationHandle::AnimationHandle(AnimationContext& context)
86         : mContext(context)
87         , mPreviousHandle(NULL)
88         , mNextHandle(NULL) {
89 }
90 
AnimationHandle(RenderNode & animatingNode,AnimationContext & context)91 AnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context)
92         : mRenderNode(&animatingNode)
93         , mContext(context)
94         , mPreviousHandle(NULL)
95         , mNextHandle(NULL) {
96     mRenderNode->animators().setAnimationHandle(this);
97 }
98 
~AnimationHandle()99 AnimationHandle::~AnimationHandle() {
100     LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle,
101             "AnimationHandle destroyed while still animating!");
102 }
103 
notifyAnimationsRan()104 void AnimationHandle::notifyAnimationsRan() {
105     removeFromList();
106     if (mRenderNode->animators().hasAnimators()) {
107         mContext.addAnimationHandle(this);
108     } else {
109         release();
110     }
111 }
112 
release()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(NULL);
118     delete this;
119 }
120 
insertAfter(AnimationHandle * prev)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 
removeFromList()131 void AnimationHandle::removeFromList() {
132     if (mPreviousHandle) {
133         mPreviousHandle->mNextHandle = mNextHandle;
134     }
135     if (mNextHandle) {
136         mNextHandle->mPreviousHandle = mPreviousHandle;
137     }
138     mPreviousHandle = NULL;
139     mNextHandle = NULL;
140 }
141 
142 } /* namespace uirenderer */
143 } /* namespace android */
144