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