blob: ee16586e7366c3d576d0a7f076751e23c11f515e [file] [log] [blame]
John Recke45b1fd2014-04-15 09:50:16 -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
17#define LOG_TAG "RT-Animator"
18
19#include "Animator.h"
20
21#include <set>
22
23#include "RenderProperties.h"
24
25namespace android {
26namespace uirenderer {
27
28/************************************************************
29 * Private header
30 ************************************************************/
31
32typedef void (RenderProperties::*SetFloatProperty)(float value);
33typedef float (RenderProperties::*GetFloatProperty)() const;
34
35struct PropertyAccessors {
36 GetFloatProperty getter;
37 SetFloatProperty setter;
38};
39
40// Maps RenderProperty enum to accessors
41static const PropertyAccessors PROPERTY_ACCESSOR_LUT[] = {
42 {&RenderProperties::getTranslationX, &RenderProperties::setTranslationX },
43 {&RenderProperties::getTranslationY, &RenderProperties::setTranslationY },
44 {&RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ },
45 {&RenderProperties::getScaleX, &RenderProperties::setScaleX },
46 {&RenderProperties::getScaleY, &RenderProperties::setScaleY },
47 {&RenderProperties::getRotation, &RenderProperties::setRotation },
48 {&RenderProperties::getRotationX, &RenderProperties::setRotationX },
49 {&RenderProperties::getRotationY, &RenderProperties::setRotationY },
50 {&RenderProperties::getX, &RenderProperties::setX },
51 {&RenderProperties::getY, &RenderProperties::setY },
52 {&RenderProperties::getZ, &RenderProperties::setZ },
53 {&RenderProperties::getAlpha, &RenderProperties::setAlpha },
54};
55
56// Helper class to contain generic animator helpers
57class BaseAnimator {
58public:
59 BaseAnimator();
60 virtual ~BaseAnimator();
61
62 void setInterpolator(Interpolator* interpolator);
63 void setDuration(nsecs_t durationInMs);
64
65 bool isFinished() { return mPlayState == FINISHED; }
66
67protected:
68 // This is the main animation entrypoint that subclasses should call
69 // to generate the onAnimation* lifecycle events
70 // Returns true if the animation has finished, false otherwise
71 bool animateFrame(nsecs_t frameTime);
72
73 // Called when PlayState switches from PENDING to RUNNING
74 virtual void onAnimationStarted() {}
75 virtual void onAnimationUpdated(float fraction) = 0;
76 virtual void onAnimationFinished() {}
77
78private:
79 enum PlayState {
80 PENDING,
81 RUNNING,
82 FINISHED,
83 };
84
85 Interpolator* mInterpolator;
86 PlayState mPlayState;
87 long mStartTime;
88 long mDuration;
89};
90
91// Hide the base classes & private bits from the exported RenderPropertyAnimator
92// in this Impl class so that subclasses of RenderPropertyAnimator don't require
93// knowledge of the inner guts but only the public virtual methods.
94// Animates a single property
95class RenderPropertyAnimatorImpl : public BaseAnimator {
96public:
97 RenderPropertyAnimatorImpl(GetFloatProperty getter, SetFloatProperty setter,
98 RenderPropertyAnimator::DeltaValueType deltaType, float delta);
99 ~RenderPropertyAnimatorImpl();
100
101 bool animate(RenderProperties* target, TreeInfo& info);
102
103protected:
104 virtual void onAnimationStarted();
105 virtual void onAnimationUpdated(float fraction);
106
107private:
108 // mTarget is only valid inside animate()
109 RenderProperties* mTarget;
110 GetFloatProperty mGetter;
111 SetFloatProperty mSetter;
112
113 RenderPropertyAnimator::DeltaValueType mDeltaValueType;
114 float mDeltaValue;
115 float mFromValue;
116};
117
118RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property,
119 DeltaValueType deltaType, float deltaValue) {
120 PropertyAccessors pa = PROPERTY_ACCESSOR_LUT[property];
121 mImpl = new RenderPropertyAnimatorImpl(pa.getter, pa.setter, deltaType, deltaValue);
122}
123
124RenderPropertyAnimator::~RenderPropertyAnimator() {
125 delete mImpl;
126 mImpl = NULL;
127}
128
129void RenderPropertyAnimator::setInterpolator(Interpolator* interpolator) {
130 mImpl->setInterpolator(interpolator);
131}
132
133void RenderPropertyAnimator::setDuration(nsecs_t durationInMs) {
134 mImpl->setDuration(durationInMs);
135}
136
137bool RenderPropertyAnimator::isFinished() {
138 return mImpl->isFinished();
139}
140
141bool RenderPropertyAnimator::animate(RenderProperties* target, TreeInfo& info) {
142 return mImpl->animate(target, info);
143}
144
145
146/************************************************************
147 * Base animator
148 ************************************************************/
149
150BaseAnimator::BaseAnimator()
151 : mInterpolator(0)
152 , mPlayState(PENDING)
153 , mStartTime(0)
154 , mDuration(300) {
155
156}
157
158BaseAnimator::~BaseAnimator() {
159 setInterpolator(NULL);
160}
161
162void BaseAnimator::setInterpolator(Interpolator* interpolator) {
163 delete mInterpolator;
164 mInterpolator = interpolator;
165}
166
167void BaseAnimator::setDuration(nsecs_t duration) {
168 mDuration = duration;
169}
170
171bool BaseAnimator::animateFrame(nsecs_t frameTime) {
172 if (mPlayState == PENDING) {
173 mPlayState = RUNNING;
174 mStartTime = frameTime;
175 // No interpolator was set, use the default
176 if (!mInterpolator) {
177 setInterpolator(Interpolator::createDefaultInterpolator());
178 }
179 onAnimationStarted();
180 }
181
182 float fraction = 1.0f;
183 if (mPlayState == RUNNING) {
184 fraction = mDuration > 0 ? (float)(frameTime - mStartTime) / mDuration : 1.0f;
185 if (fraction >= 1.0f) {
186 fraction = 1.0f;
187 mPlayState = FINISHED;
188 }
189 }
190 fraction = mInterpolator->interpolate(fraction);
191 onAnimationUpdated(fraction);
192
193 if (mPlayState == FINISHED) {
194 onAnimationFinished();
195 return true;
196 }
197 return false;
198}
199
200/************************************************************
201 * RenderPropertyAnimator
202 ************************************************************/
203
204RenderPropertyAnimatorImpl::RenderPropertyAnimatorImpl(
205 GetFloatProperty getter, SetFloatProperty setter,
206 RenderPropertyAnimator::DeltaValueType deltaType, float delta)
207 : mTarget(0)
208 , mGetter(getter)
209 , mSetter(setter)
210 , mDeltaValueType(deltaType)
211 , mDeltaValue(delta)
212 , mFromValue(-1) {
213}
214
215RenderPropertyAnimatorImpl::~RenderPropertyAnimatorImpl() {
216}
217
218bool RenderPropertyAnimatorImpl::animate(RenderProperties* target, TreeInfo& info) {
219 mTarget = target;
220 bool finished = animateFrame(info.frameTimeMs);
221 mTarget = NULL;
222 return finished;
223}
224
225void RenderPropertyAnimatorImpl::onAnimationStarted() {
226 mFromValue = (mTarget->*mGetter)();
227
228 if (mDeltaValueType == RenderPropertyAnimator::ABSOLUTE) {
229 mDeltaValue = (mDeltaValue - mFromValue);
230 mDeltaValueType = RenderPropertyAnimator::DELTA;
231 }
232}
233
234void RenderPropertyAnimatorImpl::onAnimationUpdated(float fraction) {
235 float value = mFromValue + (mDeltaValue * fraction);
236 (mTarget->*mSetter)(value);
237}
238
239} /* namespace uirenderer */
240} /* namespace android */