AnimationContext.cpp revision d41c4d8c732095ae99c955b6b82f7306633004b1
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 "renderthread/TimeLord.h"
21119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
22119907cd2575c56b1ebf66348b52e67aaf6a88d8John Recknamespace android {
23119907cd2575c56b1ebf66348b52e67aaf6a88d8John Recknamespace uirenderer {
24119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
25119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationContext::AnimationContext(renderthread::TimeLord& clock)
26119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        : mClock(clock)
27119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mCurrentFrameAnimations(*this)
28119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mNextFrameAnimations(*this)
29119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mFrameTimeMs(0) {
30119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
31119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
32119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationContext::~AnimationContext() {
33e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck}
34e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck
35e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reckvoid AnimationContext::destroy() {
36ec845a215e343cdb3b2e4c7b6aff7b24beb0236bJohn Reck    startFrame(TreeInfo::MODE_RT_ONLY);
37d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    while (mCurrentFrameAnimations.mNextHandle) {
38d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck        AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
39d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck        AnimatorManager& animators = current->mRenderNode->animators();
40e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck        animators.endAllActiveAnimators();
41d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck        LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
42c7e2993628a6c87500cb7e5369e6a52eacb3280cJohn Reck                "endAllAnimators failed to remove from current frame list!");
43d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    }
44119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
45119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
46119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::addAnimatingRenderNode(RenderNode& node) {
47119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (!node.animators().hasAnimationHandle()) {
48119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimationHandle* handle = new AnimationHandle(node, *this);
49119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        addAnimationHandle(handle);
50119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
51119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
52119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
53119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::addAnimationHandle(AnimationHandle* handle) {
54119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    handle->insertAfter(&mNextFrameAnimations);
55119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
56119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
5764bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampevoid AnimationContext::startFrame(TreeInfo::TraversalMode mode) {
58119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle,
59119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            "Missed running animations last frame!");
60119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    AnimationHandle* head = mNextFrameAnimations.mNextHandle;
61119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (head) {
62d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        mNextFrameAnimations.mNextHandle = nullptr;
63119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mCurrentFrameAnimations.mNextHandle = head;
64119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        head->mPreviousHandle = &mCurrentFrameAnimations;
65119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
66119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mFrameTimeMs = mClock.computeFrameTimeMs();
67119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
68119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
69119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::runRemainingAnimations(TreeInfo& info) {
70119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    while (mCurrentFrameAnimations.mNextHandle) {
71119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
72119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimatorManager& animators = current->mRenderNode->animators();
73119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        animators.pushStaging();
74119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        animators.animateNoDamage(info);
75119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
76119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                "Animate failed to remove from current frame list!");
77119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
78119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
79119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
80119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator,
81119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        AnimationListener* listener) {
82119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    listener->onAnimationFinished(animator);
83119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
84119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
85119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationHandle::AnimationHandle(AnimationContext& context)
86119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        : mContext(context)
87d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        , mPreviousHandle(nullptr)
88d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        , mNextHandle(nullptr) {
89119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
90119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
91119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context)
92119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        : mRenderNode(&animatingNode)
93119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        , mContext(context)
94d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        , mPreviousHandle(nullptr)
95d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik        , mNextHandle(nullptr) {
96119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mRenderNode->animators().setAnimationHandle(this);
97119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
98119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
99119907cd2575c56b1ebf66348b52e67aaf6a88d8John ReckAnimationHandle::~AnimationHandle() {
100119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle,
101119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            "AnimationHandle destroyed while still animating!");
102119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
103119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
104119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationHandle::notifyAnimationsRan() {
105119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    removeFromList();
106119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (mRenderNode->animators().hasAnimators()) {
107119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mContext.addAnimationHandle(this);
108119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    } else {
109d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck        release();
110119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
111119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
112119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
113d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reckvoid AnimationHandle::release() {
114d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    LOG_ALWAYS_FATAL_IF(mRenderNode->animators().hasAnimators(),
115d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck            "Releasing the handle for an RenderNode with outstanding animators!");
116d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    removeFromList();
117d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    mRenderNode->animators().setAnimationHandle(nullptr);
118d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck    delete this;
119d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck}
120d0cd9db31639b246587fe494ec15d32d9fdb3dc7John Reck
121119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationHandle::insertAfter(AnimationHandle* prev) {
122119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    removeFromList();
123119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mNextHandle = prev->mNextHandle;
124119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (mNextHandle) {
125119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mNextHandle->mPreviousHandle = this;
126119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
127119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    prev->mNextHandle = this;
128119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    mPreviousHandle = prev;
129119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
130119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
131119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimationHandle::removeFromList() {
132119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (mPreviousHandle) {
133119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mPreviousHandle->mNextHandle = mNextHandle;
134119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
135119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (mNextHandle) {
136119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mNextHandle->mPreviousHandle = mPreviousHandle;
137119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
138d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    mPreviousHandle = nullptr;
139d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik    mNextHandle = nullptr;
140119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}
141119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
142119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck} /* namespace uirenderer */
143119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck} /* namespace android */
144