168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck/* 268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * Copyright (C) 2014 The Android Open Source Project 368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * 468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * Licensed under the Apache License, Version 2.0 (the "License"); 568bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * you may not use this file except in compliance with the License. 668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * You may obtain a copy of the License at 768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * 868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * http://www.apache.org/licenses/LICENSE-2.0 968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * 1068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * Unless required by applicable law or agreed to in writing, software 1168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * distributed under the License is distributed on an "AS IS" BASIS, 1268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * See the License for the specific language governing permissions and 1468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck * limitations under the License. 1568bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck */ 1668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck#include "AnimatorManager.h" 1768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 1868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck#include <algorithm> 1968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 20119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck#include "AnimationContext.h" 2168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck#include "RenderNode.h" 2268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 2368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Recknamespace android { 2468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Recknamespace uirenderer { 2568bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 2668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckusing namespace std; 2768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 2868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckstatic void unref(BaseRenderNodeAnimator* animator) { 298d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck animator->detach(); 3068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck animator->decStrong(0); 3168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} 3268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 3368bfe0a37a0dcef52abd81688d8520c5d16e1a85John ReckAnimatorManager::AnimatorManager(RenderNode& parent) 34119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck : mParent(parent) 35119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck , mAnimationHandle(NULL) { 3668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} 3768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 3868bfe0a37a0dcef52abd81688d8520c5d16e1a85John ReckAnimatorManager::~AnimatorManager() { 3968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck for_each(mNewAnimators.begin(), mNewAnimators.end(), unref); 4068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck for_each(mAnimators.begin(), mAnimators.end(), unref); 4168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} 4268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 4368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckvoid AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) { 4468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck animator->incStrong(0); 458d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck animator->attach(&mParent); 4668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck mNewAnimators.push_back(animator.get()); 4768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} 4868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 49119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimatorManager::setAnimationHandle(AnimationHandle* handle) { 50119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck LOG_ALWAYS_FATAL_IF(mAnimationHandle && handle, "Already have an AnimationHandle!"); 51119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck mAnimationHandle = handle; 52e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck LOG_ALWAYS_FATAL_IF(!mAnimationHandle && mAnimators.size(), 53e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck "Lost animation handle on %p (%s) with outstanding animators!", 54e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck &mParent, mParent.getName()); 55119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck} 56119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 5768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Recktemplate<typename T> 5868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckstatic void move_all(T& source, T& dest) { 5968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck dest.reserve(source.size() + dest.size()); 6068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck for (typename T::iterator it = source.begin(); it != source.end(); it++) { 6168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck dest.push_back(*it); 6268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck } 6368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck source.clear(); 6468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} 6568bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 66119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimatorManager::pushStaging() { 6768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck if (mNewAnimators.size()) { 68e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck LOG_ALWAYS_FATAL_IF(!mAnimationHandle, 69e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck "Trying to start new animators on %p (%s) without an animation handle!", 70e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck &mParent, mParent.getName()); 7168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck // Since this is a straight move, we don't need to inc/dec the ref count 7268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck move_all(mNewAnimators, mAnimators); 7368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck } 7468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) { 75119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck (*it)->pushStaging(mAnimationHandle->context()); 7668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck } 7768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} 7868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 7968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckclass AnimateFunctor { 8068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckpublic: 81119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck AnimateFunctor(TreeInfo& info, AnimationContext& context) 82119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck : dirtyMask(0), mInfo(info), mContext(context) {} 8368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 8468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck bool operator() (BaseRenderNodeAnimator* animator) { 85a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck dirtyMask |= animator->dirtyMask(); 86119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck bool remove = animator->animate(mContext); 8768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck if (remove) { 8868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck animator->decStrong(0); 89119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck } else { 90119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck if (animator->isRunning()) { 91119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck mInfo.out.hasAnimations = true; 92119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck } 93f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck if (CC_UNLIKELY(!animator->mayRunAsync())) { 94f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck mInfo.out.requiresUiRedraw = true; 95f5945a0c8bb868f978d9d0d22043a8b44464a86eJohn Reck } 9668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck } 9768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck return remove; 9868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck } 99a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck 100a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck uint32_t dirtyMask; 101a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck 10268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckprivate: 10368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck TreeInfo& mInfo; 104119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck AnimationContext& mContext; 10568bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck}; 10668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 107a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reckuint32_t AnimatorManager::animate(TreeInfo& info) { 108a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck if (!mAnimators.size()) return 0; 10968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 11068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck // TODO: Can we target this better? For now treat it like any other staging 11168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck // property push and just damage self before and after animators are run 11268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 11368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck mParent.damageSelf(info); 11468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck info.damageAccumulator->popTransform(); 11568bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 116119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck uint32_t dirty = animateCommon(info); 11768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 11868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck mParent.mProperties.updateMatrix(); 11968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck info.damageAccumulator->pushTransform(&mParent); 12068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck mParent.damageSelf(info); 121a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck 122119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck return dirty; 123119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck} 124119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 125119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckvoid AnimatorManager::animateNoDamage(TreeInfo& info) { 126119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck if (!mAnimators.size()) return; 127119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 128119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck animateCommon(info); 129119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck} 130119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 131119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckuint32_t AnimatorManager::animateCommon(TreeInfo& info) { 132119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck AnimateFunctor functor(info, mAnimationHandle->context()); 133119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck std::vector< BaseRenderNodeAnimator* >::iterator newEnd; 134119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor); 135119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck mAnimators.erase(newEnd, mAnimators.end()); 136119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck mAnimationHandle->notifyAnimationsRan(); 137a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck return functor.dirtyMask; 13868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} 13968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 140e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reckstatic void endStagingAnimator(BaseRenderNodeAnimator* animator) { 141e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck animator->end(); 142e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck if (animator->listener()) { 143e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck animator->listener()->onAnimationFinished(animator); 144e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck } 145e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck animator->decStrong(0); 146e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck} 147e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck 148e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reckvoid AnimatorManager::endAllStagingAnimators() { 149e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck ALOGD("endAllStagingAnimators on %p (%s)", &mParent, mParent.getName()); 150e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck // This works because this state can only happen on the UI thread, 151e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck // which means we're already on the right thread to invoke listeners 152e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck for_each(mNewAnimators.begin(), mNewAnimators.end(), endStagingAnimator); 153e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck mNewAnimators.clear(); 154e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck} 155e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck 156e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reckclass EndActiveAnimatorsFunctor { 157119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckpublic: 158e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck EndActiveAnimatorsFunctor(AnimationContext& context) : mContext(context) {} 159119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 160119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck void operator() (BaseRenderNodeAnimator* animator) { 161e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck animator->forceEndNow(mContext); 162119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck animator->decStrong(0); 163119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck } 164119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 165119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckprivate: 166119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck AnimationContext& mContext; 167119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck}; 168119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 169e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reckvoid AnimatorManager::endAllActiveAnimators() { 170e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck ALOGD("endAllStagingAnimators on %p (%s) with handle %p", 171e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck &mParent, mParent.getName(), mAnimationHandle); 172e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck EndActiveAnimatorsFunctor functor(mAnimationHandle->context()); 173e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck for_each(mAnimators.begin(), mAnimators.end(), functor); 174e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck mAnimators.clear(); 175e2478d45ccbe5b6abb360ac9d44771b5f4a50bdeJohn Reck mAnimationHandle->release(); 176119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck} 177119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 17868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} /* namespace uirenderer */ 17968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} /* namespace android */ 180