Animator.cpp revision ff941dcd815021bb20d6504eb486acb1e50592c3
1/*
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
23#include "RenderNode.h"
24#include "RenderProperties.h"
25
26namespace android {
27namespace uirenderer {
28
29/************************************************************
30 *  BaseRenderNodeAnimator
31 ************************************************************/
32
33BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
34        : mFinalValue(finalValue)
35        , mDeltaValue(0)
36        , mFromValue(0)
37        , mInterpolator(0)
38        , mPlayState(NEEDS_START)
39        , mStartTime(0)
40        , mDuration(300){
41}
42
43BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
44    setInterpolator(NULL);
45}
46
47void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
48    delete mInterpolator;
49    mInterpolator = interpolator;
50}
51
52void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
53    mDuration = duration;
54}
55
56void 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) {
72    if (mPlayState == PENDING) {
73        mPlayState = RUNNING;
74        mStartTime = info.frameTimeMs;
75        // No interpolator was set, use the default
76        if (!mInterpolator) {
77            setInterpolator(Interpolator::createDefaultInterpolator());
78        }
79    }
80
81    float fraction = 1.0f;
82    if (mPlayState == RUNNING) {
83        fraction = mDuration > 0 ? (float)(info.frameTimeMs - mStartTime) / mDuration : 1.0f;
84        if (fraction >= 1.0f) {
85            fraction = 1.0f;
86            mPlayState = FINISHED;
87        }
88    }
89    fraction = mInterpolator->interpolate(fraction);
90    setValue(target, mFromValue + (mDeltaValue * fraction));
91
92    if (mPlayState == FINISHED) {
93        callOnFinishedListener(info);
94        return true;
95    }
96    return false;
97}
98
99void BaseRenderNodeAnimator::callOnFinishedListener(TreeInfo& info) {
100    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/************************************************************
110 *  RenderPropertyAnimator
111 ************************************************************/
112
113struct RenderPropertyAnimator::PropertyAccessors {
114   RenderNode::DirtyPropertyMask dirtyMask;
115   GetFloatProperty getter;
116   SetFloatProperty setter;
117};
118
119// 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])) {
138}
139
140void RenderPropertyAnimator::onAttached(RenderNode* target) {
141    if (target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
142        setStartValue((target->stagingProperties().*mPropertyAccess->getter)());
143    }
144    (target->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
145}
146
147float 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);
153}
154
155/************************************************************
156 *  CanvasPropertyPrimitiveAnimator
157 ************************************************************/
158
159CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator(
160                CanvasPropertyPrimitive* property, float finalValue)
161        : BaseRenderNodeAnimator(finalValue)
162        , mProperty(property) {
163}
164
165float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const {
166    return mProperty->value;
167}
168
169void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) {
170    mProperty->value = value;
171}
172
173/************************************************************
174 *  CanvasPropertySkPaintAnimator
175 ************************************************************/
176
177CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator(
178                CanvasPropertyPaint* property, PaintField field, float finalValue)
179        : BaseRenderNodeAnimator(finalValue)
180        , mProperty(property)
181        , mField(field) {
182}
183
184float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const {
185    switch (mField) {
186    case STROKE_WIDTH:
187        return mProperty->value.getStrokeWidth();
188    case ALPHA:
189        return mProperty->value.getAlpha();
190    }
191    LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
192    return -1;
193}
194
195static 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
200void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) {
201    switch (mField) {
202    case STROKE_WIDTH:
203        mProperty->value.setStrokeWidth(value);
204        return;
205    case ALPHA:
206        mProperty->value.setAlpha(to_uint8(value));
207        return;
208    }
209    LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
210}
211
212} /* namespace uirenderer */
213} /* namespace android */
214