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