blob: 097be08faaad4390cdce4a7ad17b97e4dc43b770 [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"
John Reck119907c2014-08-14 09:02:01 -070020#include "renderthread/TimeLord.h"
21
22namespace android {
23namespace uirenderer {
24
25AnimationContext::AnimationContext(renderthread::TimeLord& clock)
26 : mClock(clock)
27 , mCurrentFrameAnimations(*this)
28 , mNextFrameAnimations(*this)
29 , mFrameTimeMs(0) {
30}
31
32AnimationContext::~AnimationContext() {
John Recke2478d42014-09-03 16:46:05 -070033}
34
35void AnimationContext::destroy() {
John Reckec845a22014-09-05 15:23:38 -070036 startFrame(TreeInfo::MODE_RT_ONLY);
John Reckd0cd9db2014-08-28 08:43:39 -070037 while (mCurrentFrameAnimations.mNextHandle) {
38 AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
39 AnimatorManager& animators = current->mRenderNode->animators();
John Recke2478d42014-09-03 16:46:05 -070040 animators.endAllActiveAnimators();
John Reckd0cd9db2014-08-28 08:43:39 -070041 LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
John Reckc7e29932014-08-28 09:56:20 -070042 "endAllAnimators failed to remove from current frame list!");
John Reckd0cd9db2014-08-28 08:43:39 -070043 }
John Reck119907c2014-08-14 09:02:01 -070044}
45
46void AnimationContext::addAnimatingRenderNode(RenderNode& node) {
47 if (!node.animators().hasAnimationHandle()) {
48 AnimationHandle* handle = new AnimationHandle(node, *this);
49 addAnimationHandle(handle);
50 }
51}
52
53void AnimationContext::addAnimationHandle(AnimationHandle* handle) {
54 handle->insertAfter(&mNextFrameAnimations);
55}
56
Andreas Gampe64bb4132014-11-22 00:35:09 +000057void AnimationContext::startFrame(TreeInfo::TraversalMode mode) {
John Reck119907c2014-08-14 09:02:01 -070058 LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle,
59 "Missed running animations last frame!");
60 AnimationHandle* head = mNextFrameAnimations.mNextHandle;
61 if (head) {
Chris Craikd41c4d82015-01-05 15:51:13 -080062 mNextFrameAnimations.mNextHandle = nullptr;
John Reck119907c2014-08-14 09:02:01 -070063 mCurrentFrameAnimations.mNextHandle = head;
64 head->mPreviousHandle = &mCurrentFrameAnimations;
65 }
66 mFrameTimeMs = mClock.computeFrameTimeMs();
67}
68
69void 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
80void AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator,
81 AnimationListener* listener) {
82 listener->onAnimationFinished(animator);
83}
84
85AnimationHandle::AnimationHandle(AnimationContext& context)
86 : mContext(context)
Chris Craikd41c4d82015-01-05 15:51:13 -080087 , mPreviousHandle(nullptr)
88 , mNextHandle(nullptr) {
John Reck119907c2014-08-14 09:02:01 -070089}
90
91AnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context)
92 : mRenderNode(&animatingNode)
93 , mContext(context)
Chris Craikd41c4d82015-01-05 15:51:13 -080094 , mPreviousHandle(nullptr)
95 , mNextHandle(nullptr) {
John Reck119907c2014-08-14 09:02:01 -070096 mRenderNode->animators().setAnimationHandle(this);
97}
98
99AnimationHandle::~AnimationHandle() {
100 LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle,
101 "AnimationHandle destroyed while still animating!");
102}
103
104void AnimationHandle::notifyAnimationsRan() {
105 removeFromList();
106 if (mRenderNode->animators().hasAnimators()) {
107 mContext.addAnimationHandle(this);
108 } else {
John Reckd0cd9db2014-08-28 08:43:39 -0700109 release();
John Reck119907c2014-08-14 09:02:01 -0700110 }
111}
112
John Reckd0cd9db2014-08-28 08:43:39 -0700113void AnimationHandle::release() {
114 LOG_ALWAYS_FATAL_IF(mRenderNode->animators().hasAnimators(),
115 "Releasing the handle for an RenderNode with outstanding animators!");
116 removeFromList();
Chris Craikd41c4d82015-01-05 15:51:13 -0800117 mRenderNode->animators().setAnimationHandle(nullptr);
John Reckd0cd9db2014-08-28 08:43:39 -0700118 delete this;
119}
120
John Reck119907c2014-08-14 09:02:01 -0700121void 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
131void AnimationHandle::removeFromList() {
132 if (mPreviousHandle) {
133 mPreviousHandle->mNextHandle = mNextHandle;
134 }
135 if (mNextHandle) {
136 mNextHandle->mPreviousHandle = mPreviousHandle;
137 }
Chris Craikd41c4d82015-01-05 15:51:13 -0800138 mPreviousHandle = nullptr;
139 mNextHandle = nullptr;
John Reck119907c2014-08-14 09:02:01 -0700140}
141
142} /* namespace uirenderer */
143} /* namespace android */