blob: 83eedfb513b2a570137fd1ffda36caa16ac4b695 [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)
John Reckff941dc2014-05-14 16:34:14 -070040 , mDuration(300){
John Recke45b1fd2014-04-15 09:50:16 -070041}
42
John Reckff941dc2014-05-14 16:34:14 -070043BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
John Recke45b1fd2014-04-15 09:50:16 -070044 setInterpolator(NULL);
45}
46
John Reckff941dc2014-05-14 16:34:14 -070047void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
John Recke45b1fd2014-04-15 09:50:16 -070048 delete mInterpolator;
49 mInterpolator = interpolator;
50}
51
John Reckff941dc2014-05-14 16:34:14 -070052void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
John Recke45b1fd2014-04-15 09:50:16 -070053 mDuration = duration;
54}
55
John Reckff941dc2014-05-14 16:34:14 -070056void BaseRenderNodeAnimator::setStartValue(float value) {
57 LOG_ALWAYS_FATAL_IF(mPlayState != NEEDS_START,
58 "Cannot set the start value after the animator has started!");
59 mFromValue = value;
60 mDeltaValue = (mFinalValue - mFromValue);
61 mPlayState = PENDING;
62}
63
64void BaseRenderNodeAnimator::setupStartValueIfNecessary(RenderNode* target, TreeInfo& info) {
65 if (mPlayState == NEEDS_START) {
66 setStartValue(getValue(target));
67 mPlayState = PENDING;
68 }
69}
70
71bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
John Recke45b1fd2014-04-15 09:50:16 -070072 if (mPlayState == PENDING) {
73 mPlayState = RUNNING;
John Reck52244ff2014-05-01 21:27:37 -070074 mStartTime = info.frameTimeMs;
John Recke45b1fd2014-04-15 09:50:16 -070075 // No interpolator was set, use the default
76 if (!mInterpolator) {
77 setInterpolator(Interpolator::createDefaultInterpolator());
78 }
John Recke45b1fd2014-04-15 09:50:16 -070079 }
80
81 float fraction = 1.0f;
82 if (mPlayState == RUNNING) {
John Reck52244ff2014-05-01 21:27:37 -070083 fraction = mDuration > 0 ? (float)(info.frameTimeMs - mStartTime) / mDuration : 1.0f;
John Recke45b1fd2014-04-15 09:50:16 -070084 if (fraction >= 1.0f) {
85 fraction = 1.0f;
86 mPlayState = FINISHED;
87 }
88 }
89 fraction = mInterpolator->interpolate(fraction);
John Reckff941dc2014-05-14 16:34:14 -070090 setValue(target, mFromValue + (mDeltaValue * fraction));
John Recke45b1fd2014-04-15 09:50:16 -070091
92 if (mPlayState == FINISHED) {
John Reck52244ff2014-05-01 21:27:37 -070093 callOnFinishedListener(info);
John Recke45b1fd2014-04-15 09:50:16 -070094 return true;
95 }
96 return false;
97}
98
John Reckff941dc2014-05-14 16:34:14 -070099void BaseRenderNodeAnimator::callOnFinishedListener(TreeInfo& info) {
John Reck52244ff2014-05-01 21:27:37 -0700100 if (mListener.get()) {
101 if (!info.animationHook) {
102 mListener->onAnimationFinished(this);
103 } else {
104 info.animationHook->callOnFinished(this, mListener.get());
105 }
106 }
107}
108
109/************************************************************
John Recke45b1fd2014-04-15 09:50:16 -0700110 * RenderPropertyAnimator
111 ************************************************************/
112
John Reckff941dc2014-05-14 16:34:14 -0700113struct RenderPropertyAnimator::PropertyAccessors {
114 RenderNode::DirtyPropertyMask dirtyMask;
115 GetFloatProperty getter;
116 SetFloatProperty setter;
John Reck52244ff2014-05-01 21:27:37 -0700117};
118
John Reckff941dc2014-05-14 16:34:14 -0700119// Maps RenderProperty enum to accessors
120const RenderPropertyAnimator::PropertyAccessors RenderPropertyAnimator::PROPERTY_ACCESSOR_LUT[] = {
121 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationX, &RenderProperties::setTranslationX },
122 {RenderNode::TRANSLATION_Y, &RenderProperties::getTranslationY, &RenderProperties::setTranslationY },
123 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ },
124 {RenderNode::SCALE_X, &RenderProperties::getScaleX, &RenderProperties::setScaleX },
125 {RenderNode::SCALE_Y, &RenderProperties::getScaleY, &RenderProperties::setScaleY },
126 {RenderNode::ROTATION, &RenderProperties::getRotation, &RenderProperties::setRotation },
127 {RenderNode::ROTATION_X, &RenderProperties::getRotationX, &RenderProperties::setRotationX },
128 {RenderNode::ROTATION_Y, &RenderProperties::getRotationY, &RenderProperties::setRotationY },
129 {RenderNode::X, &RenderProperties::getX, &RenderProperties::setX },
130 {RenderNode::Y, &RenderProperties::getY, &RenderProperties::setY },
131 {RenderNode::Z, &RenderProperties::getZ, &RenderProperties::setZ },
132 {RenderNode::ALPHA, &RenderProperties::getAlpha, &RenderProperties::setAlpha },
133};
134
135RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float finalValue)
136 : BaseRenderNodeAnimator(finalValue)
137 , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) {
John Recke45b1fd2014-04-15 09:50:16 -0700138}
139
John Reckff941dc2014-05-14 16:34:14 -0700140void RenderPropertyAnimator::onAttached(RenderNode* target) {
141 if (target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
142 setStartValue((target->stagingProperties().*mPropertyAccess->getter)());
143 }
144 (target->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
John Recke45b1fd2014-04-15 09:50:16 -0700145}
146
John Reckff941dc2014-05-14 16:34:14 -0700147float RenderPropertyAnimator::getValue(RenderNode* target) const {
148 return (target->properties().*mPropertyAccess->getter)();
149}
150
151void RenderPropertyAnimator::setValue(RenderNode* target, float value) {
152 (target->animatorProperties().*mPropertyAccess->setter)(value);
John Recke45b1fd2014-04-15 09:50:16 -0700153}
154
John Reck52244ff2014-05-01 21:27:37 -0700155/************************************************************
156 * CanvasPropertyPrimitiveAnimator
157 ************************************************************/
John Recke45b1fd2014-04-15 09:50:16 -0700158
John Reck52244ff2014-05-01 21:27:37 -0700159CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700160 CanvasPropertyPrimitive* property, float finalValue)
161 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700162 , mProperty(property) {
163}
164
John Reckff941dc2014-05-14 16:34:14 -0700165float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700166 return mProperty->value;
167}
168
John Reckff941dc2014-05-14 16:34:14 -0700169void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700170 mProperty->value = value;
171}
172
173/************************************************************
174 * CanvasPropertySkPaintAnimator
175 ************************************************************/
176
177CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator(
John Reckff941dc2014-05-14 16:34:14 -0700178 CanvasPropertyPaint* property, PaintField field, float finalValue)
179 : BaseRenderNodeAnimator(finalValue)
John Reck52244ff2014-05-01 21:27:37 -0700180 , mProperty(property)
181 , mField(field) {
182}
183
John Reckff941dc2014-05-14 16:34:14 -0700184float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const {
John Reck52244ff2014-05-01 21:27:37 -0700185 switch (mField) {
186 case STROKE_WIDTH:
187 return mProperty->value.getStrokeWidth();
188 case ALPHA:
189 return mProperty->value.getAlpha();
John Recke45b1fd2014-04-15 09:50:16 -0700190 }
John Reck52244ff2014-05-01 21:27:37 -0700191 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
192 return -1;
John Recke45b1fd2014-04-15 09:50:16 -0700193}
194
John Reck531ee702014-05-13 10:06:08 -0700195static uint8_t to_uint8(float value) {
196 int c = (int) (value + .5f);
197 return static_cast<uint8_t>( c < 0 ? 0 : c > 255 ? 255 : c );
198}
199
John Reckff941dc2014-05-14 16:34:14 -0700200void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) {
John Reck52244ff2014-05-01 21:27:37 -0700201 switch (mField) {
202 case STROKE_WIDTH:
203 mProperty->value.setStrokeWidth(value);
204 return;
205 case ALPHA:
John Reck531ee702014-05-13 10:06:08 -0700206 mProperty->value.setAlpha(to_uint8(value));
John Reck52244ff2014-05-01 21:27:37 -0700207 return;
208 }
209 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
John Recke45b1fd2014-04-15 09:50:16 -0700210}
211
212} /* namespace uirenderer */
213} /* namespace android */