blob: ec44de369f1f909cfe92d83e5f29f8fe652ca950 [file] [log] [blame]
John Reck119907c2014-08-14 09:02:01 -07001/*
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 */