AnimationContext.cpp revision 119907cd2575c56b1ebf66348b52e67aaf6a88d8
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 "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 */
127