blob: 1c697d5b8baef070506726d98436f0e937da8193 [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
John Recke45b1fd2014-04-15 09:50:16 -070017#include "Animator.h"
18
John Reck68bfe0a2014-06-24 15:34:58 -070019#include <inttypes.h>
John Recke45b1fd2014-04-15 09:50:16 -070020#include <set>
21
John Reck119907c2014-08-14 09:02:01 -070022#include "AnimationContext.h"
John Reck52244ff2014-05-01 21:27:37 -070023#include "RenderNode.h"
John Recke45b1fd2014-04-15 09:50:16 -070024#include "RenderProperties.h"
25
26namespace android {
27namespace uirenderer {
28
29/************************************************************
John Reckff941dc2014-05-14 16:34:14 -070030 * BaseRenderNodeAnimator
John Recke45b1fd2014-04-15 09:50:16 -070031 ************************************************************/
32
John Reckff941dc2014-05-14 16:34:14 -070033BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
John Reck8d8af3c2014-07-01 15:23:45 -070034 : mTarget(NULL)
35 , mFinalValue(finalValue)
John Reckff941dc2014-05-14 16:34:14 -070036 , mDeltaValue(0)
37 , mFromValue(0)
38 , mInterpolator(0)
John Reck68bfe0a2014-06-24 15:34:58 -070039 , mStagingPlayState(NOT_STARTED)
40 , mPlayState(NOT_STARTED)
41 , mHasStartValue(false)
John Recke45b1fd2014-04-15 09:50:16 -070042 , mStartTime(0)
Alan Viverettead2f8e32014-05-16 13:28:33 -070043 , mDuration(300)
44 , mStartDelay(0) {
John Recke45b1fd2014-04-15 09:50:16 -070045}
46
John Reckff941dc2014-05-14 16:34:14 -070047BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
John Reck68bfe0a2014-06-24 15:34:58 -070048 delete mInterpolator;
49}
50
51void BaseRenderNodeAnimator::checkMutable() {
52 // Should be impossible to hit as the Java-side also has guards for this
53 LOG_ALWAYS_FATAL_IF(mStagingPlayState != NOT_STARTED,
54 "Animator has already been started!");
John Recke45b1fd2014-04-15 09:50:16 -070055}
56
John Reckff941dc2014-05-14 16:34:14 -070057void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
John Reck68bfe0a2014-06-24 15:34:58 -070058 checkMutable();
John Recke45b1fd2014-04-15 09:50:16 -070059 delete mInterpolator;
60 mInterpolator = interpolator;
61}
62
John Reckff941dc2014-05-14 16:34:14 -070063void BaseRenderNodeAnimator::setStartValue(float value) {
John Reck68bfe0a2014-06-24 15:34:58 -070064 checkMutable();
65 doSetStartValue(value);
John Reckff941dc2014-05-14 16:34:14 -070066}
67
John Reck68bfe0a2014-06-24 15:34:58 -070068void BaseRenderNodeAnimator::doSetStartValue(float value) {
69 mFromValue = value;
70 mDeltaValue = (mFinalValue - mFromValue);
71 mHasStartValue = true;
John Reckff941dc2014-05-14 16:34:14 -070072}
73
Alan Viverettead2f8e32014-05-16 13:28:33 -070074void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
John Reck68bfe0a2014-06-24 15:34:58 -070075 checkMutable();
Alan Viverettead2f8e32014-05-16 13:28:33 -070076 mDuration = duration;
77}
78
79void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) {
John Reck68bfe0a2014-06-24 15:34:58 -070080 checkMutable();
Alan Viverettead2f8e32014-05-16 13:28:33 -070081 mStartDelay = startDelay;
82}
83
John Reck8d8af3c2014-07-01 15:23:45 -070084void BaseRenderNodeAnimator::attach(RenderNode* target) {
85 mTarget = target;
86 onAttached();
87}
88
John Reck119907c2014-08-14 09:02:01 -070089void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) {
John Reck68bfe0a2014-06-24 15:34:58 -070090 if (!mHasStartValue) {
John Reck8d8af3c2014-07-01 15:23:45 -070091 doSetStartValue(getValue(mTarget));
Alan Viverettead2f8e32014-05-16 13:28:33 -070092 }
John Reck68bfe0a2014-06-24 15:34:58 -070093 if (mStagingPlayState > mPlayState) {
94 mPlayState = mStagingPlayState;
95 // Oh boy, we're starting! Man the battle stations!
96 if (mPlayState == RUNNING) {
John Reck119907c2014-08-14 09:02:01 -070097 transitionToRunning(context);
John Recke45b1fd2014-04-15 09:50:16 -070098 }
John Recke45b1fd2014-04-15 09:50:16 -070099 }
John Reck68bfe0a2014-06-24 15:34:58 -0700100}
101
John Reck119907c2014-08-14 09:02:01 -0700102void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) {
103 nsecs_t frameTimeMs = context.frameTimeMs();
104 LOG_ALWAYS_FATAL_IF(frameTimeMs <= 0, "%" PRId64 " isn't a real frame time!", frameTimeMs);
John Reck68bfe0a2014-06-24 15:34:58 -0700105 if (mStartDelay < 0 || mStartDelay > 50000) {
106 ALOGW("Your start delay is strange and confusing: %" PRId64, mStartDelay);
107 }
John Reck119907c2014-08-14 09:02:01 -0700108 mStartTime = frameTimeMs + mStartDelay;
John Reck68bfe0a2014-06-24 15:34:58 -0700109 if (mStartTime < 0) {
110 ALOGW("Ended up with a really weird start time of %" PRId64
111 " with frame time %" PRId64 " and start delay %" PRId64,
John Reck119907c2014-08-14 09:02:01 -0700112 mStartTime, frameTimeMs, mStartDelay);
John Reck68bfe0a2014-06-24 15:34:58 -0700113 // Set to 0 so that the animate() basically instantly finishes
114 mStartTime = 0;
115 }
116 // No interpolator was set, use the default
117 if (!mInterpolator) {
John Reck8d8af3c2014-07-01 15:23:45 -0700118 mInterpolator = Interpolator::createDefaultInterpolator();
John Reck68bfe0a2014-06-24 15:34:58 -0700119 }
120 if (mDuration < 0 || mDuration > 50000) {
121 ALOGW("Your duration is strange and confusing: %" PRId64, mDuration);
122 }
123}
124
John Reck119907c2014-08-14 09:02:01 -0700125bool BaseRenderNodeAnimator::animate(AnimationContext& context) {
John Reck68bfe0a2014-06-24 15:34:58 -0700126 if (mPlayState < RUNNING) {
127 return false;
128 }
John Reck32fb6302014-07-07 09:50:32 -0700129 if (mPlayState == FINISHED) {
130 return true;
131 }
John Reck68bfe0a2014-06-24 15:34:58 -0700132
John Reck8d8af3c2014-07-01 15:23:45 -0700133 // If BaseRenderNodeAnimator is handling the delay (not typical), then
134 // because the staging properties reflect the final value, we always need
135 // to call setValue even if the animation isn't yet running or is still
136 // being delayed as we need to override the staging value
John Reck119907c2014-08-14 09:02:01 -0700137 if (mStartTime > context.frameTimeMs()) {
John Reck8d8af3c2014-07-01 15:23:45 -0700138 setValue(mTarget, mFromValue);
John Reck68bfe0a2014-06-24 15:34:58 -0700139 return false;
140 }
John Recke45b1fd2014-04-15 09:50:16 -0700141
142 float fraction = 1.0f;
John Reck68bfe0a2014-06-24 15:34:58 -0700143 if (mPlayState == RUNNING && mDuration > 0) {
John Reck119907c2014-08-14 09:02:01 -0700144 fraction = (float)(context.frameTimeMs() - mStartTime) / mDuration;
John Recke45b1fd2014-04-15 09:50:16 -0700145 }
John Reck68bfe0a2014-06-24 15:34:58 -0700146 if (fraction >= 1.0f) {
147 fraction = 1.0f;
148 mPlayState = FINISHED;
149 }
150
John Recke45b1fd2014-04-15 09:50:16 -0700151 fraction = mInterpolator->interpolate(fraction);
John Reck8d8af3c2014-07-01 15:23:45 -0700152 setValue(mTarget, mFromValue + (mDeltaValue * fraction));
John Recke45b1fd2014-04-15 09:50:16 -0700153
154 if (mPlayState == FINISHED) {
John Reck119907c2014-08-14 09:02:01 -0700155 callOnFinishedListener(context);
John Recke45b1fd2014-04-15 09:50:16 -0700156 return true;
157 }
John Reck68bfe0a2014-06-24 15:34:58 -0700158
John Recke45b1fd2014-04-15 09:50:16 -0700159 return false;
160}
161
John Reck119907c2014-08-14 09:02:01 -0700162void BaseRenderNodeAnimator::callOnFinishedListener(AnimationContext& context) {
John Reck52244ff2014-05-01 21:27:37 -0700163 if (mListener.get()) {
John Reck119907c2014-08-14 09:02:01 -0700164 context.callOnFinished(this, mListener.get());
John Reck52244ff2014-05-01 21:27:37 -0700165 }
166}
167
168/************************************************************
John Recke45b1fd2014-04-15 09:50:16 -0700169 * RenderPropertyAnimator
170 ************************************************************/
171
John Reckff941dc2014-05-14 16:34:14 -0700172struct RenderPropertyAnimator::PropertyAccessors {
173 RenderNode::DirtyPropertyMask dirtyMask;
174 GetFloatProperty getter;
175 SetFloatProperty setter;
John Reck52244ff2014-05-01 21:27:37 -0700176};
177
John Reckff941dc2014-05-14 16:34:14 -0700178// Maps RenderProperty enum to accessors
179const RenderPropertyAnimator::PropertyAccessors RenderPropertyAnimator::PROPERTY_ACCESSOR_LUT[] = {
180 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationX, &RenderProperties::setTranslationX },
181 {RenderNode::TRANSLATION_Y, &RenderProperties::getTranslationY, &RenderProperties::setTranslationY },
182 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ },
183 {RenderNode::SCALE_X, &RenderProperties::getScaleX, &RenderProperties::setScaleX },
184 {RenderNode::SCALE_Y, &RenderProperties::getScaleY, &RenderProperties::setScaleY },
185 {RenderNode::ROTATION, &RenderProperties::getRotation, &RenderProperties::setRotation },
186 {RenderNode::ROTATION_X, &RenderProperties::getRotationX, &RenderProperties::setRotationX },
187 {RenderNode::ROTATION_Y, &RenderProperties::getRotationY, &RenderProperties::setRotationY },
188 {RenderNode::X, &RenderProperties::getX, &RenderProperties::setX },
189 {RenderNode::Y, &RenderProperties::getY, &RenderProperties::setY },
190 {RenderNode::Z, &RenderProperties::getZ, &RenderProperties::setZ },
191 {RenderNode::ALPHA, &RenderProperties::getAlpha, &RenderProperties::setAlpha },
192};
193
194RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float finalValue)
195 : BaseRenderNodeAnimator(finalValue)
196 , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) {
John Recke45b1fd2014-04-15 09:50:16 -0700197}
198
John Reck8d8af3c2014-07-01 15:23:45 -0700199void RenderPropertyAnimator::onAttached() {
John Reck68bfe0a2014-06-24 15:34:58 -0700200 if (!mHasStartValue
John Reck8d8af3c2014-07-01 15:23:45 -0700201 && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
202 setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)());
John Reckff941dc2014-05-14 16:34:14 -0700203 }
John Reck8d8af3c2014-07-01 15:23:45 -0700204}
205
206void RenderPropertyAnimator::onStagingPlayStateChanged() {
207 if (mStagingPlayState == RUNNING) {
208 (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
John Reck32fb6302014-07-07 09:50:32 -0700209 } else if (mStagingPlayState == FINISHED) {
210 // We're being canceled, so make sure that whatever values the UI thread
211 // is observing for us is pushed over
212 mTarget->setPropertyFieldsDirty(dirtyMask());
John Reck8d8af3c2014-07-01 15:23:45 -0700213 }
John Recke45b1fd2014-04-15 09:50:16 -0700214}
215
John Reck22184722014-06-20 07:19:30 -0700216uint32_t RenderPropertyAnimator::dirtyMask() {
217 return mPropertyAccess->dirtyMask;
218}
219
John Reckff941dc2014-05-14 16:34:14 -0700220float RenderPropertyAnimator::getValue(RenderNode* target) const {
221 return (target->properties().*mPropertyAccess->getter)();
222}
223
224void RenderPropertyAnimator::setValue(RenderNode* target, float value) {
225 (target->animatorProperties().*mPropertyAccess->setter)(value);
John Recke45b1fd2014-04-15 09:50:16 -0700226}
227
John Reck52244ff2014-05-01 21:27:37 -0700228/************************************************************
229 * CanvasPropertyPrimitiveAnimator
230 ************************************************************/
John Recke45b1fd2014-04-15 09:50:16 -0700231
John Reck52244ff2014-05-01 21:27:37 -0700232CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700233 CanvasPropertyPrimitive* property, float finalValue)
234 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700235 , mProperty(property) {
236}
237
John Reckff941dc2014-05-14 16:34:14 -0700238float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700239 return mProperty->value;
240}
241
John Reckff941dc2014-05-14 16:34:14 -0700242void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700243 mProperty->value = value;
244}
245
John Recka7c2ea22014-08-08 13:21:00 -0700246uint32_t CanvasPropertyPrimitiveAnimator::dirtyMask() {
247 return RenderNode::DISPLAY_LIST;
248}
249
John Reck52244ff2014-05-01 21:27:37 -0700250/************************************************************
251 * CanvasPropertySkPaintAnimator
252 ************************************************************/
253
254CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700255 CanvasPropertyPaint* property, PaintField field, float finalValue)
256 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700257 , mProperty(property)
258 , mField(field) {
259}
260
John Reckff941dc2014-05-14 16:34:14 -0700261float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700262 switch (mField) {
263 case STROKE_WIDTH:
264 return mProperty->value.getStrokeWidth();
265 case ALPHA:
266 return mProperty->value.getAlpha();
John Recke45b1fd2014-04-15 09:50:16 -0700267 }
John Reck52244ff2014-05-01 21:27:37 -0700268 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
269 return -1;
John Recke45b1fd2014-04-15 09:50:16 -0700270}
271
John Reck531ee702014-05-13 10:06:08 -0700272static uint8_t to_uint8(float value) {
273 int c = (int) (value + .5f);
274 return static_cast<uint8_t>( c < 0 ? 0 : c > 255 ? 255 : c );
275}
276
John Reckff941dc2014-05-14 16:34:14 -0700277void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700278 switch (mField) {
279 case STROKE_WIDTH:
280 mProperty->value.setStrokeWidth(value);
281 return;
282 case ALPHA:
John Reck531ee702014-05-13 10:06:08 -0700283 mProperty->value.setAlpha(to_uint8(value));
John Reck52244ff2014-05-01 21:27:37 -0700284 return;
285 }
286 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
John Recke45b1fd2014-04-15 09:50:16 -0700287}
288
John Recka7c2ea22014-08-08 13:21:00 -0700289uint32_t CanvasPropertyPaintAnimator::dirtyMask() {
290 return RenderNode::DISPLAY_LIST;
291}
292
Chris Craikaf4d04c2014-07-29 12:50:14 -0700293RevealAnimator::RevealAnimator(int centerX, int centerY,
John Reckd3de42c2014-07-15 14:29:33 -0700294 float startValue, float finalValue)
295 : BaseRenderNodeAnimator(finalValue)
296 , mCenterX(centerX)
Chris Craikaf4d04c2014-07-29 12:50:14 -0700297 , mCenterY(centerY) {
John Reckd3de42c2014-07-15 14:29:33 -0700298 setStartValue(startValue);
299}
300
301float RevealAnimator::getValue(RenderNode* target) const {
Chris Craikaf4d04c2014-07-29 12:50:14 -0700302 return target->properties().getRevealClip().getRadius();
John Reckd3de42c2014-07-15 14:29:33 -0700303}
304
305void RevealAnimator::setValue(RenderNode* target, float value) {
Chris Craikaf4d04c2014-07-29 12:50:14 -0700306 target->animatorProperties().mutableRevealClip().set(true,
John Reckd3de42c2014-07-15 14:29:33 -0700307 mCenterX, mCenterY, value);
308}
309
John Recka7c2ea22014-08-08 13:21:00 -0700310uint32_t RevealAnimator::dirtyMask() {
311 return RenderNode::GENERIC;
312}
313
John Recke45b1fd2014-04-15 09:50:16 -0700314} /* namespace uirenderer */
315} /* namespace android */