2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "AnimationContext.h"
19 #include "RenderNode.h"
20 #include "renderthread/TimeLord.h"
23 namespace uirenderer {
25 AnimationContext::AnimationContext(renderthread::TimeLord& clock)
27 , mCurrentFrameAnimations(*this)
28 , mNextFrameAnimations(*this)
32 AnimationContext::~AnimationContext() {
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!");
46 void AnimationContext::addAnimatingRenderNode(RenderNode& node) {
47 if (!node.animators().hasAnimationHandle()) {
48 AnimationHandle* handle = new AnimationHandle(node, *this);
49 addAnimationHandle(handle);
53 void AnimationContext::addAnimationHandle(AnimationHandle* handle) {
54 handle->insertAfter(&mNextFrameAnimations);
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;
62 mNextFrameAnimations.mNextHandle = nullptr;
63 mCurrentFrameAnimations.mNextHandle = head;
64 head->mPreviousHandle = &mCurrentFrameAnimations;
66 mFrameTimeMs = ns2ms(mClock.latestVsync());
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!");
80 void AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator,
81 AnimationListener* listener) {
82 listener->onAnimationFinished(animator);
85 AnimationHandle::AnimationHandle(AnimationContext& context)
87 , mPreviousHandle(nullptr)
88 , mNextHandle(nullptr) {
91 AnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context)
92 : mRenderNode(&animatingNode)
94 , mPreviousHandle(nullptr)
95 , mNextHandle(nullptr) {
96 mRenderNode->animators().setAnimationHandle(this);
99 AnimationHandle::~AnimationHandle() {
100 LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle,
101 "AnimationHandle destroyed while still animating!");
104 void AnimationHandle::notifyAnimationsRan() {
106 if (mRenderNode->animators().hasAnimators()) {
107 mContext.addAnimationHandle(this);
113 void AnimationHandle::release() {
114 LOG_ALWAYS_FATAL_IF(mRenderNode->animators().hasAnimators(),
115 "Releasing the handle for an RenderNode with outstanding animators!");
117 mRenderNode->animators().setAnimationHandle(nullptr);
121 void AnimationHandle::insertAfter(AnimationHandle* prev) {
123 mNextHandle = prev->mNextHandle;
125 mNextHandle->mPreviousHandle = this;
127 prev->mNextHandle = this;
128 mPreviousHandle = prev;
131 void AnimationHandle::removeFromList() {
132 if (mPreviousHandle) {
133 mPreviousHandle->mNextHandle = mNextHandle;
136 mNextHandle->mPreviousHandle = mPreviousHandle;
138 mPreviousHandle = nullptr;
139 mNextHandle = nullptr;
142 } /* namespace uirenderer */
143 } /* namespace android */