Animator.h revision e03ef25a3e44ef5d495e366c30b9b5b69fc58194
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#ifndef ANIMATOR_H
17#define ANIMATOR_H
18
19#include <memory>
20#include <cutils/compiler.h>
21#include <utils/RefBase.h>
22#include <utils/StrongPointer.h>
23#include <utils/Timers.h>
24
25#include "utils/Macros.h"
26
27namespace android {
28namespace uirenderer {
29
30class AnimationContext;
31class BaseRenderNodeAnimator;
32class CanvasPropertyPrimitive;
33class CanvasPropertyPaint;
34class Interpolator;
35class RenderNode;
36class RenderProperties;
37
38class AnimationListener : public VirtualLightRefBase {
39public:
40    ANDROID_API virtual void onAnimationFinished(BaseRenderNodeAnimator*) = 0;
41protected:
42    ANDROID_API virtual ~AnimationListener() {}
43};
44
45class BaseRenderNodeAnimator : public VirtualLightRefBase {
46    PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator);
47public:
48    ANDROID_API void setStartValue(float value);
49    ANDROID_API void setInterpolator(Interpolator* interpolator);
50    ANDROID_API void setDuration(nsecs_t durationInMs);
51    ANDROID_API nsecs_t duration() { return mDuration; }
52    ANDROID_API void setStartDelay(nsecs_t startDelayInMs);
53    ANDROID_API nsecs_t startDelay() { return mStartDelay; }
54    ANDROID_API void setListener(AnimationListener* listener) {
55        mListener = listener;
56    }
57    AnimationListener* listener() { return mListener.get(); }
58    ANDROID_API void setAllowRunningAsync(bool mayRunAsync) {
59        mMayRunAsync = mayRunAsync;
60    }
61    bool mayRunAsync() { return mMayRunAsync; }
62    ANDROID_API void start() {
63        if (mStagingPlayState == PlayState::NotStarted) {
64            mStagingPlayState = PlayState::Running;
65        } else {
66            mStagingPlayState = PlayState::Restarted;
67        }
68        onStagingPlayStateChanged(); }
69    ANDROID_API void end() { mStagingPlayState = PlayState::Finished; onStagingPlayStateChanged(); }
70
71    void attach(RenderNode* target);
72    virtual void onAttached() {}
73    void detach() { mTarget = nullptr; }
74    void pushStaging(AnimationContext& context);
75    bool animate(AnimationContext& context);
76
77    bool isRunning() { return mPlayState == PlayState::Running; }
78    bool isFinished() { return mPlayState == PlayState::Finished; }
79    float finalValue() { return mFinalValue; }
80
81    ANDROID_API virtual uint32_t dirtyMask() = 0;
82
83    void forceEndNow(AnimationContext& context);
84
85protected:
86    // PlayState is used by mStagingPlayState and mPlayState to track the state initiated from UI
87    // thread and Render Thread animation state, respectively.
88    // From the UI thread, mStagingPlayState transition looks like
89    // NotStarted -> Running -> Finished
90    //                ^            |
91    //                |            |
92    //            Restarted <------
93    // Note: For mStagingState, the Finished state (optional) is only set when the animation is
94    // terminated by user.
95    //
96    // On Render Thread, mPlayState transition:
97    // NotStart -> Running -> Finished
98    //                ^            |
99    //                |            |
100    //                -------------
101
102    enum class PlayState {
103        NotStarted,
104        Running,
105        Finished,
106        Restarted,
107    };
108
109    BaseRenderNodeAnimator(float finalValue);
110    virtual ~BaseRenderNodeAnimator();
111
112    virtual float getValue(RenderNode* target) const = 0;
113    virtual void setValue(RenderNode* target, float value) = 0;
114    RenderNode* target() { return mTarget; }
115
116    void callOnFinishedListener(AnimationContext& context);
117
118    virtual void onStagingPlayStateChanged() {}
119    virtual void onPlayTimeChanged(nsecs_t playTime) {}
120
121    RenderNode* mTarget;
122
123    float mFinalValue;
124    float mDeltaValue;
125    float mFromValue;
126
127    std::unique_ptr<Interpolator> mInterpolator;
128    PlayState mStagingPlayState;
129    PlayState mPlayState;
130    bool mHasStartValue;
131    nsecs_t mStartTime;
132    nsecs_t mDuration;
133    nsecs_t mStartDelay;
134    bool mMayRunAsync;
135
136    sp<AnimationListener> mListener;
137
138private:
139    inline void checkMutable();
140    virtual void transitionToRunning(AnimationContext& context);
141    void doSetStartValue(float value);
142};
143
144class RenderPropertyAnimator : public BaseRenderNodeAnimator {
145public:
146    enum RenderProperty {
147        TRANSLATION_X = 0,
148        TRANSLATION_Y,
149        TRANSLATION_Z,
150        SCALE_X,
151        SCALE_Y,
152        ROTATION,
153        ROTATION_X,
154        ROTATION_Y,
155        X,
156        Y,
157        Z,
158        ALPHA,
159    };
160
161    ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue);
162
163    ANDROID_API virtual uint32_t dirtyMask();
164
165protected:
166    virtual float getValue(RenderNode* target) const override;
167    virtual void setValue(RenderNode* target, float value) override;
168    virtual void onAttached() override;
169    virtual void onStagingPlayStateChanged() override;
170
171private:
172    typedef bool (RenderProperties::*SetFloatProperty)(float value);
173    typedef float (RenderProperties::*GetFloatProperty)() const;
174
175    struct PropertyAccessors;
176    const PropertyAccessors* mPropertyAccess;
177
178    static const PropertyAccessors PROPERTY_ACCESSOR_LUT[];
179};
180
181class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator {
182public:
183    ANDROID_API CanvasPropertyPrimitiveAnimator(CanvasPropertyPrimitive* property,
184            float finalValue);
185
186    ANDROID_API virtual uint32_t dirtyMask();
187
188protected:
189    virtual float getValue(RenderNode* target) const override;
190    virtual void setValue(RenderNode* target, float value) override;
191private:
192    sp<CanvasPropertyPrimitive> mProperty;
193};
194
195class CanvasPropertyPaintAnimator : public BaseRenderNodeAnimator {
196public:
197    enum PaintField {
198        STROKE_WIDTH = 0,
199        ALPHA,
200    };
201
202    ANDROID_API CanvasPropertyPaintAnimator(CanvasPropertyPaint* property,
203            PaintField field, float finalValue);
204
205    ANDROID_API virtual uint32_t dirtyMask();
206
207protected:
208    virtual float getValue(RenderNode* target) const override;
209    virtual void setValue(RenderNode* target, float value) override;
210private:
211    sp<CanvasPropertyPaint> mProperty;
212    PaintField mField;
213};
214
215class RevealAnimator : public BaseRenderNodeAnimator {
216public:
217    ANDROID_API RevealAnimator(int centerX, int centerY,
218            float startValue, float finalValue);
219
220    ANDROID_API virtual uint32_t dirtyMask();
221
222protected:
223    virtual float getValue(RenderNode* target) const override;
224    virtual void setValue(RenderNode* target, float value) override;
225
226private:
227    int mCenterX, mCenterY;
228};
229
230} /* namespace uirenderer */
231} /* namespace android */
232
233#endif /* ANIMATOR_H */
234