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