Animator.h revision 718cd3eb70703c43f29ca37907bbf0e153d8cca0
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
27#include <vector>
28
29namespace android {
30namespace uirenderer {
31
32class AnimationContext;
33class BaseRenderNodeAnimator;
34class CanvasPropertyPrimitive;
35class CanvasPropertyPaint;
36class Interpolator;
37class RenderNode;
38class RenderProperties;
39
40class AnimationListener : public VirtualLightRefBase {
41public:
42    ANDROID_API virtual void onAnimationFinished(BaseRenderNodeAnimator*) = 0;
43protected:
44    ANDROID_API virtual ~AnimationListener() {}
45};
46
47class BaseRenderNodeAnimator : public VirtualLightRefBase {
48    PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator);
49public:
50    ANDROID_API void setStartValue(float value);
51    ANDROID_API void setInterpolator(Interpolator* interpolator);
52    ANDROID_API void setDuration(nsecs_t durationInMs);
53    ANDROID_API nsecs_t duration() { return mDuration; }
54    ANDROID_API void setStartDelay(nsecs_t startDelayInMs);
55    ANDROID_API nsecs_t startDelay() { return mStartDelay; }
56    ANDROID_API void setListener(AnimationListener* listener) {
57        mListener = listener;
58    }
59    AnimationListener* listener() { return mListener.get(); }
60    ANDROID_API void setAllowRunningAsync(bool mayRunAsync) {
61        mMayRunAsync = mayRunAsync;
62    }
63    bool mayRunAsync() { return mMayRunAsync; }
64    ANDROID_API void start();
65    ANDROID_API virtual void reset();
66    ANDROID_API void reverse();
67    // Terminates the animation at its current progress.
68    ANDROID_API void cancel();
69
70    // Terminates the animation and skip to the end of the animation.
71    ANDROID_API virtual void end();
72
73    void attach(RenderNode* target);
74    virtual void onAttached() {}
75    void detach() { mTarget = nullptr; }
76    ANDROID_API void pushStaging(AnimationContext& context);
77    ANDROID_API bool animate(AnimationContext& context);
78
79    // Returns the remaining time in ms for the animation. Note this should only be called during
80    // an animation on RenderThread.
81    ANDROID_API nsecs_t getRemainingPlayTime();
82
83    bool isRunning() { return mPlayState == PlayState::Running
84            || mPlayState == PlayState::Reversing; }
85    bool isFinished() { return mPlayState == PlayState::Finished; }
86    float finalValue() { return mFinalValue; }
87
88    ANDROID_API virtual uint32_t dirtyMask() = 0;
89
90    void forceEndNow(AnimationContext& context);
91    RenderNode* target() { return mTarget; }
92    RenderNode* stagingTarget() { return mStagingTarget; }
93
94protected:
95    // PlayState is used by mStagingPlayState and mPlayState to track the state initiated from UI
96    // thread and Render Thread animation state, respectively.
97    // From the UI thread, mStagingPlayState transition looks like
98    // NotStarted -> Running/Reversing -> Finished
99    //                ^                     |
100    //                |                     |
101    //                ----------------------
102    // Note: For mStagingState, the Finished state (optional) is only set when the animation is
103    // terminated by user.
104    //
105    // On Render Thread, mPlayState transition:
106    // NotStart -> Running/Reversing-> Finished
107    //                ^                 |
108    //                |                 |
109    //                ------------------
110    // Note that if the animation is in Running/Reversing state, calling start or reverse again
111    // would do nothing if the animation has the same play direction as the request; otherwise,
112    // the animation would start from where it is and change direction (i.e. Reversing <-> Running)
113
114    enum class PlayState {
115        NotStarted,
116        Running,
117        Reversing,
118        Finished,
119    };
120
121    BaseRenderNodeAnimator(float finalValue);
122    virtual ~BaseRenderNodeAnimator();
123
124    virtual float getValue(RenderNode* target) const = 0;
125    virtual void setValue(RenderNode* target, float value) = 0;
126
127    void callOnFinishedListener(AnimationContext& context);
128
129    virtual void onStagingPlayStateChanged() {}
130    virtual void onPlayTimeChanged(nsecs_t playTime) {}
131    virtual void onPushStaging() {}
132
133    RenderNode* mTarget;
134    RenderNode* mStagingTarget;
135
136    float mFinalValue;
137    float mDeltaValue;
138    float mFromValue;
139
140    std::unique_ptr<Interpolator> mInterpolator;
141    PlayState mStagingPlayState;
142    PlayState mPlayState;
143    bool mHasStartValue;
144    nsecs_t mStartTime;
145    nsecs_t mDuration;
146    nsecs_t mStartDelay;
147    bool mMayRunAsync;
148    // Play Time tracks the progress of animation, it should always be [0, mDuration], 0 being
149    // the beginning of the animation, will reach mDuration at the end of an animation.
150    nsecs_t mPlayTime;
151
152    sp<AnimationListener> mListener;
153
154private:
155    enum class Request {
156        Start,
157        Reverse,
158        Reset,
159        Cancel,
160        End
161    };
162    inline void checkMutable();
163    virtual void transitionToRunning(AnimationContext& context);
164    void doSetStartValue(float value);
165    bool updatePlayTime(nsecs_t playTime);
166    void resolveStagingRequest(Request request);
167
168    std::vector<Request> mStagingRequests;
169
170};
171
172class RenderPropertyAnimator : public BaseRenderNodeAnimator {
173public:
174    enum RenderProperty {
175        TRANSLATION_X = 0,
176        TRANSLATION_Y,
177        TRANSLATION_Z,
178        SCALE_X,
179        SCALE_Y,
180        ROTATION,
181        ROTATION_X,
182        ROTATION_Y,
183        X,
184        Y,
185        Z,
186        ALPHA,
187    };
188
189    ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue);
190
191    ANDROID_API virtual uint32_t dirtyMask();
192
193protected:
194    virtual float getValue(RenderNode* target) const override;
195    virtual void setValue(RenderNode* target, float value) override;
196    virtual void onAttached() override;
197    virtual void onStagingPlayStateChanged() override;
198    virtual void onPushStaging() override;
199
200private:
201    typedef bool (RenderProperties::*SetFloatProperty)(float value);
202    typedef float (RenderProperties::*GetFloatProperty)() const;
203
204    struct PropertyAccessors;
205    const PropertyAccessors* mPropertyAccess;
206
207    static const PropertyAccessors PROPERTY_ACCESSOR_LUT[];
208    bool mShouldSyncPropertyFields = false;
209    bool mShouldUpdateStagingProperties = false;
210};
211
212class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator {
213public:
214    ANDROID_API CanvasPropertyPrimitiveAnimator(CanvasPropertyPrimitive* property,
215            float finalValue);
216
217    ANDROID_API virtual uint32_t dirtyMask();
218
219protected:
220    virtual float getValue(RenderNode* target) const override;
221    virtual void setValue(RenderNode* target, float value) override;
222private:
223    sp<CanvasPropertyPrimitive> mProperty;
224};
225
226class CanvasPropertyPaintAnimator : public BaseRenderNodeAnimator {
227public:
228    enum PaintField {
229        STROKE_WIDTH = 0,
230        ALPHA,
231    };
232
233    ANDROID_API CanvasPropertyPaintAnimator(CanvasPropertyPaint* property,
234            PaintField field, float finalValue);
235
236    ANDROID_API virtual uint32_t dirtyMask();
237
238protected:
239    virtual float getValue(RenderNode* target) const override;
240    virtual void setValue(RenderNode* target, float value) override;
241private:
242    sp<CanvasPropertyPaint> mProperty;
243    PaintField mField;
244};
245
246class RevealAnimator : public BaseRenderNodeAnimator {
247public:
248    ANDROID_API RevealAnimator(int centerX, int centerY,
249            float startValue, float finalValue);
250
251    ANDROID_API virtual uint32_t dirtyMask();
252
253protected:
254    virtual float getValue(RenderNode* target) const override;
255    virtual void setValue(RenderNode* target, float value) override;
256
257private:
258    int mCenterX, mCenterY;
259};
260
261} /* namespace uirenderer */
262} /* namespace android */
263
264#endif /* ANIMATOR_H */
265