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