1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "AnimationContext.h"
#include "Animator.h"
#include "RenderNode.h"
#include "TreeInfo.h"
#include "renderthread/TimeLord.h"
namespace android {
namespace uirenderer {
AnimationContext::AnimationContext(renderthread::TimeLord& clock)
: mClock(clock)
, mCurrentFrameAnimations(*this)
, mNextFrameAnimations(*this)
, mFrameTimeMs(0) {
}
AnimationContext::~AnimationContext() {
}
void AnimationContext::addAnimatingRenderNode(RenderNode& node) {
if (!node.animators().hasAnimationHandle()) {
AnimationHandle* handle = new AnimationHandle(node, *this);
addAnimationHandle(handle);
}
}
void AnimationContext::addAnimationHandle(AnimationHandle* handle) {
handle->insertAfter(&mNextFrameAnimations);
}
void AnimationContext::startFrame() {
LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle,
"Missed running animations last frame!");
AnimationHandle* head = mNextFrameAnimations.mNextHandle;
if (head) {
mNextFrameAnimations.mNextHandle = NULL;
mCurrentFrameAnimations.mNextHandle = head;
head->mPreviousHandle = &mCurrentFrameAnimations;
}
mFrameTimeMs = mClock.computeFrameTimeMs();
}
void AnimationContext::runRemainingAnimations(TreeInfo& info) {
while (mCurrentFrameAnimations.mNextHandle) {
AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
AnimatorManager& animators = current->mRenderNode->animators();
animators.pushStaging();
animators.animateNoDamage(info);
LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
"Animate failed to remove from current frame list!");
}
}
void AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator,
AnimationListener* listener) {
listener->onAnimationFinished(animator);
}
AnimationHandle::AnimationHandle(AnimationContext& context)
: mContext(context)
, mPreviousHandle(NULL)
, mNextHandle(NULL) {
}
AnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context)
: mRenderNode(&animatingNode)
, mContext(context)
, mPreviousHandle(NULL)
, mNextHandle(NULL) {
mRenderNode->animators().setAnimationHandle(this);
}
AnimationHandle::~AnimationHandle() {
LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle,
"AnimationHandle destroyed while still animating!");
}
void AnimationHandle::notifyAnimationsRan() {
removeFromList();
if (mRenderNode->animators().hasAnimators()) {
mContext.addAnimationHandle(this);
} else {
mRenderNode->animators().setAnimationHandle(NULL);
delete this;
}
}
void AnimationHandle::insertAfter(AnimationHandle* prev) {
removeFromList();
mNextHandle = prev->mNextHandle;
if (mNextHandle) {
mNextHandle->mPreviousHandle = this;
}
prev->mNextHandle = this;
mPreviousHandle = prev;
}
void AnimationHandle::removeFromList() {
if (mPreviousHandle) {
mPreviousHandle->mNextHandle = mNextHandle;
}
if (mNextHandle) {
mNextHandle->mPreviousHandle = mPreviousHandle;
}
mPreviousHandle = NULL;
mNextHandle = NULL;
}
} /* namespace uirenderer */
} /* namespace android */
|