Animator refactoring & fixes

 Tweaks animators to have less unnecessary refcounting

 Pull animator management out into seperate class

 More control to tweak animator lifecycle, such as doing
 Java-side handling of start delay by attaching but not
 starting the animator

Change-Id: I4ff8207580ca11fb38f45ef0007b406e0097281c
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 131384a..e803ec3 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -62,7 +62,7 @@
         , mNeedsDisplayListDataSync(false)
         , mDisplayListData(0)
         , mStagingDisplayListData(0)
-        , mNeedsAnimatorsSync(false)
+        , mAnimatorManager(*this)
         , mLayer(0) {
 }
 
@@ -117,6 +117,10 @@
     prepareTreeImpl(info);
 }
 
+void RenderNode::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+    mAnimatorManager.addAnimator(animator);
+}
+
 void RenderNode::damageSelf(TreeInfo& info) {
     if (isRenderable()) {
         if (properties().getClipDamageToBounds()) {
@@ -193,11 +197,11 @@
     info.damageAccumulator->pushTransform(this);
     if (info.mode == TreeInfo::MODE_FULL) {
         pushStagingPropertiesChanges(info);
-        evaluateAnimations(info);
+        mAnimatorManager.animate(info);
     } else if (info.mode == TreeInfo::MODE_MAYBE_DETACHING) {
         pushStagingPropertiesChanges(info);
     } else if (info.mode == TreeInfo::MODE_RT_ONLY) {
-        evaluateAnimations(info);
+        mAnimatorManager.animate(info);
     }
 
     prepareLayer(info);
@@ -210,33 +214,11 @@
     info.damageAccumulator->popTransform();
 }
 
-class PushAnimatorsFunctor {
-public:
-    PushAnimatorsFunctor(RenderNode* target, TreeInfo& info)
-            : mTarget(target), mInfo(info) {}
-
-    bool operator() (const sp<BaseRenderNodeAnimator>& animator) {
-        animator->setupStartValueIfNecessary(mTarget, mInfo);
-        return animator->isFinished();
-    }
-private:
-    RenderNode* mTarget;
-    TreeInfo& mInfo;
-};
-
 void RenderNode::pushStagingPropertiesChanges(TreeInfo& info) {
     // Push the animators first so that setupStartValueIfNecessary() is called
     // before properties() is trampled by stagingProperties(), as they are
     // required by some animators.
-    if (mNeedsAnimatorsSync) {
-        mAnimators.resize(mStagingAnimators.size());
-        std::vector< sp<BaseRenderNodeAnimator> >::iterator it;
-        PushAnimatorsFunctor functor(this, info);
-        // hint: this means copy_if_not()
-        it = std::remove_copy_if(mStagingAnimators.begin(), mStagingAnimators.end(),
-                mAnimators.begin(), functor);
-        mAnimators.resize(std::distance(mAnimators.begin(), it));
-    }
+    mAnimatorManager.pushStaging(info);
     if (mDirtyPropertyFields) {
         mDirtyPropertyFields = 0;
         damageSelf(info);
@@ -267,8 +249,7 @@
         mNeedsDisplayListDataSync = false;
         // Do a push pass on the old tree to handle freeing DisplayListData
         // that are no longer used
-        TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING, info.renderState);
-        oldTreeInfo.damageAccumulator = info.damageAccumulator;
+        TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING, info);
         prepareSubTree(oldTreeInfo, mDisplayListData);
         delete mDisplayListData;
         mDisplayListData = mStagingDisplayListData;
@@ -277,39 +258,6 @@
     }
 }
 
-class AnimateFunctor {
-public:
-    AnimateFunctor(RenderNode* target, TreeInfo& info)
-            : mTarget(target), mInfo(info) {}
-
-    bool operator() (const sp<BaseRenderNodeAnimator>& animator) {
-        return animator->animate(mTarget, mInfo);
-    }
-private:
-    RenderNode* mTarget;
-    TreeInfo& mInfo;
-};
-
-void RenderNode::evaluateAnimations(TreeInfo& info) {
-    if (!mAnimators.size()) return;
-
-    // TODO: Can we target this better? For now treat it like any other staging
-    // property push and just damage self before and after animators are run
-
-    damageSelf(info);
-    info.damageAccumulator->popTransform();
-
-    AnimateFunctor functor(this, info);
-    std::vector< sp<BaseRenderNodeAnimator> >::iterator newEnd;
-    newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
-    mAnimators.erase(newEnd, mAnimators.end());
-    mProperties.updateMatrix();
-    info.out.hasAnimations |= mAnimators.size();
-
-    info.damageAccumulator->pushTransform(this);
-    damageSelf(info);
-}
-
 void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
     if (subtree) {
         TextureCache& cache = Caches::getInstance().textureCache;