• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "animation/rs_render_animation.h"
17 
18 #include "pipeline/rs_canvas_render_node.h"
19 #include "platform/common/rs_log.h"
20 
21 namespace OHOS {
22 namespace Rosen {
RSRenderAnimation(AnimationId id)23 RSRenderAnimation::RSRenderAnimation(AnimationId id) : id_(id) {}
Marshalling(Parcel & parcel) const24 bool RSRenderAnimation::Marshalling(Parcel& parcel) const
25 {
26     // animationId, targetId
27     if (!(parcel.WriteUint64(id_))) {
28         ROSEN_LOGE("RSRenderAnimation::Marshalling, write id failed");
29         return false;
30     }
31     // RSAnimationTimingProtocol
32     if (!(parcel.WriteInt32(animationFraction_.GetDuration()) &&
33         parcel.WriteInt32(animationFraction_.GetStartDelay()) &&
34         parcel.WriteFloat(animationFraction_.GetSpeed()) &&
35         parcel.WriteInt32(animationFraction_.GetRepeatCount()) &&
36         parcel.WriteBool(animationFraction_.GetAutoReverse()) &&
37         parcel.WriteBool(animationFraction_.GetDirection()) &&
38         parcel.WriteInt32(static_cast<std::underlying_type<FillMode>::type>(animationFraction_.GetFillMode())))) {
39         ROSEN_LOGE("RSRenderAnimation::Marshalling, write param failed");
40         return false;
41     }
42     return true;
43 }
44 
ParseParam(Parcel & parcel)45 bool RSRenderAnimation::ParseParam(Parcel& parcel)
46 {
47     int32_t duration = 0;
48     int32_t startDelay = 0;
49     int32_t repeatCount = 0;
50     int32_t fillMode = 0;
51     float speed = 0.0;
52     bool autoReverse = false;
53     bool direction = false;
54     if (!(parcel.ReadUint64(id_) && parcel.ReadInt32(duration) && parcel.ReadInt32(startDelay) &&
55             parcel.ReadFloat(speed) && parcel.ReadInt32(repeatCount) && parcel.ReadBool(autoReverse) &&
56             parcel.ReadBool(direction) && parcel.ReadInt32(fillMode))) {
57         ROSEN_LOGE("RSRenderAnimation::ParseParam, read param failed");
58         return false;
59     }
60     SetDuration(duration);
61     SetStartDelay(startDelay);
62     SetRepeatCount(repeatCount);
63     SetAutoReverse(autoReverse);
64     SetSpeed(speed);
65     SetDirection(direction);
66     SetFillMode(static_cast<FillMode>(fillMode));
67     return true;
68 }
GetAnimationId() const69 AnimationId RSRenderAnimation::GetAnimationId() const
70 {
71     return id_;
72 }
73 
IsStarted() const74 bool RSRenderAnimation::IsStarted() const
75 {
76     return state_ != AnimationState::INITIALIZED;
77 }
78 
IsRunning() const79 bool RSRenderAnimation::IsRunning() const
80 {
81     return state_ == AnimationState::RUNNING;
82 }
83 
IsPaused() const84 bool RSRenderAnimation::IsPaused() const
85 {
86     return state_ == AnimationState::PAUSED;
87 }
88 
IsFinished() const89 bool RSRenderAnimation::IsFinished() const
90 {
91     return state_ == AnimationState::FINISHED;
92 }
93 
GetPropertyId() const94 PropertyId RSRenderAnimation::GetPropertyId() const
95 {
96     return 0;
97 }
98 
Attach(RSRenderNode * renderNode)99 void RSRenderAnimation::Attach(RSRenderNode* renderNode)
100 {
101     if (target_ != nullptr) {
102         Detach();
103     }
104     target_ = renderNode;
105     if (target_ != nullptr) {
106         targetId_ = target_->GetId();
107     }
108     OnAttach();
109     Start();
110     needUpdateStartTime_ = false;
111 }
112 
Detach()113 void RSRenderAnimation::Detach()
114 {
115     OnDetach();
116     target_ = nullptr;
117 }
118 
GetTargetId() const119 NodeId RSRenderAnimation::GetTargetId() const
120 {
121     return targetId_;
122 }
123 
Start()124 void RSRenderAnimation::Start()
125 {
126     if (IsStarted()) {
127         ROSEN_LOGE("Failed to start animation, animation has started!");
128         return;
129     }
130 
131     state_ = AnimationState::RUNNING;
132     needUpdateStartTime_ = true;
133     ProcessFillModeOnStart(animationFraction_.GetStartFraction());
134 }
135 
Finish()136 void RSRenderAnimation::Finish()
137 {
138     if (!IsPaused() && !IsRunning()) {
139         ROSEN_LOGE("Failed to finish animation, animation is not running!");
140         return;
141     }
142 
143     state_ = AnimationState::FINISHED;
144     ProcessFillModeOnFinish(animationFraction_.GetEndFraction());
145 }
146 
FinishOnCurrentPosition()147 void RSRenderAnimation::FinishOnCurrentPosition()
148 {
149     if (!IsPaused() && !IsRunning()) {
150         ROSEN_LOGE("Failed to finish animation, animation is not running!");
151         return;
152     }
153 
154     state_ = AnimationState::FINISHED;
155 }
156 
Pause()157 void RSRenderAnimation::Pause()
158 {
159     if (!IsRunning()) {
160         ROSEN_LOGE("Failed to pause animation, animation is not running!");
161         return;
162     }
163 
164     state_ = AnimationState::PAUSED;
165 }
166 
Resume()167 void RSRenderAnimation::Resume()
168 {
169     if (!IsPaused()) {
170         ROSEN_LOGE("Failed to resume animation, animation is not paused!");
171         return;
172     }
173 
174     state_ = AnimationState::RUNNING;
175     needUpdateStartTime_ = true;
176 }
177 
SetFraction(float fraction)178 void RSRenderAnimation::SetFraction(float fraction)
179 {
180     if (!IsPaused()) {
181         ROSEN_LOGE("Failed to set fraction, animation is not paused!");
182         return;
183     }
184 
185     fraction = std::min(std::max(fraction, 0.0f), 1.0f);
186     OnSetFraction(fraction);
187 }
188 
SetReversed(bool isReversed)189 void RSRenderAnimation::SetReversed(bool isReversed)
190 {
191     if (!IsPaused() && !IsRunning()) {
192         ROSEN_LOGE("Failed to reverse animation, animation is not running!");
193         return;
194     }
195 
196     animationFraction_.SetDirectionAfterStart(isReversed ? ForwardDirection::REVERSE : ForwardDirection::NORMAL);
197 }
198 
GetTarget() const199 RSRenderNode* RSRenderAnimation::GetTarget() const
200 {
201     return target_;
202 }
203 
SetFractionInner(float fraction)204 void RSRenderAnimation::SetFractionInner(float fraction)
205 {
206     animationFraction_.UpdateRemainTimeFraction(fraction);
207 }
208 
OnSetFraction(float fraction)209 void RSRenderAnimation::OnSetFraction(float fraction)
210 {
211     SetFractionInner(fraction);
212 }
213 
ProcessFillModeOnStart(float startFraction)214 void RSRenderAnimation::ProcessFillModeOnStart(float startFraction)
215 {
216     auto fillMode = GetFillMode();
217     if (fillMode == FillMode::BACKWARDS || fillMode == FillMode::BOTH) {
218         OnAnimate(startFraction);
219     }
220 }
221 
ProcessFillModeOnFinish(float endFraction)222 void RSRenderAnimation::ProcessFillModeOnFinish(float endFraction)
223 {
224     auto fillMode = GetFillMode();
225     if (fillMode == FillMode::FORWARDS || fillMode == FillMode::BOTH) {
226         OnAnimate(endFraction);
227     } else {
228         OnRemoveOnCompletion();
229     }
230 }
231 
Animate(int64_t time)232 bool RSRenderAnimation::Animate(int64_t time)
233 {
234     if (!IsRunning()) {
235         ROSEN_LOGI("RSRenderAnimation::Animate, IsRunning is false!");
236         return state_ == AnimationState::FINISHED;
237     }
238 
239     // set start time and return
240     if (needUpdateStartTime_) {
241         SetStartTime(time);
242         return state_ == AnimationState::FINISHED;
243     }
244 
245     // if time not changed since last frame, return
246     if (time == animationFraction_.GetLastFrameTime()) {
247         return state_ == AnimationState::FINISHED;
248     }
249 
250     if (needInitialize_) {
251         OnInitialize();
252         needInitialize_ = false;
253     }
254 
255     bool isInStartDelay = false;
256     bool isFinished = false;
257     float fraction = animationFraction_.GetAnimationFraction(time, isInStartDelay, isFinished);
258     if (isInStartDelay) {
259         ProcessFillModeOnStart(fraction);
260         ROSEN_LOGI("RSRenderAnimation::Animate, isInStartDelay is true");
261         return false;
262     }
263 
264     OnAnimate(fraction);
265     if (isFinished) {
266         ProcessFillModeOnFinish(fraction);
267         ROSEN_LOGD("RSRenderAnimation::Animate, isFinished is true");
268         return true;
269     }
270     return isFinished;
271 }
272 
SetStartTime(int64_t time)273 void RSRenderAnimation::SetStartTime(int64_t time)
274 {
275     animationFraction_.SetLastFrameTime(time);
276     needUpdateStartTime_ = false;
277 }
278 } // namespace Rosen
279 } // namespace OHOS
280