AnimationContext.cpp revision 501ff9acfe9dd656c1fb6d82ec0533c3244fd88b
19e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu/*
29e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Copyright (C) 2014 The Android Open Source Project
39e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *
49e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Licensed under the Apache License, Version 2.0 (the "License");
59e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * you may not use this file except in compliance with the License.
69e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * You may obtain a copy of the License at
79e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *
89e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *      http://www.apache.org/licenses/LICENSE-2.0
99e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *
109e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Unless required by applicable law or agreed to in writing, software
119e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * distributed under the License is distributed on an "AS IS" BASIS,
129e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * See the License for the specific language governing permissions and
149e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * limitations under the License.
159e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu */
169e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include "AnimationContext.h"
179e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
189e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include "Animator.h"
199e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include "RenderNode.h"
209e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include "renderthread/TimeLord.h"
219e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
229e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wunamespace android {
2319352b3287480394aa9963276305d5168a7adf85Ronghua Wunamespace uirenderer {
249e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
259e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua WuAnimationContext::AnimationContext(renderthread::TimeLord& clock)
269e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        : mClock(clock)
279e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        , mCurrentFrameAnimations(*this)
289ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu        , mNextFrameAnimations(*this)
2979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        , mFrameTimeMs(0) {
309e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
319e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
3279608158c2254fe1357959157f2d0c1560a8a6c6Chong ZhangAnimationContext::~AnimationContext() {
339e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
349e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
359e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid AnimationContext::destroy() {
3665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    startFrame(TreeInfo::MODE_RT_ONLY);
3765c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    while (mCurrentFrameAnimations.mNextHandle) {
3819352b3287480394aa9963276305d5168a7adf85Ronghua Wu        AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
3919352b3287480394aa9963276305d5168a7adf85Ronghua Wu        AnimatorManager& animators = current->mRenderNode->animators();
4019352b3287480394aa9963276305d5168a7adf85Ronghua Wu        animators.endAllActiveAnimators();
4119352b3287480394aa9963276305d5168a7adf85Ronghua Wu        LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
4219352b3287480394aa9963276305d5168a7adf85Ronghua Wu                "endAllAnimators failed to remove from current frame list!");
4319352b3287480394aa9963276305d5168a7adf85Ronghua Wu    }
4419352b3287480394aa9963276305d5168a7adf85Ronghua Wu}
4519352b3287480394aa9963276305d5168a7adf85Ronghua Wu
4619352b3287480394aa9963276305d5168a7adf85Ronghua Wuvoid AnimationContext::addAnimatingRenderNode(RenderNode& node) {
479e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    if (!node.animators().hasAnimationHandle()) {
489e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        AnimationHandle* handle = new AnimationHandle(node, *this);
499e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        addAnimationHandle(handle);
509e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
519e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
5240d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh
539e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid AnimationContext::addAnimationHandle(AnimationHandle* handle) {
549e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    handle->insertAfter(&mNextFrameAnimations);
559e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
569e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
579e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid AnimationContext::startFrame(TreeInfo::TraversalMode mode) {
589e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle,
599e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            "Missed running animations last frame!");
609e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    AnimationHandle* head = mNextFrameAnimations.mNextHandle;
619e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    if (head) {
629e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        mNextFrameAnimations.mNextHandle = nullptr;
639e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        mCurrentFrameAnimations.mNextHandle = head;
649e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        head->mPreviousHandle = &mCurrentFrameAnimations;
659e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
669e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    mFrameTimeMs = ns2ms(mClock.latestVsync());
679e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
689e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
699e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid AnimationContext::runRemainingAnimations(TreeInfo& info) {
709e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    while (mCurrentFrameAnimations.mNextHandle) {
719e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
729e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        AnimatorManager& animators = current->mRenderNode->animators();
739e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        animators.pushStaging();
749e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        animators.animateNoDamage(info);
7540d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh        LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
769e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu                "Animate failed to remove from current frame list!");
779e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
789e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
799e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
809e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator,
819e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        AnimationListener* listener) {
829e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    listener->onAnimationFinished(animator);
839e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
849e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
859e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua WuAnimationHandle::AnimationHandle(AnimationContext& context)
869e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        : mContext(context)
879e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        , mPreviousHandle(nullptr)
889e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        , mNextHandle(nullptr) {
899e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
909e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
919e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua WuAnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context)
929e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        : mRenderNode(&animatingNode)
9340d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh        , mContext(context)
949e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        , mPreviousHandle(nullptr)
959e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        , mNextHandle(nullptr) {
969e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    mRenderNode->animators().setAnimationHandle(this);
979e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
989e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
999e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua WuAnimationHandle::~AnimationHandle() {
1009e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle,
10179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang            "AnimationHandle destroyed while still animating!");
1029e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
1039e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1049e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid AnimationHandle::notifyAnimationsRan() {
1059e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    removeFromList();
1069e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    if (mRenderNode->animators().hasAnimators()) {
1079e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        mContext.addAnimationHandle(this);
1089e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    } else {
1099e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        release();
1109e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
1119e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
1129e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1139e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid AnimationHandle::release() {
1149e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    LOG_ALWAYS_FATAL_IF(mRenderNode->animators().hasAnimators(),
1159e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            "Releasing the handle for an RenderNode with outstanding animators!");
1169e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    removeFromList();
1179e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    mRenderNode->animators().setAnimationHandle(nullptr);
1189e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    delete this;
1199e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
1209e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1219e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuvoid AnimationHandle::insertAfter(AnimationHandle* prev) {
1229e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    removeFromList();
1239e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    mNextHandle = prev->mNextHandle;
1249e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    if (mNextHandle) {
1259e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        mNextHandle->mPreviousHandle = this;
1269e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
1279e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    prev->mNextHandle = this;
1289e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    mPreviousHandle = prev;
1299e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
1309e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
13140d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsiehvoid AnimationHandle::removeFromList() {
1329e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    if (mPreviousHandle) {
1339e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        mPreviousHandle->mNextHandle = mNextHandle;
1349e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
1359e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    if (mNextHandle) {
1369e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        mNextHandle->mPreviousHandle = mPreviousHandle;
1379e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
1389e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    mPreviousHandle = nullptr;
1399e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    mNextHandle = nullptr;
1409e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
1419e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1429e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} /* namespace uirenderer */
1439e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} /* namespace android */
1449e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu