Home | History | Annotate | Download | only in hwui
      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 "renderthread/TimeLord.h"
     21 
     22 namespace android {
     23 namespace uirenderer {
     24 
     25 AnimationContext::AnimationContext(renderthread::TimeLord& clock)
     26         : mClock(clock)
     27         , mCurrentFrameAnimations(*this)
     28         , mNextFrameAnimations(*this)
     29         , mFrameTimeMs(0) {}
     30 
     31 AnimationContext::~AnimationContext() {}
     32 
     33 void AnimationContext::destroy() {
     34     startFrame(TreeInfo::MODE_RT_ONLY);
     35     while (mCurrentFrameAnimations.mNextHandle) {
     36         AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
     37         AnimatorManager& animators = current->mRenderNode->animators();
     38         animators.endAllActiveAnimators();
     39         LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
     40                             "endAllAnimators failed to remove from current frame list!");
     41     }
     42 }
     43 
     44 void AnimationContext::addAnimatingRenderNode(RenderNode& node) {
     45     if (!node.animators().hasAnimationHandle()) {
     46         AnimationHandle* handle = new AnimationHandle(node, *this);
     47         addAnimationHandle(handle);
     48     }
     49 }
     50 
     51 void AnimationContext::addAnimationHandle(AnimationHandle* handle) {
     52     handle->insertAfter(&mNextFrameAnimations);
     53 }
     54 
     55 void AnimationContext::startFrame(TreeInfo::TraversalMode mode) {
     56     LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle,
     57                         "Missed running animations last frame!");
     58     AnimationHandle* head = mNextFrameAnimations.mNextHandle;
     59     if (head) {
     60         mNextFrameAnimations.mNextHandle = nullptr;
     61         mCurrentFrameAnimations.mNextHandle = head;
     62         head->mPreviousHandle = &mCurrentFrameAnimations;
     63     }
     64     mFrameTimeMs = ns2ms(mClock.latestVsync());
     65 }
     66 
     67 void AnimationContext::runRemainingAnimations(TreeInfo& info) {
     68     while (mCurrentFrameAnimations.mNextHandle) {
     69         AnimationHandle* current = mCurrentFrameAnimations.mNextHandle;
     70         AnimatorManager& animators = current->mRenderNode->animators();
     71         animators.pushStaging();
     72         animators.animateNoDamage(info);
     73         LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current,
     74                             "Animate failed to remove from current frame list!");
     75     }
     76 }
     77 
     78 void AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator,
     79                                       AnimationListener* listener) {
     80     listener->onAnimationFinished(animator);
     81 }
     82 
     83 AnimationHandle::AnimationHandle(AnimationContext& context)
     84         : mContext(context), mPreviousHandle(nullptr), mNextHandle(nullptr) {}
     85 
     86 AnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context)
     87         : mRenderNode(&animatingNode)
     88         , mContext(context)
     89         , mPreviousHandle(nullptr)
     90         , mNextHandle(nullptr) {
     91     mRenderNode->animators().setAnimationHandle(this);
     92 }
     93 
     94 AnimationHandle::~AnimationHandle() {
     95     LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle,
     96                         "AnimationHandle destroyed while still animating!");
     97 }
     98 
     99 void AnimationHandle::notifyAnimationsRan() {
    100     removeFromList();
    101     if (mRenderNode->animators().hasAnimators()) {
    102         mContext.addAnimationHandle(this);
    103     } else {
    104         release();
    105     }
    106 }
    107 
    108 void AnimationHandle::release() {
    109     LOG_ALWAYS_FATAL_IF(mRenderNode->animators().hasAnimators(),
    110                         "Releasing the handle for an RenderNode with outstanding animators!");
    111     removeFromList();
    112     mRenderNode->animators().setAnimationHandle(nullptr);
    113     delete this;
    114 }
    115 
    116 void AnimationHandle::insertAfter(AnimationHandle* prev) {
    117     removeFromList();
    118     mNextHandle = prev->mNextHandle;
    119     if (mNextHandle) {
    120         mNextHandle->mPreviousHandle = this;
    121     }
    122     prev->mNextHandle = this;
    123     mPreviousHandle = prev;
    124 }
    125 
    126 void AnimationHandle::removeFromList() {
    127     if (mPreviousHandle) {
    128         mPreviousHandle->mNextHandle = mNextHandle;
    129     }
    130     if (mNextHandle) {
    131         mNextHandle->mPreviousHandle = mPreviousHandle;
    132     }
    133     mPreviousHandle = nullptr;
    134     mNextHandle = nullptr;
    135 }
    136 
    137 } /* namespace uirenderer */
    138 } /* namespace android */
    139