blob: f3ef48b18edb23b11e3e20a52b510f722226efe4 [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
John Reck68bfe0a2014-06-24 15:34:58 -070021#include <inttypes.h>
John Recke45b1fd2014-04-15 09:50:16 -070022#include <set>
23
John Reck52244ff2014-05-01 21:27:37 -070024#include "RenderNode.h"
John Recke45b1fd2014-04-15 09:50:16 -070025#include "RenderProperties.h"
26
27namespace android {
28namespace uirenderer {
29
30/************************************************************
John Reckff941dc2014-05-14 16:34:14 -070031 * BaseRenderNodeAnimator
John Recke45b1fd2014-04-15 09:50:16 -070032 ************************************************************/
33
John Reckff941dc2014-05-14 16:34:14 -070034BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
John Reck8d8af3c2014-07-01 15:23:45 -070035 : mTarget(NULL)
36 , mFinalValue(finalValue)
John Reckff941dc2014-05-14 16:34:14 -070037 , mDeltaValue(0)
38 , mFromValue(0)
39 , mInterpolator(0)
John Reck68bfe0a2014-06-24 15:34:58 -070040 , mStagingPlayState(NOT_STARTED)
41 , mPlayState(NOT_STARTED)
42 , mHasStartValue(false)
John Recke45b1fd2014-04-15 09:50:16 -070043 , mStartTime(0)
Alan Viverettead2f8e32014-05-16 13:28:33 -070044 , mDuration(300)
45 , mStartDelay(0) {
John Recke45b1fd2014-04-15 09:50:16 -070046}
47
John Reckff941dc2014-05-14 16:34:14 -070048BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
John Reck68bfe0a2014-06-24 15:34:58 -070049 delete mInterpolator;
50}
51
52void BaseRenderNodeAnimator::checkMutable() {
53 // Should be impossible to hit as the Java-side also has guards for this
54 LOG_ALWAYS_FATAL_IF(mStagingPlayState != NOT_STARTED,
55 "Animator has already been started!");
John Recke45b1fd2014-04-15 09:50:16 -070056}
57
John Reckff941dc2014-05-14 16:34:14 -070058void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
John Reck68bfe0a2014-06-24 15:34:58 -070059 checkMutable();
John Recke45b1fd2014-04-15 09:50:16 -070060 delete mInterpolator;
61 mInterpolator = interpolator;
62}
63
John Reckff941dc2014-05-14 16:34:14 -070064void BaseRenderNodeAnimator::setStartValue(float value) {
John Reck68bfe0a2014-06-24 15:34:58 -070065 checkMutable();
66 doSetStartValue(value);
John Reckff941dc2014-05-14 16:34:14 -070067}
68
John Reck68bfe0a2014-06-24 15:34:58 -070069void BaseRenderNodeAnimator::doSetStartValue(float value) {
70 mFromValue = value;
71 mDeltaValue = (mFinalValue - mFromValue);
72 mHasStartValue = true;
John Reckff941dc2014-05-14 16:34:14 -070073}
74
Alan Viverettead2f8e32014-05-16 13:28:33 -070075void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
John Reck68bfe0a2014-06-24 15:34:58 -070076 checkMutable();
Alan Viverettead2f8e32014-05-16 13:28:33 -070077 mDuration = duration;
78}
79
80void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) {
John Reck68bfe0a2014-06-24 15:34:58 -070081 checkMutable();
Alan Viverettead2f8e32014-05-16 13:28:33 -070082 mStartDelay = startDelay;
83}
84
John Reck8d8af3c2014-07-01 15:23:45 -070085void BaseRenderNodeAnimator::attach(RenderNode* target) {
86 mTarget = target;
87 onAttached();
88}
89
90void BaseRenderNodeAnimator::pushStaging(TreeInfo& info) {
John Reck68bfe0a2014-06-24 15:34:58 -070091 if (!mHasStartValue) {
John Reck8d8af3c2014-07-01 15:23:45 -070092 doSetStartValue(getValue(mTarget));
Alan Viverettead2f8e32014-05-16 13:28:33 -070093 }
John Reck68bfe0a2014-06-24 15:34:58 -070094 if (mStagingPlayState > mPlayState) {
95 mPlayState = mStagingPlayState;
96 // Oh boy, we're starting! Man the battle stations!
97 if (mPlayState == RUNNING) {
98 transitionToRunning(info);
John Recke45b1fd2014-04-15 09:50:16 -070099 }
John Recke45b1fd2014-04-15 09:50:16 -0700100 }
John Reck68bfe0a2014-06-24 15:34:58 -0700101}
102
103void BaseRenderNodeAnimator::transitionToRunning(TreeInfo& info) {
104 LOG_ALWAYS_FATAL_IF(info.frameTimeMs <= 0, "%" PRId64 " isn't a real frame time!", info.frameTimeMs);
105 if (mStartDelay < 0 || mStartDelay > 50000) {
106 ALOGW("Your start delay is strange and confusing: %" PRId64, mStartDelay);
107 }
108 mStartTime = info.frameTimeMs + mStartDelay;
109 if (mStartTime < 0) {
110 ALOGW("Ended up with a really weird start time of %" PRId64
111 " with frame time %" PRId64 " and start delay %" PRId64,
112 mStartTime, info.frameTimeMs, mStartDelay);
113 // 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 Reck8d8af3c2014-07-01 15:23:45 -0700125bool BaseRenderNodeAnimator::animate(TreeInfo& info) {
John Reck68bfe0a2014-06-24 15:34:58 -0700126 if (mPlayState < RUNNING) {
127 return false;
128 }
129
John Reck8d8af3c2014-07-01 15:23:45 -0700130 // If BaseRenderNodeAnimator is handling the delay (not typical), then
131 // because the staging properties reflect the final value, we always need
132 // to call setValue even if the animation isn't yet running or is still
133 // being delayed as we need to override the staging value
John Reck68bfe0a2014-06-24 15:34:58 -0700134 if (mStartTime > info.frameTimeMs) {
135 info.out.hasAnimations |= true;
John Reck8d8af3c2014-07-01 15:23:45 -0700136 setValue(mTarget, mFromValue);
John Reck68bfe0a2014-06-24 15:34:58 -0700137 return false;
138 }
John Recke45b1fd2014-04-15 09:50:16 -0700139
140 float fraction = 1.0f;
John Reck68bfe0a2014-06-24 15:34:58 -0700141 if (mPlayState == RUNNING && mDuration > 0) {
142 fraction = (float)(info.frameTimeMs - mStartTime) / mDuration;
John Recke45b1fd2014-04-15 09:50:16 -0700143 }
John Reck68bfe0a2014-06-24 15:34:58 -0700144 if (fraction >= 1.0f) {
145 fraction = 1.0f;
146 mPlayState = FINISHED;
147 }
148
John Recke45b1fd2014-04-15 09:50:16 -0700149 fraction = mInterpolator->interpolate(fraction);
John Reck8d8af3c2014-07-01 15:23:45 -0700150 setValue(mTarget, mFromValue + (mDeltaValue * fraction));
John Recke45b1fd2014-04-15 09:50:16 -0700151
152 if (mPlayState == FINISHED) {
John Reck52244ff2014-05-01 21:27:37 -0700153 callOnFinishedListener(info);
John Recke45b1fd2014-04-15 09:50:16 -0700154 return true;
155 }
John Reck68bfe0a2014-06-24 15:34:58 -0700156
157 info.out.hasAnimations |= true;
John Recke45b1fd2014-04-15 09:50:16 -0700158 return false;
159}
160
John Reckff941dc2014-05-14 16:34:14 -0700161void BaseRenderNodeAnimator::callOnFinishedListener(TreeInfo& info) {
John Reck52244ff2014-05-01 21:27:37 -0700162 if (mListener.get()) {
163 if (!info.animationHook) {
164 mListener->onAnimationFinished(this);
165 } else {
166 info.animationHook->callOnFinished(this, mListener.get());
167 }
168 }
169}
170
171/************************************************************
John Recke45b1fd2014-04-15 09:50:16 -0700172 * RenderPropertyAnimator
173 ************************************************************/
174
John Reckff941dc2014-05-14 16:34:14 -0700175struct RenderPropertyAnimator::PropertyAccessors {
176 RenderNode::DirtyPropertyMask dirtyMask;
177 GetFloatProperty getter;
178 SetFloatProperty setter;
John Reck52244ff2014-05-01 21:27:37 -0700179};
180
John Reckff941dc2014-05-14 16:34:14 -0700181// Maps RenderProperty enum to accessors
182const RenderPropertyAnimator::PropertyAccessors RenderPropertyAnimator::PROPERTY_ACCESSOR_LUT[] = {
183 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationX, &RenderProperties::setTranslationX },
184 {RenderNode::TRANSLATION_Y, &RenderProperties::getTranslationY, &RenderProperties::setTranslationY },
185 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ },
186 {RenderNode::SCALE_X, &RenderProperties::getScaleX, &RenderProperties::setScaleX },
187 {RenderNode::SCALE_Y, &RenderProperties::getScaleY, &RenderProperties::setScaleY },
188 {RenderNode::ROTATION, &RenderProperties::getRotation, &RenderProperties::setRotation },
189 {RenderNode::ROTATION_X, &RenderProperties::getRotationX, &RenderProperties::setRotationX },
190 {RenderNode::ROTATION_Y, &RenderProperties::getRotationY, &RenderProperties::setRotationY },
191 {RenderNode::X, &RenderProperties::getX, &RenderProperties::setX },
192 {RenderNode::Y, &RenderProperties::getY, &RenderProperties::setY },
193 {RenderNode::Z, &RenderProperties::getZ, &RenderProperties::setZ },
194 {RenderNode::ALPHA, &RenderProperties::getAlpha, &RenderProperties::setAlpha },
195};
196
197RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float finalValue)
198 : BaseRenderNodeAnimator(finalValue)
199 , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) {
John Recke45b1fd2014-04-15 09:50:16 -0700200}
201
John Reck8d8af3c2014-07-01 15:23:45 -0700202void RenderPropertyAnimator::onAttached() {
John Reck68bfe0a2014-06-24 15:34:58 -0700203 if (!mHasStartValue
John Reck8d8af3c2014-07-01 15:23:45 -0700204 && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
205 setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)());
John Reckff941dc2014-05-14 16:34:14 -0700206 }
John Reck8d8af3c2014-07-01 15:23:45 -0700207}
208
209void RenderPropertyAnimator::onStagingPlayStateChanged() {
210 if (mStagingPlayState == RUNNING) {
211 (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
212 }
John Recke45b1fd2014-04-15 09:50:16 -0700213}
214
John Reck22184722014-06-20 07:19:30 -0700215uint32_t RenderPropertyAnimator::dirtyMask() {
216 return mPropertyAccess->dirtyMask;
217}
218
John Reckff941dc2014-05-14 16:34:14 -0700219float RenderPropertyAnimator::getValue(RenderNode* target) const {
220 return (target->properties().*mPropertyAccess->getter)();
221}
222
223void RenderPropertyAnimator::setValue(RenderNode* target, float value) {
224 (target->animatorProperties().*mPropertyAccess->setter)(value);
John Recke45b1fd2014-04-15 09:50:16 -0700225}
226
John Reck52244ff2014-05-01 21:27:37 -0700227/************************************************************
228 * CanvasPropertyPrimitiveAnimator
229 ************************************************************/
John Recke45b1fd2014-04-15 09:50:16 -0700230
John Reck52244ff2014-05-01 21:27:37 -0700231CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700232 CanvasPropertyPrimitive* property, float finalValue)
233 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700234 , mProperty(property) {
235}
236
John Reckff941dc2014-05-14 16:34:14 -0700237float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700238 return mProperty->value;
239}
240
John Reckff941dc2014-05-14 16:34:14 -0700241void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700242 mProperty->value = value;
243}
244
245/************************************************************
246 * CanvasPropertySkPaintAnimator
247 ************************************************************/
248
249CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700250 CanvasPropertyPaint* property, PaintField field, float finalValue)
251 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700252 , mProperty(property)
253 , mField(field) {
254}
255
John Reckff941dc2014-05-14 16:34:14 -0700256float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700257 switch (mField) {
258 case STROKE_WIDTH:
259 return mProperty->value.getStrokeWidth();
260 case ALPHA:
261 return mProperty->value.getAlpha();
John Recke45b1fd2014-04-15 09:50:16 -0700262 }
John Reck52244ff2014-05-01 21:27:37 -0700263 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
264 return -1;
John Recke45b1fd2014-04-15 09:50:16 -0700265}
266
John Reck531ee702014-05-13 10:06:08 -0700267static uint8_t to_uint8(float value) {
268 int c = (int) (value + .5f);
269 return static_cast<uint8_t>( c < 0 ? 0 : c > 255 ? 255 : c );
270}
271
John Reckff941dc2014-05-14 16:34:14 -0700272void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700273 switch (mField) {
274 case STROKE_WIDTH:
275 mProperty->value.setStrokeWidth(value);
276 return;
277 case ALPHA:
John Reck531ee702014-05-13 10:06:08 -0700278 mProperty->value.setAlpha(to_uint8(value));
John Reck52244ff2014-05-01 21:27:37 -0700279 return;
280 }
281 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
John Recke45b1fd2014-04-15 09:50:16 -0700282}
283
284} /* namespace uirenderer */
285} /* namespace android */