blob: 78d569dfad2e4beca63bbec9a1d549d3b38cfba6 [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 Reck52244ff2014-05-01 21:27:37 -070022#include "RenderNode.h"
John Recke45b1fd2014-04-15 09:50:16 -070023#include "RenderProperties.h"
24
25namespace android {
26namespace uirenderer {
27
28/************************************************************
John Reckff941dc2014-05-14 16:34:14 -070029 * BaseRenderNodeAnimator
John Recke45b1fd2014-04-15 09:50:16 -070030 ************************************************************/
31
John Reckff941dc2014-05-14 16:34:14 -070032BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
John Reck8d8af3c2014-07-01 15:23:45 -070033 : mTarget(NULL)
34 , mFinalValue(finalValue)
John Reckff941dc2014-05-14 16:34:14 -070035 , mDeltaValue(0)
36 , mFromValue(0)
37 , mInterpolator(0)
John Reck68bfe0a2014-06-24 15:34:58 -070038 , mStagingPlayState(NOT_STARTED)
39 , mPlayState(NOT_STARTED)
40 , mHasStartValue(false)
John Recke45b1fd2014-04-15 09:50:16 -070041 , mStartTime(0)
Alan Viverettead2f8e32014-05-16 13:28:33 -070042 , mDuration(300)
43 , mStartDelay(0) {
John Recke45b1fd2014-04-15 09:50:16 -070044}
45
John Reckff941dc2014-05-14 16:34:14 -070046BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
John Reck68bfe0a2014-06-24 15:34:58 -070047 delete mInterpolator;
48}
49
50void BaseRenderNodeAnimator::checkMutable() {
51 // Should be impossible to hit as the Java-side also has guards for this
52 LOG_ALWAYS_FATAL_IF(mStagingPlayState != NOT_STARTED,
53 "Animator has already been started!");
John Recke45b1fd2014-04-15 09:50:16 -070054}
55
John Reckff941dc2014-05-14 16:34:14 -070056void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
John Reck68bfe0a2014-06-24 15:34:58 -070057 checkMutable();
John Recke45b1fd2014-04-15 09:50:16 -070058 delete mInterpolator;
59 mInterpolator = interpolator;
60}
61
John Reckff941dc2014-05-14 16:34:14 -070062void BaseRenderNodeAnimator::setStartValue(float value) {
John Reck68bfe0a2014-06-24 15:34:58 -070063 checkMutable();
64 doSetStartValue(value);
John Reckff941dc2014-05-14 16:34:14 -070065}
66
John Reck68bfe0a2014-06-24 15:34:58 -070067void BaseRenderNodeAnimator::doSetStartValue(float value) {
68 mFromValue = value;
69 mDeltaValue = (mFinalValue - mFromValue);
70 mHasStartValue = true;
John Reckff941dc2014-05-14 16:34:14 -070071}
72
Alan Viverettead2f8e32014-05-16 13:28:33 -070073void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
John Reck68bfe0a2014-06-24 15:34:58 -070074 checkMutable();
Alan Viverettead2f8e32014-05-16 13:28:33 -070075 mDuration = duration;
76}
77
78void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) {
John Reck68bfe0a2014-06-24 15:34:58 -070079 checkMutable();
Alan Viverettead2f8e32014-05-16 13:28:33 -070080 mStartDelay = startDelay;
81}
82
John Reck8d8af3c2014-07-01 15:23:45 -070083void BaseRenderNodeAnimator::attach(RenderNode* target) {
84 mTarget = target;
85 onAttached();
86}
87
88void BaseRenderNodeAnimator::pushStaging(TreeInfo& info) {
John Reck68bfe0a2014-06-24 15:34:58 -070089 if (!mHasStartValue) {
John Reck8d8af3c2014-07-01 15:23:45 -070090 doSetStartValue(getValue(mTarget));
Alan Viverettead2f8e32014-05-16 13:28:33 -070091 }
John Reck68bfe0a2014-06-24 15:34:58 -070092 if (mStagingPlayState > mPlayState) {
93 mPlayState = mStagingPlayState;
94 // Oh boy, we're starting! Man the battle stations!
95 if (mPlayState == RUNNING) {
96 transitionToRunning(info);
John Recke45b1fd2014-04-15 09:50:16 -070097 }
John Recke45b1fd2014-04-15 09:50:16 -070098 }
John Reck68bfe0a2014-06-24 15:34:58 -070099}
100
101void BaseRenderNodeAnimator::transitionToRunning(TreeInfo& info) {
102 LOG_ALWAYS_FATAL_IF(info.frameTimeMs <= 0, "%" PRId64 " isn't a real frame time!", info.frameTimeMs);
103 if (mStartDelay < 0 || mStartDelay > 50000) {
104 ALOGW("Your start delay is strange and confusing: %" PRId64, mStartDelay);
105 }
106 mStartTime = info.frameTimeMs + mStartDelay;
107 if (mStartTime < 0) {
108 ALOGW("Ended up with a really weird start time of %" PRId64
109 " with frame time %" PRId64 " and start delay %" PRId64,
110 mStartTime, info.frameTimeMs, mStartDelay);
111 // Set to 0 so that the animate() basically instantly finishes
112 mStartTime = 0;
113 }
114 // No interpolator was set, use the default
115 if (!mInterpolator) {
John Reck8d8af3c2014-07-01 15:23:45 -0700116 mInterpolator = Interpolator::createDefaultInterpolator();
John Reck68bfe0a2014-06-24 15:34:58 -0700117 }
118 if (mDuration < 0 || mDuration > 50000) {
119 ALOGW("Your duration is strange and confusing: %" PRId64, mDuration);
120 }
121}
122
John Reck8d8af3c2014-07-01 15:23:45 -0700123bool BaseRenderNodeAnimator::animate(TreeInfo& info) {
John Reck68bfe0a2014-06-24 15:34:58 -0700124 if (mPlayState < RUNNING) {
125 return false;
126 }
John Reck32fb6302014-07-07 09:50:32 -0700127 if (mPlayState == FINISHED) {
128 return true;
129 }
John Reck68bfe0a2014-06-24 15:34:58 -0700130
John Reck8d8af3c2014-07-01 15:23:45 -0700131 // If BaseRenderNodeAnimator is handling the delay (not typical), then
132 // because the staging properties reflect the final value, we always need
133 // to call setValue even if the animation isn't yet running or is still
134 // being delayed as we need to override the staging value
John Reck68bfe0a2014-06-24 15:34:58 -0700135 if (mStartTime > info.frameTimeMs) {
136 info.out.hasAnimations |= true;
John Reck8d8af3c2014-07-01 15:23:45 -0700137 setValue(mTarget, mFromValue);
John Reck68bfe0a2014-06-24 15:34:58 -0700138 return false;
139 }
John Recke45b1fd2014-04-15 09:50:16 -0700140
141 float fraction = 1.0f;
John Reck68bfe0a2014-06-24 15:34:58 -0700142 if (mPlayState == RUNNING && mDuration > 0) {
143 fraction = (float)(info.frameTimeMs - mStartTime) / mDuration;
John Recke45b1fd2014-04-15 09:50:16 -0700144 }
John Reck68bfe0a2014-06-24 15:34:58 -0700145 if (fraction >= 1.0f) {
146 fraction = 1.0f;
147 mPlayState = FINISHED;
148 }
149
John Recke45b1fd2014-04-15 09:50:16 -0700150 fraction = mInterpolator->interpolate(fraction);
John Reck8d8af3c2014-07-01 15:23:45 -0700151 setValue(mTarget, mFromValue + (mDeltaValue * fraction));
John Recke45b1fd2014-04-15 09:50:16 -0700152
153 if (mPlayState == FINISHED) {
John Reck52244ff2014-05-01 21:27:37 -0700154 callOnFinishedListener(info);
John Recke45b1fd2014-04-15 09:50:16 -0700155 return true;
156 }
John Reck68bfe0a2014-06-24 15:34:58 -0700157
158 info.out.hasAnimations |= true;
John Recke45b1fd2014-04-15 09:50:16 -0700159 return false;
160}
161
John Reckff941dc2014-05-14 16:34:14 -0700162void BaseRenderNodeAnimator::callOnFinishedListener(TreeInfo& info) {
John Reck52244ff2014-05-01 21:27:37 -0700163 if (mListener.get()) {
164 if (!info.animationHook) {
165 mListener->onAnimationFinished(this);
166 } else {
167 info.animationHook->callOnFinished(this, mListener.get());
168 }
169 }
170}
171
172/************************************************************
John Recke45b1fd2014-04-15 09:50:16 -0700173 * RenderPropertyAnimator
174 ************************************************************/
175
John Reckff941dc2014-05-14 16:34:14 -0700176struct RenderPropertyAnimator::PropertyAccessors {
177 RenderNode::DirtyPropertyMask dirtyMask;
178 GetFloatProperty getter;
179 SetFloatProperty setter;
John Reck52244ff2014-05-01 21:27:37 -0700180};
181
John Reckff941dc2014-05-14 16:34:14 -0700182// Maps RenderProperty enum to accessors
183const RenderPropertyAnimator::PropertyAccessors RenderPropertyAnimator::PROPERTY_ACCESSOR_LUT[] = {
184 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationX, &RenderProperties::setTranslationX },
185 {RenderNode::TRANSLATION_Y, &RenderProperties::getTranslationY, &RenderProperties::setTranslationY },
186 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ },
187 {RenderNode::SCALE_X, &RenderProperties::getScaleX, &RenderProperties::setScaleX },
188 {RenderNode::SCALE_Y, &RenderProperties::getScaleY, &RenderProperties::setScaleY },
189 {RenderNode::ROTATION, &RenderProperties::getRotation, &RenderProperties::setRotation },
190 {RenderNode::ROTATION_X, &RenderProperties::getRotationX, &RenderProperties::setRotationX },
191 {RenderNode::ROTATION_Y, &RenderProperties::getRotationY, &RenderProperties::setRotationY },
192 {RenderNode::X, &RenderProperties::getX, &RenderProperties::setX },
193 {RenderNode::Y, &RenderProperties::getY, &RenderProperties::setY },
194 {RenderNode::Z, &RenderProperties::getZ, &RenderProperties::setZ },
195 {RenderNode::ALPHA, &RenderProperties::getAlpha, &RenderProperties::setAlpha },
196};
197
198RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float finalValue)
199 : BaseRenderNodeAnimator(finalValue)
200 , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) {
John Recke45b1fd2014-04-15 09:50:16 -0700201}
202
John Reck8d8af3c2014-07-01 15:23:45 -0700203void RenderPropertyAnimator::onAttached() {
John Reck68bfe0a2014-06-24 15:34:58 -0700204 if (!mHasStartValue
John Reck8d8af3c2014-07-01 15:23:45 -0700205 && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
206 setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)());
John Reckff941dc2014-05-14 16:34:14 -0700207 }
John Reck8d8af3c2014-07-01 15:23:45 -0700208}
209
210void RenderPropertyAnimator::onStagingPlayStateChanged() {
211 if (mStagingPlayState == RUNNING) {
212 (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
John Reck32fb6302014-07-07 09:50:32 -0700213 } else if (mStagingPlayState == FINISHED) {
214 // We're being canceled, so make sure that whatever values the UI thread
215 // is observing for us is pushed over
216 mTarget->setPropertyFieldsDirty(dirtyMask());
John Reck8d8af3c2014-07-01 15:23:45 -0700217 }
John Recke45b1fd2014-04-15 09:50:16 -0700218}
219
John Reck22184722014-06-20 07:19:30 -0700220uint32_t RenderPropertyAnimator::dirtyMask() {
221 return mPropertyAccess->dirtyMask;
222}
223
John Reckff941dc2014-05-14 16:34:14 -0700224float RenderPropertyAnimator::getValue(RenderNode* target) const {
225 return (target->properties().*mPropertyAccess->getter)();
226}
227
228void RenderPropertyAnimator::setValue(RenderNode* target, float value) {
229 (target->animatorProperties().*mPropertyAccess->setter)(value);
John Recke45b1fd2014-04-15 09:50:16 -0700230}
231
John Reck52244ff2014-05-01 21:27:37 -0700232/************************************************************
233 * CanvasPropertyPrimitiveAnimator
234 ************************************************************/
John Recke45b1fd2014-04-15 09:50:16 -0700235
John Reck52244ff2014-05-01 21:27:37 -0700236CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700237 CanvasPropertyPrimitive* property, float finalValue)
238 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700239 , mProperty(property) {
240}
241
John Reckff941dc2014-05-14 16:34:14 -0700242float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700243 return mProperty->value;
244}
245
John Reckff941dc2014-05-14 16:34:14 -0700246void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700247 mProperty->value = value;
248}
249
John Recka7c2ea22014-08-08 13:21:00 -0700250uint32_t CanvasPropertyPrimitiveAnimator::dirtyMask() {
251 return RenderNode::DISPLAY_LIST;
252}
253
John Reck52244ff2014-05-01 21:27:37 -0700254/************************************************************
255 * CanvasPropertySkPaintAnimator
256 ************************************************************/
257
258CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700259 CanvasPropertyPaint* property, PaintField field, float finalValue)
260 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700261 , mProperty(property)
262 , mField(field) {
263}
264
John Reckff941dc2014-05-14 16:34:14 -0700265float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700266 switch (mField) {
267 case STROKE_WIDTH:
268 return mProperty->value.getStrokeWidth();
269 case ALPHA:
270 return mProperty->value.getAlpha();
John Recke45b1fd2014-04-15 09:50:16 -0700271 }
John Reck52244ff2014-05-01 21:27:37 -0700272 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
273 return -1;
John Recke45b1fd2014-04-15 09:50:16 -0700274}
275
John Reck531ee702014-05-13 10:06:08 -0700276static uint8_t to_uint8(float value) {
277 int c = (int) (value + .5f);
278 return static_cast<uint8_t>( c < 0 ? 0 : c > 255 ? 255 : c );
279}
280
John Reckff941dc2014-05-14 16:34:14 -0700281void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700282 switch (mField) {
283 case STROKE_WIDTH:
284 mProperty->value.setStrokeWidth(value);
285 return;
286 case ALPHA:
John Reck531ee702014-05-13 10:06:08 -0700287 mProperty->value.setAlpha(to_uint8(value));
John Reck52244ff2014-05-01 21:27:37 -0700288 return;
289 }
290 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
John Recke45b1fd2014-04-15 09:50:16 -0700291}
292
John Recka7c2ea22014-08-08 13:21:00 -0700293uint32_t CanvasPropertyPaintAnimator::dirtyMask() {
294 return RenderNode::DISPLAY_LIST;
295}
296
Chris Craikaf4d04c2014-07-29 12:50:14 -0700297RevealAnimator::RevealAnimator(int centerX, int centerY,
John Reckd3de42c2014-07-15 14:29:33 -0700298 float startValue, float finalValue)
299 : BaseRenderNodeAnimator(finalValue)
300 , mCenterX(centerX)
Chris Craikaf4d04c2014-07-29 12:50:14 -0700301 , mCenterY(centerY) {
John Reckd3de42c2014-07-15 14:29:33 -0700302 setStartValue(startValue);
303}
304
305float RevealAnimator::getValue(RenderNode* target) const {
Chris Craikaf4d04c2014-07-29 12:50:14 -0700306 return target->properties().getRevealClip().getRadius();
John Reckd3de42c2014-07-15 14:29:33 -0700307}
308
309void RevealAnimator::setValue(RenderNode* target, float value) {
Chris Craikaf4d04c2014-07-29 12:50:14 -0700310 target->animatorProperties().mutableRevealClip().set(true,
John Reckd3de42c2014-07-15 14:29:33 -0700311 mCenterX, mCenterY, value);
312}
313
John Recka7c2ea22014-08-08 13:21:00 -0700314uint32_t RevealAnimator::dirtyMask() {
315 return RenderNode::GENERIC;
316}
317
John Recke45b1fd2014-04-15 09:50:16 -0700318} /* namespace uirenderer */
319} /* namespace android */