blob: dc6d8520597c6a249616f39851645388154ba1f9 [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
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)
34 : mFinalValue(finalValue)
35 , mDeltaValue(0)
36 , mFromValue(0)
37 , mInterpolator(0)
38 , mPlayState(NEEDS_START)
John Recke45b1fd2014-04-15 09:50:16 -070039 , mStartTime(0)
Alan Viverettead2f8e32014-05-16 13:28:33 -070040 , mDelayUntil(0)
41 , mDuration(300)
42 , mStartDelay(0) {
43
John Recke45b1fd2014-04-15 09:50:16 -070044}
45
John Reckff941dc2014-05-14 16:34:14 -070046BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
John Recke45b1fd2014-04-15 09:50:16 -070047 setInterpolator(NULL);
48}
49
John Reckff941dc2014-05-14 16:34:14 -070050void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
John Recke45b1fd2014-04-15 09:50:16 -070051 delete mInterpolator;
52 mInterpolator = interpolator;
53}
54
John Reckff941dc2014-05-14 16:34:14 -070055void BaseRenderNodeAnimator::setStartValue(float value) {
56 LOG_ALWAYS_FATAL_IF(mPlayState != NEEDS_START,
57 "Cannot set the start value after the animator has started!");
58 mFromValue = value;
59 mDeltaValue = (mFinalValue - mFromValue);
60 mPlayState = PENDING;
61}
62
63void BaseRenderNodeAnimator::setupStartValueIfNecessary(RenderNode* target, TreeInfo& info) {
64 if (mPlayState == NEEDS_START) {
65 setStartValue(getValue(target));
John Reckff941dc2014-05-14 16:34:14 -070066 }
67}
68
Alan Viverettead2f8e32014-05-16 13:28:33 -070069void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
70 mDuration = duration;
71}
72
73void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) {
74 mStartDelay = startDelay;
75}
76
John Reckff941dc2014-05-14 16:34:14 -070077bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
Alan Viverettead2f8e32014-05-16 13:28:33 -070078 if (mPlayState == PENDING && mStartDelay > 0 && mDelayUntil == 0) {
79 mDelayUntil = info.frameTimeMs + mStartDelay;
80 return false;
81 }
82
83 if (mDelayUntil > info.frameTimeMs) {
84 return false;
85 }
86
John Recke45b1fd2014-04-15 09:50:16 -070087 if (mPlayState == PENDING) {
88 mPlayState = RUNNING;
John Reck52244ff2014-05-01 21:27:37 -070089 mStartTime = info.frameTimeMs;
John Recke45b1fd2014-04-15 09:50:16 -070090 // No interpolator was set, use the default
91 if (!mInterpolator) {
92 setInterpolator(Interpolator::createDefaultInterpolator());
93 }
John Recke45b1fd2014-04-15 09:50:16 -070094 }
95
96 float fraction = 1.0f;
97 if (mPlayState == RUNNING) {
John Reck52244ff2014-05-01 21:27:37 -070098 fraction = mDuration > 0 ? (float)(info.frameTimeMs - mStartTime) / mDuration : 1.0f;
John Recke45b1fd2014-04-15 09:50:16 -070099 if (fraction >= 1.0f) {
100 fraction = 1.0f;
101 mPlayState = FINISHED;
102 }
103 }
104 fraction = mInterpolator->interpolate(fraction);
John Reckff941dc2014-05-14 16:34:14 -0700105 setValue(target, mFromValue + (mDeltaValue * fraction));
John Recke45b1fd2014-04-15 09:50:16 -0700106
107 if (mPlayState == FINISHED) {
John Reck52244ff2014-05-01 21:27:37 -0700108 callOnFinishedListener(info);
John Recke45b1fd2014-04-15 09:50:16 -0700109 return true;
110 }
111 return false;
112}
113
John Reckff941dc2014-05-14 16:34:14 -0700114void BaseRenderNodeAnimator::callOnFinishedListener(TreeInfo& info) {
John Reck52244ff2014-05-01 21:27:37 -0700115 if (mListener.get()) {
116 if (!info.animationHook) {
117 mListener->onAnimationFinished(this);
118 } else {
119 info.animationHook->callOnFinished(this, mListener.get());
120 }
121 }
122}
123
124/************************************************************
John Recke45b1fd2014-04-15 09:50:16 -0700125 * RenderPropertyAnimator
126 ************************************************************/
127
John Reckff941dc2014-05-14 16:34:14 -0700128struct RenderPropertyAnimator::PropertyAccessors {
129 RenderNode::DirtyPropertyMask dirtyMask;
130 GetFloatProperty getter;
131 SetFloatProperty setter;
John Reck52244ff2014-05-01 21:27:37 -0700132};
133
John Reckff941dc2014-05-14 16:34:14 -0700134// Maps RenderProperty enum to accessors
135const RenderPropertyAnimator::PropertyAccessors RenderPropertyAnimator::PROPERTY_ACCESSOR_LUT[] = {
136 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationX, &RenderProperties::setTranslationX },
137 {RenderNode::TRANSLATION_Y, &RenderProperties::getTranslationY, &RenderProperties::setTranslationY },
138 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ },
139 {RenderNode::SCALE_X, &RenderProperties::getScaleX, &RenderProperties::setScaleX },
140 {RenderNode::SCALE_Y, &RenderProperties::getScaleY, &RenderProperties::setScaleY },
141 {RenderNode::ROTATION, &RenderProperties::getRotation, &RenderProperties::setRotation },
142 {RenderNode::ROTATION_X, &RenderProperties::getRotationX, &RenderProperties::setRotationX },
143 {RenderNode::ROTATION_Y, &RenderProperties::getRotationY, &RenderProperties::setRotationY },
144 {RenderNode::X, &RenderProperties::getX, &RenderProperties::setX },
145 {RenderNode::Y, &RenderProperties::getY, &RenderProperties::setY },
146 {RenderNode::Z, &RenderProperties::getZ, &RenderProperties::setZ },
147 {RenderNode::ALPHA, &RenderProperties::getAlpha, &RenderProperties::setAlpha },
148};
149
150RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float finalValue)
151 : BaseRenderNodeAnimator(finalValue)
152 , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) {
John Recke45b1fd2014-04-15 09:50:16 -0700153}
154
John Reckff941dc2014-05-14 16:34:14 -0700155void RenderPropertyAnimator::onAttached(RenderNode* target) {
John Reckc6b32642014-06-02 11:00:09 -0700156 if (mPlayState == NEEDS_START
157 && target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
John Reckff941dc2014-05-14 16:34:14 -0700158 setStartValue((target->stagingProperties().*mPropertyAccess->getter)());
159 }
160 (target->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
John Recke45b1fd2014-04-15 09:50:16 -0700161}
162
John Reck22184722014-06-20 07:19:30 -0700163uint32_t RenderPropertyAnimator::dirtyMask() {
164 return mPropertyAccess->dirtyMask;
165}
166
John Reckff941dc2014-05-14 16:34:14 -0700167float RenderPropertyAnimator::getValue(RenderNode* target) const {
168 return (target->properties().*mPropertyAccess->getter)();
169}
170
171void RenderPropertyAnimator::setValue(RenderNode* target, float value) {
172 (target->animatorProperties().*mPropertyAccess->setter)(value);
John Recke45b1fd2014-04-15 09:50:16 -0700173}
174
John Reck52244ff2014-05-01 21:27:37 -0700175/************************************************************
176 * CanvasPropertyPrimitiveAnimator
177 ************************************************************/
John Recke45b1fd2014-04-15 09:50:16 -0700178
John Reck52244ff2014-05-01 21:27:37 -0700179CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700180 CanvasPropertyPrimitive* property, float finalValue)
181 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700182 , mProperty(property) {
183}
184
John Reckff941dc2014-05-14 16:34:14 -0700185float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700186 return mProperty->value;
187}
188
John Reckff941dc2014-05-14 16:34:14 -0700189void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700190 mProperty->value = value;
191}
192
193/************************************************************
194 * CanvasPropertySkPaintAnimator
195 ************************************************************/
196
197CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700198 CanvasPropertyPaint* property, PaintField field, float finalValue)
199 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700200 , mProperty(property)
201 , mField(field) {
202}
203
John Reckff941dc2014-05-14 16:34:14 -0700204float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700205 switch (mField) {
206 case STROKE_WIDTH:
207 return mProperty->value.getStrokeWidth();
208 case ALPHA:
209 return mProperty->value.getAlpha();
John Recke45b1fd2014-04-15 09:50:16 -0700210 }
John Reck52244ff2014-05-01 21:27:37 -0700211 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
212 return -1;
John Recke45b1fd2014-04-15 09:50:16 -0700213}
214
John Reck531ee702014-05-13 10:06:08 -0700215static uint8_t to_uint8(float value) {
216 int c = (int) (value + .5f);
217 return static_cast<uint8_t>( c < 0 ? 0 : c > 255 ? 255 : c );
218}
219
John Reckff941dc2014-05-14 16:34:14 -0700220void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700221 switch (mField) {
222 case STROKE_WIDTH:
223 mProperty->value.setStrokeWidth(value);
224 return;
225 case ALPHA:
John Reck531ee702014-05-13 10:06:08 -0700226 mProperty->value.setAlpha(to_uint8(value));
John Reck52244ff2014-05-01 21:27:37 -0700227 return;
228 }
229 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
John Recke45b1fd2014-04-15 09:50:16 -0700230}
231
232} /* namespace uirenderer */
233} /* namespace android */