• 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 "command/rs_animation_command.h"
19 #include "pipeline/rs_canvas_render_node.h"
20 #include "command/rs_message_processor.h"
21 #include "platform/common/rs_log.h"
22 
23 namespace OHOS {
24 namespace Rosen {
RSRenderAnimation(AnimationId id)25 RSRenderAnimation::RSRenderAnimation(AnimationId id) : id_(id) {}
Marshalling(Parcel & parcel) const26 bool RSRenderAnimation::Marshalling(Parcel& parcel) const
27 {
28     // animationId, targetId
29     if (!(parcel.WriteUint64(id_))) {
30         ROSEN_LOGE("RSRenderAnimation::Marshalling, write id failed");
31         return false;
32     }
33     // RSAnimationTimingProtocol
34     if (!(parcel.WriteInt32(animationFraction_.GetDuration()) &&
35         parcel.WriteInt32(animationFraction_.GetStartDelay()) &&
36         parcel.WriteFloat(animationFraction_.GetSpeed()) &&
37         parcel.WriteInt32(animationFraction_.GetRepeatCount()) &&
38         parcel.WriteBool(animationFraction_.GetAutoReverse()) &&
39         parcel.WriteBool(animationFraction_.GetDirection()) &&
40         parcel.WriteInt32(static_cast<std::underlying_type<FillMode>::type>(animationFraction_.GetFillMode())) &&
41         parcel.WriteBool(animationFraction_.GetRepeatCallbackEnable()) &&
42         parcel.WriteInt32(animationFraction_.GetFrameRateRange().min_) &&
43         parcel.WriteInt32(animationFraction_.GetFrameRateRange().max_) &&
44         parcel.WriteInt32(animationFraction_.GetFrameRateRange().preferred_))) {
45         ROSEN_LOGE("RSRenderAnimation::Marshalling, write param failed");
46         return false;
47     }
48     return true;
49 }
50 
DumpAnimation(std::string & out) const51 void RSRenderAnimation::DumpAnimation(std::string& out) const
52 {
53     out += "Animation: [id:" + std::to_string(id_) + ", ";
54     DumpAnimationType(out);
55     out += ", AnimationState:" + std::to_string(static_cast<int>(state_));
56     out += ", StartDelay:" + std::to_string(animationFraction_.GetDuration());
57     out += ", Duration:" + std::to_string(animationFraction_.GetStartDelay());
58     out += ", Speed:" + std::to_string(animationFraction_.GetSpeed());
59     out += ", RepeatCount:" + std::to_string(animationFraction_.GetRepeatCount());
60     out += ", AutoReverse:" + std::to_string(animationFraction_.GetAutoReverse());
61     out += ", Direction:" + std::to_string(animationFraction_.GetDirection());
62     out += ", FillMode:" + std::to_string(static_cast<int>(animationFraction_.GetFillMode()));
63     out += ", RepeatCallbackEnable:" + std::to_string(animationFraction_.GetRepeatCallbackEnable());
64     out += ", FrameRateRange_min:" + std::to_string(animationFraction_.GetFrameRateRange().min_);
65     out += ", FrameRateRange_max:" + std::to_string(animationFraction_.GetFrameRateRange().max_);
66     out += ", FrameRateRange_prefered:" + std::to_string(animationFraction_.GetFrameRateRange().preferred_);
67     out += "]";
68 }
69 
DumpAnimationType(std::string & out) const70 void RSRenderAnimation::DumpAnimationType(std::string& out) const
71 {
72     out += "Type:Unknown";
73 }
74 
ParseParam(Parcel & parcel)75 bool RSRenderAnimation::ParseParam(Parcel& parcel)
76 {
77     int32_t duration = 0;
78     int32_t startDelay = 0;
79     int32_t repeatCount = 0;
80     int32_t fillMode = 0;
81     float speed = 0.0;
82     bool autoReverse = false;
83     bool direction = false;
84     bool isRepeatCallbackEnable = false;
85     int fpsMin = 0;
86     int fpsMax = 0;
87     int fpsPreferred = 0;
88     if (!(parcel.ReadUint64(id_) && parcel.ReadInt32(duration) && parcel.ReadInt32(startDelay) &&
89             parcel.ReadFloat(speed) && parcel.ReadInt32(repeatCount) && parcel.ReadBool(autoReverse) &&
90             parcel.ReadBool(direction) && parcel.ReadInt32(fillMode) && parcel.ReadBool(isRepeatCallbackEnable) &&
91             parcel.ReadInt32(fpsMin) && parcel.ReadInt32(fpsMax) && parcel.ReadInt32(fpsPreferred))) {
92         ROSEN_LOGE("RSRenderAnimation::ParseParam, read param failed");
93         return false;
94     }
95     SetDuration(duration);
96     SetStartDelay(startDelay);
97     SetRepeatCount(repeatCount);
98     SetAutoReverse(autoReverse);
99     SetSpeed(speed);
100     SetDirection(direction);
101     SetFillMode(static_cast<FillMode>(fillMode));
102     SetRepeatCallbackEnable(isRepeatCallbackEnable);
103     SetFrameRateRange({fpsMin, fpsMax, fpsPreferred});
104     return true;
105 }
GetAnimationId() const106 AnimationId RSRenderAnimation::GetAnimationId() const
107 {
108     return id_;
109 }
110 
IsStarted() const111 bool RSRenderAnimation::IsStarted() const
112 {
113     return state_ != AnimationState::INITIALIZED;
114 }
115 
IsRunning() const116 bool RSRenderAnimation::IsRunning() const
117 {
118     return state_ == AnimationState::RUNNING;
119 }
120 
IsPaused() const121 bool RSRenderAnimation::IsPaused() const
122 {
123     return state_ == AnimationState::PAUSED;
124 }
125 
IsFinished() const126 bool RSRenderAnimation::IsFinished() const
127 {
128     return state_ == AnimationState::FINISHED;
129 }
130 
GetPropertyId() const131 PropertyId RSRenderAnimation::GetPropertyId() const
132 {
133     return 0;
134 }
135 
Attach(RSRenderNode * renderNode)136 void RSRenderAnimation::Attach(RSRenderNode* renderNode)
137 {
138     if (target_ != nullptr) {
139         Detach();
140     }
141     target_ = renderNode;
142     if (target_ != nullptr) {
143         targetId_ = target_->GetId();
144         target_->CheckGroupableAnimation(GetPropertyId(), true);
145     }
146     OnAttach();
147     Start();
148     needUpdateStartTime_ = false;
149 }
150 
Detach(bool forceDetach)151 void RSRenderAnimation::Detach(bool forceDetach)
152 {
153     if (!forceDetach) {
154         OnDetach();
155         if (target_ != nullptr) {
156             target_->CheckGroupableAnimation(GetPropertyId(), false);
157         }
158     }
159     target_ = nullptr;
160 }
161 
GetTargetId() const162 NodeId RSRenderAnimation::GetTargetId() const
163 {
164     return targetId_;
165 }
166 
Start()167 void RSRenderAnimation::Start()
168 {
169     if (IsStarted()) {
170         ROSEN_LOGE("Failed to start animation, animation has started!");
171         return;
172     }
173 
174     state_ = AnimationState::RUNNING;
175     needUpdateStartTime_ = true;
176     ProcessFillModeOnStart(animationFraction_.GetStartFraction());
177 }
178 
Finish()179 void RSRenderAnimation::Finish()
180 {
181     if (!IsPaused() && !IsRunning()) {
182         ROSEN_LOGD("Failed to finish animation, animation is not running!");
183         return;
184     }
185 
186     state_ = AnimationState::FINISHED;
187     ProcessFillModeOnFinish(animationFraction_.GetEndFraction());
188 }
189 
FinishOnCurrentPosition()190 void RSRenderAnimation::FinishOnCurrentPosition()
191 {
192     if (!IsPaused() && !IsRunning()) {
193         ROSEN_LOGD("Failed to finish animation, animation is not running!");
194         return;
195     }
196 
197     state_ = AnimationState::FINISHED;
198 }
199 
Pause()200 void RSRenderAnimation::Pause()
201 {
202     if (!IsRunning()) {
203         ROSEN_LOGE("Failed to pause animation, animation is not running!");
204         return;
205     }
206 
207     state_ = AnimationState::PAUSED;
208 }
209 
Resume()210 void RSRenderAnimation::Resume()
211 {
212     if (!IsPaused()) {
213         ROSEN_LOGE("Failed to resume animation, animation is not paused!");
214         return;
215     }
216 
217     state_ = AnimationState::RUNNING;
218     needUpdateStartTime_ = true;
219 }
220 
SetFraction(float fraction)221 void RSRenderAnimation::SetFraction(float fraction)
222 {
223     if (!IsPaused()) {
224         ROSEN_LOGE("Failed to set fraction, animation is not paused!");
225         return;
226     }
227 
228     fraction = std::min(std::max(fraction, 0.0f), 1.0f);
229     OnSetFraction(fraction);
230 }
231 
SetReversed(bool isReversed)232 void RSRenderAnimation::SetReversed(bool isReversed)
233 {
234     if (!IsPaused() && !IsRunning()) {
235         ROSEN_LOGE("Failed to reverse animation, animation is not running!");
236         return;
237     }
238 
239     animationFraction_.SetDirectionAfterStart(isReversed ? ForwardDirection::REVERSE : ForwardDirection::NORMAL);
240 }
241 
GetTarget() const242 RSRenderNode* RSRenderAnimation::GetTarget() const
243 {
244     return target_;
245 }
246 
SetFractionInner(float fraction)247 void RSRenderAnimation::SetFractionInner(float fraction)
248 {
249     animationFraction_.UpdateRemainTimeFraction(fraction);
250 }
251 
OnSetFraction(float fraction)252 void RSRenderAnimation::OnSetFraction(float fraction)
253 {
254     SetFractionInner(fraction);
255 }
256 
ProcessFillModeOnStart(float startFraction)257 void RSRenderAnimation::ProcessFillModeOnStart(float startFraction)
258 {
259     auto fillMode = GetFillMode();
260     if (fillMode == FillMode::BACKWARDS || fillMode == FillMode::BOTH) {
261         OnAnimate(startFraction);
262     }
263 }
264 
ProcessFillModeOnFinish(float endFraction)265 void RSRenderAnimation::ProcessFillModeOnFinish(float endFraction)
266 {
267     auto fillMode = GetFillMode();
268     if (fillMode == FillMode::FORWARDS || fillMode == FillMode::BOTH) {
269         OnAnimate(endFraction);
270     } else {
271         OnRemoveOnCompletion();
272     }
273 }
274 
ProcessOnRepeatFinish()275 void RSRenderAnimation::ProcessOnRepeatFinish()
276 {
277     std::unique_ptr<RSCommand> command =
278         std::make_unique<RSAnimationCallback>(targetId_, id_, REPEAT_FINISHED);
279     RSMessageProcessor::Instance().AddUIMessage(ExtractPid(id_), command);
280 }
281 
Animate(int64_t time)282 bool RSRenderAnimation::Animate(int64_t time)
283 {
284     // calculateAnimationValue_ is embedded modify for stat animate frame drop
285     calculateAnimationValue_ = true;
286 
287     if (!IsRunning()) {
288         return state_ == AnimationState::FINISHED;
289     }
290 
291     // set start time and return
292     if (needUpdateStartTime_) {
293         SetStartTime(time);
294         return state_ == AnimationState::FINISHED;
295     }
296 
297     // if time not changed since last frame, return
298     if (time == animationFraction_.GetLastFrameTime()) {
299         return state_ == AnimationState::FINISHED;
300     }
301 
302     if (needInitialize_) {
303         // normally this only run once, but in spring animation with blendDuration, it may run multiple times
304         OnInitialize(time);
305     }
306 
307     // calculate frame time interval in seconds
308     float frameInterval = (time - animationFraction_.GetLastFrameTime()) * 1.0f / NS_TO_S;
309 
310     // convert time to fraction
311     auto [fraction, isInStartDelay, isFinished, isRepeatFinished] = animationFraction_.GetAnimationFraction(time);
312     if (isInStartDelay) {
313         calculateAnimationValue_ = false;
314         ProcessFillModeOnStart(fraction);
315         ROSEN_LOGD("RSRenderAnimation::Animate, isInStartDelay is true");
316         return false;
317     }
318 
319     RecordLastAnimateValue();
320     OnAnimate(fraction);
321     UpdateAnimateVelocity(frameInterval);
322 
323     if (isRepeatFinished) {
324         ProcessOnRepeatFinish();
325     }
326     if (isFinished) {
327         ProcessFillModeOnFinish(fraction);
328         ROSEN_LOGD("RSRenderAnimation::Animate, isFinished is true");
329         return true;
330     }
331     return isFinished;
332 }
333 
SetStartTime(int64_t time)334 void RSRenderAnimation::SetStartTime(int64_t time)
335 {
336     animationFraction_.SetLastFrameTime(time);
337     needUpdateStartTime_ = false;
338 }
339 
GetAnimateVelocity() const340 const std::shared_ptr<RSRenderPropertyBase> RSRenderAnimation::GetAnimateVelocity() const
341 {
342     return animateVelocity_;
343 }
344 
345 bool RSRenderAnimation::isCalcAnimateVelocity_ = true;
346 } // namespace Rosen
347 } // namespace OHOS
348