blob: cd30b18593842b45050fad623f279c39d64debc7 [file] [log] [blame]
John Reck68bfe0a2014-06-24 15:34:58 -07001/*
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 "AnimatorManager.h"
17
18#include <algorithm>
19
Tom Hudson2dc236b2014-10-15 15:46:42 -040020#include "Animator.h"
John Reck119907c2014-08-14 09:02:01 -070021#include "AnimationContext.h"
Tom Hudson2dc236b2014-10-15 15:46:42 -040022#include "DamageAccumulator.h"
John Reck68bfe0a2014-06-24 15:34:58 -070023#include "RenderNode.h"
24
25namespace android {
26namespace uirenderer {
27
28using namespace std;
29
John Recke03ef252016-02-11 17:02:33 +000030static void unref(BaseRenderNodeAnimator* animator) {
John Reck8d8af3c2014-07-01 15:23:45 -070031 animator->detach();
John Recke03ef252016-02-11 17:02:33 +000032 animator->decStrong(nullptr);
John Reck68bfe0a2014-06-24 15:34:58 -070033}
34
35AnimatorManager::AnimatorManager(RenderNode& parent)
John Reck119907c2014-08-14 09:02:01 -070036 : mParent(parent)
Chris Craikd41c4d82015-01-05 15:51:13 -080037 , mAnimationHandle(nullptr) {
John Reck68bfe0a2014-06-24 15:34:58 -070038}
39
40AnimatorManager::~AnimatorManager() {
John Recke03ef252016-02-11 17:02:33 +000041 for_each(mNewAnimators.begin(), mNewAnimators.end(), unref);
42 for_each(mAnimators.begin(), mAnimators.end(), unref);
John Reck68bfe0a2014-06-24 15:34:58 -070043}
44
45void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
John Recke03ef252016-02-11 17:02:33 +000046 animator->incStrong(nullptr);
47 animator->attach(&mParent);
48 mNewAnimators.push_back(animator.get());
John Reck68bfe0a2014-06-24 15:34:58 -070049}
50
John Reck119907c2014-08-14 09:02:01 -070051void AnimatorManager::setAnimationHandle(AnimationHandle* handle) {
52 LOG_ALWAYS_FATAL_IF(mAnimationHandle && handle, "Already have an AnimationHandle!");
53 mAnimationHandle = handle;
John Recke2478d42014-09-03 16:46:05 -070054 LOG_ALWAYS_FATAL_IF(!mAnimationHandle && mAnimators.size(),
55 "Lost animation handle on %p (%s) with outstanding animators!",
56 &mParent, mParent.getName());
John Reck119907c2014-08-14 09:02:01 -070057}
58
John Recke03ef252016-02-11 17:02:33 +000059template<typename T>
60static void move_all(T& source, T& dest) {
61 dest.reserve(source.size() + dest.size());
62 for (typename T::iterator it = source.begin(); it != source.end(); it++) {
63 dest.push_back(*it);
64 }
65 source.clear();
66}
67
John Reck119907c2014-08-14 09:02:01 -070068void AnimatorManager::pushStaging() {
John Reck68bfe0a2014-06-24 15:34:58 -070069 if (mNewAnimators.size()) {
John Recke2478d42014-09-03 16:46:05 -070070 LOG_ALWAYS_FATAL_IF(!mAnimationHandle,
71 "Trying to start new animators on %p (%s) without an animation handle!",
72 &mParent, mParent.getName());
John Recke03ef252016-02-11 17:02:33 +000073 // Since this is a straight move, we don't need to inc/dec the ref count
74 move_all(mNewAnimators, mAnimators);
John Reck68bfe0a2014-06-24 15:34:58 -070075 }
John Recke03ef252016-02-11 17:02:33 +000076 for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) {
77 (*it)->pushStaging(mAnimationHandle->context());
John Reck68bfe0a2014-06-24 15:34:58 -070078 }
79}
80
81class AnimateFunctor {
82public:
John Reck119907c2014-08-14 09:02:01 -070083 AnimateFunctor(TreeInfo& info, AnimationContext& context)
84 : dirtyMask(0), mInfo(info), mContext(context) {}
John Reck68bfe0a2014-06-24 15:34:58 -070085
John Recke03ef252016-02-11 17:02:33 +000086 bool operator() (BaseRenderNodeAnimator* animator) {
John Recka7c2ea22014-08-08 13:21:00 -070087 dirtyMask |= animator->dirtyMask();
John Reck119907c2014-08-14 09:02:01 -070088 bool remove = animator->animate(mContext);
John Reck68bfe0a2014-06-24 15:34:58 -070089 if (remove) {
John Recke03ef252016-02-11 17:02:33 +000090 animator->decStrong(nullptr);
John Reck119907c2014-08-14 09:02:01 -070091 } else {
92 if (animator->isRunning()) {
93 mInfo.out.hasAnimations = true;
94 }
John Reckf5945a02014-09-05 15:57:47 -070095 if (CC_UNLIKELY(!animator->mayRunAsync())) {
96 mInfo.out.requiresUiRedraw = true;
97 }
John Reck68bfe0a2014-06-24 15:34:58 -070098 }
99 return remove;
100 }
John Recka7c2ea22014-08-08 13:21:00 -0700101
102 uint32_t dirtyMask;
103
John Reck68bfe0a2014-06-24 15:34:58 -0700104private:
John Reck68bfe0a2014-06-24 15:34:58 -0700105 TreeInfo& mInfo;
John Reck119907c2014-08-14 09:02:01 -0700106 AnimationContext& mContext;
John Reck68bfe0a2014-06-24 15:34:58 -0700107};
108
John Recka7c2ea22014-08-08 13:21:00 -0700109uint32_t AnimatorManager::animate(TreeInfo& info) {
110 if (!mAnimators.size()) return 0;
John Reck68bfe0a2014-06-24 15:34:58 -0700111
112 // TODO: Can we target this better? For now treat it like any other staging
113 // property push and just damage self before and after animators are run
114
115 mParent.damageSelf(info);
116 info.damageAccumulator->popTransform();
117
John Reck119907c2014-08-14 09:02:01 -0700118 uint32_t dirty = animateCommon(info);
John Reck68bfe0a2014-06-24 15:34:58 -0700119
John Reck68bfe0a2014-06-24 15:34:58 -0700120 info.damageAccumulator->pushTransform(&mParent);
121 mParent.damageSelf(info);
John Recka7c2ea22014-08-08 13:21:00 -0700122
John Reck119907c2014-08-14 09:02:01 -0700123 return dirty;
124}
125
126void AnimatorManager::animateNoDamage(TreeInfo& info) {
John Reck119907c2014-08-14 09:02:01 -0700127 animateCommon(info);
128}
129
130uint32_t AnimatorManager::animateCommon(TreeInfo& info) {
131 AnimateFunctor functor(info, mAnimationHandle->context());
John Recke03ef252016-02-11 17:02:33 +0000132 std::vector< BaseRenderNodeAnimator* >::iterator newEnd;
133 newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
John Reck119907c2014-08-14 09:02:01 -0700134 mAnimators.erase(newEnd, mAnimators.end());
135 mAnimationHandle->notifyAnimationsRan();
John Reck49dec432015-07-23 15:33:12 -0700136 mParent.mProperties.updateMatrix();
John Recka7c2ea22014-08-08 13:21:00 -0700137 return functor.dirtyMask;
John Reck68bfe0a2014-06-24 15:34:58 -0700138}
139
John Recke03ef252016-02-11 17:02:33 +0000140static void endStagingAnimator(BaseRenderNodeAnimator* animator) {
141 animator->end();
John Reck119907c2014-08-14 09:02:01 -0700142 if (animator->listener()) {
John Recke03ef252016-02-11 17:02:33 +0000143 animator->listener()->onAnimationFinished(animator);
John Reck119907c2014-08-14 09:02:01 -0700144 }
John Recke03ef252016-02-11 17:02:33 +0000145 animator->decStrong(nullptr);
John Reck119907c2014-08-14 09:02:01 -0700146}
147
John Recke2478d42014-09-03 16:46:05 -0700148void AnimatorManager::endAllStagingAnimators() {
149 ALOGD("endAllStagingAnimators on %p (%s)", &mParent, mParent.getName());
150 // This works because this state can only happen on the UI thread,
151 // which means we're already on the right thread to invoke listeners
152 for_each(mNewAnimators.begin(), mNewAnimators.end(), endStagingAnimator);
153 mNewAnimators.clear();
154}
155
156class EndActiveAnimatorsFunctor {
157public:
158 EndActiveAnimatorsFunctor(AnimationContext& context) : mContext(context) {}
159
John Recke03ef252016-02-11 17:02:33 +0000160 void operator() (BaseRenderNodeAnimator* animator) {
John Recke2478d42014-09-03 16:46:05 -0700161 animator->forceEndNow(mContext);
John Recke03ef252016-02-11 17:02:33 +0000162 animator->decStrong(nullptr);
John Reck119907c2014-08-14 09:02:01 -0700163 }
John Recke2478d42014-09-03 16:46:05 -0700164
165private:
166 AnimationContext& mContext;
167};
168
169void AnimatorManager::endAllActiveAnimators() {
Fred Fettinger2ccb5032015-07-01 16:43:48 -0500170 ALOGD("endAllActiveAnimators on %p (%s) with handle %p",
John Recke2478d42014-09-03 16:46:05 -0700171 &mParent, mParent.getName(), mAnimationHandle);
172 EndActiveAnimatorsFunctor functor(mAnimationHandle->context());
173 for_each(mAnimators.begin(), mAnimators.end(), functor);
174 mAnimators.clear();
175 mAnimationHandle->release();
John Reck119907c2014-08-14 09:02:01 -0700176}
177
John Reck68bfe0a2014-06-24 15:34:58 -0700178} /* namespace uirenderer */
179} /* namespace android */