AnimationContext.cpp revision e2478d45ccbe5b6abb360ac9d44771b5f4a50bde
1119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck/*
2119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * Copyright (C) 2014 The Android Open Source Project
3119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck *
4119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * Licensed under the Apache License, Version 2.0 (the "License");
5119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * you may not use this file except in compliance with the License.
6119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * You may obtain a copy of the License at
7119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck *
8119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck *      http://www.apache.org/licenses/LICENSE-2.0
9119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck *
10119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * Unless required by applicable law or agreed to in writing, software
11119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * distributed under the License is distributed on an "AS IS" BASIS,
12119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * See the License for the specific language governing permissions and
14119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck * limitations under the License.
15119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck */
16119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck#include "AnimationContext.h"
17119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
18119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck#include "Animator.h"
19119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck#include "RenderNode.h"
20119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck#include "TreeInfo.h"
21119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck#include "renderthread/TimeLord.h"
22119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
23119907cd2575c56b1ebf66348b52e67aaf6a88d8John Recknamespace android {
24119907cd2575c56b1ebf66348b52e67aaf6a88d8John Recknamespace uirenderer {
25119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
26119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationContext::AnimationContext(renderthread::TimeLord& clock)
27119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        : mClock(clock)
28119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mCurrentFrameAnimations(*this)
29119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mNextFrameAnimations(*this)
30119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mFrameTimeMs(0) {
31119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
32119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
33119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationContext::~AnimationContext() {
34e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck}
35e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck
36e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reckvoid AnimationContext::destroy() {
37d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    startFrame();
38d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    while (mCurrentFrameAnimations.mNextHandle) {
39d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck        AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
40d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck        AnimatorManager& animators = current->mRenderNode->animators();
41e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck        animators.endAllActiveAnimators();
42d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck        LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
43c7e2993628a6c87500cb7e5369e6a52eacb3280cJohn Reck                "endAllAnimators failed to remove from current frame list!");
44d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    }
45119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
46119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
47119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::addAnimatingRenderNode(RenderNode& node) {
48119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (!node.animators().hasAnimationHandle()) {
49119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimationHandle* handle = new AnimationHandle(node, *this);
50119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        addAnimationHandle(handle);
51119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
52119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
53119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
54119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::addAnimationHandle(AnimationHandle* handle) {
55119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    handle->insertAfter(&mNextFrameAnimations);
56119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
57119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
58119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::startFrame() {
59119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle,
60119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            "Missed running animations last frame!");
61119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    AnimationHandle* head = mNextFrameAnimations.mNextHandle;
62119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (head) {
63119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mNextFrameAnimations.mNextHandle = NULL;
64119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mCurrentFrameAnimations.mNextHandle = head;
65119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        head->mPreviousHandle = &mCurrentFrameAnimations;
66119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
67119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mFrameTimeMs = mClock.computeFrameTimeMs();
68119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
69119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
70119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::runRemainingAnimations(TreeInfo& info) {
71119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    while (mCurrentFrameAnimations.mNextHandle) {
72119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
73119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimatorManager& animators = current->mRenderNode->animators();
74119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        animators.pushStaging();
75119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        animators.animateNoDamage(info);
76119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
77119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                "Animate failed to remove from current frame list!");
78119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
79119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
80119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
81119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator,
82119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimationListener* listener) {
83119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    listener->onAnimationFinished(animator);
84119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
85119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
86119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationHandle::AnimationHandle(AnimationContext& context)
87119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        : mContext(context)
88119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mPreviousHandle(NULL)
89119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mNextHandle(NULL) {
90119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
91119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
92119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context)
93119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        : mRenderNode(&animatingNode)
94119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mContext(context)
95119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mPreviousHandle(NULL)
96119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mNextHandle(NULL) {
97119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mRenderNode->animators().setAnimationHandle(this);
98119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
99119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
100119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationHandle::~AnimationHandle() {
101119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle,
102119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            "AnimationHandle destroyed while still animating!");
103119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
104119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
105119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationHandle::notifyAnimationsRan() {
106119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    removeFromList();
107119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (mRenderNode->animators().hasAnimators()) {
108119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mContext.addAnimationHandle(this);
109119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    } else {
110d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck        release();
111119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
112119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
113119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
114d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reckvoid AnimationHandle::release() {
115d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    LOG_ALWAYS_FATAL_IF(mRenderNode->animators().hasAnimators(),
116d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck            "Releasing the handle for an RenderNode with outstanding animators!");
117d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    removeFromList();
118d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    mRenderNode->animators().setAnimationHandle(NULL);
119d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    delete this;
120d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck}
121d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck
122119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationHandle::insertAfter(AnimationHandle* prev) {
123119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    removeFromList();
124119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mNextHandle = prev->mNextHandle;
125119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (mNextHandle) {
126119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mNextHandle->mPreviousHandle = this;
127119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
128119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    prev->mNextHandle = this;
129119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mPreviousHandle = prev;
130119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
131119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
132119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationHandle::removeFromList() {
133119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (mPreviousHandle) {
134119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mPreviousHandle->mNextHandle = mNextHandle;
135119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
136119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (mNextHandle) {
137119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mNextHandle->mPreviousHandle = mPreviousHandle;
138119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
139119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mPreviousHandle = NULL;
140119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mNextHandle = NULL;
141119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
142119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
143119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck} /* namespace uirenderer */
144119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck} /* namespace android */
145