diff options
author | John Reck <jreck@google.com> | 2014-06-24 15:34:58 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-06-26 10:45:43 -0700 |
commit | 68bfe0a37a0dcef52abd81688d8520c5d16e1a85 (patch) | |
tree | b67e0671dba8221a16fcf880daeaf1e271499e9f /libs/hwui/AnimatorManager.cpp | |
parent | 6507f2e03a90244e08fb62f9b55653ba3230d0b7 (diff) |
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
Diffstat (limited to 'libs/hwui/AnimatorManager.cpp')
-rw-r--r-- | libs/hwui/AnimatorManager.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp new file mode 100644 index 000000000000..6a10cf8f48fc --- /dev/null +++ b/libs/hwui/AnimatorManager.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "AnimatorManager.h" + +#include <algorithm> + +#include "RenderNode.h" + +namespace android { +namespace uirenderer { + +using namespace std; + +static void unref(BaseRenderNodeAnimator* animator) { + animator->decStrong(0); +} + +AnimatorManager::AnimatorManager(RenderNode& parent) + : mParent(parent) { +} + +AnimatorManager::~AnimatorManager() { + for_each(mNewAnimators.begin(), mNewAnimators.end(), unref); + for_each(mAnimators.begin(), mAnimators.end(), unref); +} + +void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) { + animator->incStrong(0); + animator->onAttached(&mParent); + mNewAnimators.push_back(animator.get()); +} + +template<typename T> +static void move_all(T& source, T& dest) { + dest.reserve(source.size() + dest.size()); + for (typename T::iterator it = source.begin(); it != source.end(); it++) { + dest.push_back(*it); + } + source.clear(); +} + +void AnimatorManager::pushStaging(TreeInfo& info) { + if (mNewAnimators.size()) { + // Since this is a straight move, we don't need to inc/dec the ref count + move_all(mNewAnimators, mAnimators); + } + for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) { + (*it)->pushStaging(&mParent, info); + } +} + +class AnimateFunctor { +public: + AnimateFunctor(RenderNode& target, TreeInfo& info) + : mTarget(target), mInfo(info) {} + + bool operator() (BaseRenderNodeAnimator* animator) { + bool remove = animator->animate(&mTarget, mInfo); + if (remove) { + animator->decStrong(0); + } + return remove; + } +private: + RenderNode& mTarget; + TreeInfo& mInfo; +}; + +void AnimatorManager::animate(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 + + mParent.damageSelf(info); + info.damageAccumulator->popTransform(); + + AnimateFunctor functor(mParent, info); + std::vector< BaseRenderNodeAnimator* >::iterator newEnd; + newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor); + mAnimators.erase(newEnd, mAnimators.end()); + + mParent.mProperties.updateMatrix(); + info.damageAccumulator->pushTransform(&mParent); + mParent.damageSelf(info); +} + +} /* namespace uirenderer */ +} /* namespace android */ |