• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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_implicit_animator.h"
17 
18 #include "animation/rs_animation.h"
19 #include "animation/rs_animation_callback.h"
20 #include "animation/rs_path_animation.h"
21 #include "pipeline/rs_node_map.h"
22 #include "animation/rs_implicit_animation_param.h"
23 #include "platform/common/rs_log.h"
24 #include "ui/rs_node.h"
25 #include "modifier/rs_property.h"
26 
27 namespace OHOS {
28 namespace Rosen {
OpenImplicitAnimation(const RSAnimationTimingProtocol & timingProtocol,const RSAnimationTimingCurve & timingCurve,const std::function<void ()> & finishCallback)29 void RSImplicitAnimator::OpenImplicitAnimation(const RSAnimationTimingProtocol& timingProtocol,
30     const RSAnimationTimingCurve& timingCurve, const std::function<void()>& finishCallback)
31 {
32     globalImplicitParams_.push({ timingProtocol, timingCurve, finishCallback });
33     implicitAnimations_.push({});
34     keyframeAnimations_.push({});
35     switch (timingCurve.type_) {
36         case RSAnimationTimingCurve::CurveType::INTERPOLATING:
37             BeginImplicitCurveAnimation();
38             break;
39         case RSAnimationTimingCurve::CurveType::SPRING:
40             BeginImplicitSpringAnimation();
41             break;
42         default:
43             ROSEN_LOGE("Wrong type of timing curve!");
44             return;
45     }
46 }
47 
CloseImplicitAnimation()48 std::vector<std::shared_ptr<RSAnimation>> RSImplicitAnimator::CloseImplicitAnimation()
49 {
50     std::vector<std::pair<std::shared_ptr<RSAnimation>, NodeId>> currentAnimations;
51     if (globalImplicitParams_.empty() || implicitAnimations_.empty() || keyframeAnimations_.empty()) {
52         ROSEN_LOGE("Failed to close implicit animation, need to open implicit animation firstly!");
53         return {};
54     }
55 
56     auto finishCallback = std::get<std::function<void()>>(globalImplicitParams_.top());
57     if (implicitAnimations_.top().empty()) {
58         ROSEN_LOGD("No implicit animations created!");
59         if (finishCallback == nullptr) {
60             globalImplicitParams_.pop();
61             implicitAnimations_.pop();
62             keyframeAnimations_.pop();
63             EndImplicitAnimation();
64             return {};
65         } else {
66             CreateEmptyAnimation();
67         }
68     }
69     currentAnimations = implicitAnimations_.top();
70 
71     for (const auto& [animationInfo, keyframeAnimation] : keyframeAnimations_.top()) {
72         auto target = RSNodeMap::Instance().GetNode<RSNode>(animationInfo.first);
73         if (target == nullptr) {
74             ROSEN_LOGE("Failed to start implicit keyframe animation[%" PRIu64 "], target is null!",
75                 keyframeAnimation->GetId());
76             continue;
77         }
78 
79         target->AddAnimation(keyframeAnimation);
80     }
81 
82     std::shared_ptr<AnimationFinishCallback> animationFinishCallback;
83     if (finishCallback != nullptr) {
84         animationFinishCallback = std::make_shared<AnimationFinishCallback>(finishCallback);
85     }
86 
87     std::vector<std::shared_ptr<RSAnimation>> resultAnimations;
88     for (const auto& [animation, nodeId] : currentAnimations) {
89         if (animation == nullptr) {
90             continue;
91         }
92 
93         if (animationFinishCallback != nullptr) {
94             animation->SetFinishCallback(animationFinishCallback);
95         }
96 
97         resultAnimations.emplace_back(animation);
98     }
99 
100     globalImplicitParams_.pop();
101     implicitAnimations_.pop();
102     keyframeAnimations_.pop();
103     EndImplicitAnimation();
104     return resultAnimations;
105 }
106 
BeginImplicitKeyFrameAnimation(float fraction,const RSAnimationTimingCurve & timingCurve)107 void RSImplicitAnimator::BeginImplicitKeyFrameAnimation(float fraction, const RSAnimationTimingCurve& timingCurve)
108 {
109     if (globalImplicitParams_.empty()) {
110         ROSEN_LOGE("Failed to begin keyframe implicit animation, need to open implicit animation firstly!");
111         return;
112     }
113 
114     if (timingCurve.type_ != RSAnimationTimingCurve::CurveType::INTERPOLATING) {
115         ROSEN_LOGE("Wrong type of timing curve!");
116         return;
117     }
118 
119     auto paramsTuple = globalImplicitParams_.top();
120     auto keyframeAnimationParam = std::make_shared<RSImplicitKeyframeAnimationParam>(
121         std::get<RSAnimationTimingProtocol>(paramsTuple), timingCurve, fraction);
122     PushImplicitParam(keyframeAnimationParam);
123 }
124 
BeginImplicitKeyFrameAnimation(float fraction)125 void RSImplicitAnimator::BeginImplicitKeyFrameAnimation(float fraction)
126 {
127     if (globalImplicitParams_.empty()) {
128         ROSEN_LOGE("Failed to begin keyframe implicit animation, need to open implicit animation firstly!");
129         return;
130     }
131 
132     BeginImplicitKeyFrameAnimation(fraction, std::get<RSAnimationTimingCurve>(globalImplicitParams_.top()));
133 }
134 
EndImplicitKeyFrameAnimation()135 void RSImplicitAnimator::EndImplicitKeyFrameAnimation()
136 {
137     if (implicitAnimationParams_.empty() ||
138         implicitAnimationParams_.top()->GetType() != ImplicitAnimationParamType::KEYFRAME) {
139         ROSEN_LOGE("Failed to end keyframe implicit animation, need to begin keyframe implicit animation firstly!");
140         return;
141     }
142 
143     PopImplicitParam();
144 }
145 
NeedImplicitAnimation()146 bool RSImplicitAnimator::NeedImplicitAnimation()
147 {
148     return !implicitAnimationParams_.empty();
149 }
150 
BeginImplicitCurveAnimation()151 void RSImplicitAnimator::BeginImplicitCurveAnimation()
152 {
153     if (globalImplicitParams_.empty()) {
154         ROSEN_LOGE("Failed to begin curve implicit animation, need to open implicit animation firstly!");
155         return;
156     }
157 
158     [[maybe_unused]] auto& [protocol, curve, unused] = globalImplicitParams_.top();
159     if (curve.type_ != RSAnimationTimingCurve::CurveType::INTERPOLATING) {
160         ROSEN_LOGE("Wrong type of timing curve!");
161         return;
162     }
163     auto curveAnimationParam = std::make_shared<RSImplicitCurveAnimationParam>(protocol, curve);
164     PushImplicitParam(curveAnimationParam);
165 }
166 
EndImplicitAnimation()167 void RSImplicitAnimator::EndImplicitAnimation()
168 {
169     if (implicitAnimationParams_.empty() ||
170         (implicitAnimationParams_.top()->GetType() != ImplicitAnimationParamType::CURVE &&
171             implicitAnimationParams_.top()->GetType() != ImplicitAnimationParamType::SPRING)) {
172         ROSEN_LOGE("Failed to end implicit animation, need to begin implicit animation firstly!");
173         return;
174     }
175 
176     PopImplicitParam();
177 }
178 
BeginImplicitPathAnimation(const std::shared_ptr<RSMotionPathOption> & motionPathOption)179 void RSImplicitAnimator::BeginImplicitPathAnimation(const std::shared_ptr<RSMotionPathOption>& motionPathOption)
180 {
181     if (globalImplicitParams_.empty()) {
182         ROSEN_LOGE("Failed to begin path implicit animation, need to open implicit animation firstly!");
183         return;
184     }
185 
186     [[maybe_unused]] auto& [protocol, curve, unused] = globalImplicitParams_.top();
187     if (curve.type_ != RSAnimationTimingCurve::CurveType::INTERPOLATING) {
188         ROSEN_LOGE("Wrong type of timing curve!");
189         return;
190     }
191     auto pathAnimationParam = std::make_shared<RSImplicitPathAnimationParam>(protocol, curve, motionPathOption);
192     PushImplicitParam(pathAnimationParam);
193 }
194 
EndImplicitPathAnimation()195 void RSImplicitAnimator::EndImplicitPathAnimation()
196 {
197     if (implicitAnimationParams_.empty() ||
198         implicitAnimationParams_.top()->GetType() != ImplicitAnimationParamType::PATH) {
199         ROSEN_LOGE("Failed to end path implicit animation, need to begin path implicit animation firstly!");
200         return;
201     }
202 
203     PopImplicitParam();
204 }
205 
BeginImplicitSpringAnimation()206 void RSImplicitAnimator::BeginImplicitSpringAnimation()
207 {
208     if (globalImplicitParams_.empty()) {
209         ROSEN_LOGE("Failed to begin implicit transition, need to open implicit transition firstly!");
210         return;
211     }
212 
213     [[maybe_unused]] auto& [protocol, curve, unused] = globalImplicitParams_.top();
214     if (curve.type_ != RSAnimationTimingCurve::CurveType::SPRING) {
215         ROSEN_LOGE("Wrong type of timing curve!");
216         return;
217     }
218     auto springParam = std::make_shared<RSImplicitSpringAnimationParam>(protocol, curve);
219     PushImplicitParam(springParam);
220 }
221 
BeginImplicitTransition(const std::shared_ptr<const RSTransitionEffect> & effect)222 void RSImplicitAnimator::BeginImplicitTransition(const std::shared_ptr<const RSTransitionEffect>& effect)
223 {
224     if (globalImplicitParams_.empty()) {
225         ROSEN_LOGE("Failed to begin implicit transition, need to open implicit transition firstly!");
226         return;
227     }
228 
229     [[maybe_unused]] auto& [protocol, curve, unused] = globalImplicitParams_.top();
230     if (curve.type_ != RSAnimationTimingCurve::CurveType::INTERPOLATING) {
231         ROSEN_LOGE("Wrong type of timing curve!");
232         return;
233     }
234     auto transitionParam = std::make_shared<RSImplicitTransitionParam>(protocol, curve, effect);
235     PushImplicitParam(transitionParam);
236 }
237 
EndImplicitTransition()238 void RSImplicitAnimator::EndImplicitTransition()
239 {
240     if (implicitAnimationParams_.empty() ||
241         implicitAnimationParams_.top()->GetType() != ImplicitAnimationParamType::TRANSITION) {
242         ROSEN_LOGE("Failed to end implicit transition, need to begin implicit transition firstly!");
243         return;
244     }
245 
246     PopImplicitParam();
247 }
248 
PushImplicitParam(const std::shared_ptr<RSImplicitAnimationParam> & implicitParam)249 void RSImplicitAnimator::PushImplicitParam(const std::shared_ptr<RSImplicitAnimationParam>& implicitParam)
250 {
251     implicitAnimationParams_.emplace(implicitParam);
252 }
253 
PopImplicitParam()254 void RSImplicitAnimator::PopImplicitParam()
255 {
256     if (implicitAnimationParams_.empty()) {
257         ROSEN_LOGE("Failed to pop implicit params, params stack is empty!");
258         return;
259     }
260 
261     implicitAnimationParams_.pop();
262 }
263 
CreateImplicitTransition(RSNode & target,bool isTransitionIn)264 std::shared_ptr<RSAnimation> RSImplicitAnimator::CreateImplicitTransition(RSNode& target, bool isTransitionIn)
265 {
266     if (globalImplicitParams_.empty() || implicitAnimations_.empty() || keyframeAnimations_.empty()) {
267         ROSEN_LOGE("Failed to create implicit transition, need to open implicit transition firstly!");
268         return {};
269     }
270     std::shared_ptr<RSAnimation> transition = nullptr;
271     auto params = implicitAnimationParams_.top();
272     switch (params->GetType()) {
273         case ImplicitAnimationParamType::TRANSITION: {
274             auto transitionImplicitParam = std::static_pointer_cast<RSImplicitTransitionParam>(params);
275             transition = transitionImplicitParam->CreateAnimation(isTransitionIn);
276             break;
277         }
278         default:
279             break;
280     }
281     if (transition != nullptr) {
282         target.AddAnimation(transition);
283         implicitAnimations_.top().push_back({ transition, target.GetId() });
284     }
285     return transition;
286 }
287 
CreateEmptyAnimation()288 void RSImplicitAnimator::CreateEmptyAnimation()
289 {
290     auto target = RSNodeMap::Instance().GetAnimationFallbackNode();
291     if (target == nullptr) {
292         ROSEN_LOGE("RSImplicitAnimator::CreateEmptyAnimation, target is nullptr");
293         return;
294     }
295     std::shared_ptr<RSAnimatableProperty<float>> property = std::make_shared<RSAnimatableProperty<float>>(0.f);
296     property->id_ = 0;
297     auto startValue = std::make_shared<RSAnimatableProperty<float>>(0.f);
298     auto endValue = std::make_shared<RSAnimatableProperty<float>>(0.f);
299     CreateImplicitAnimation(target, property, startValue, endValue);
300     return;
301 }
302 
SetPropertyValue(std::shared_ptr<RSPropertyBase> property,const std::shared_ptr<RSPropertyBase> & value)303 void RSImplicitAnimator::SetPropertyValue(std::shared_ptr<RSPropertyBase> property,
304     const std::shared_ptr<RSPropertyBase>& value)
305 {
306     if (property != nullptr) {
307         property->SetValue(value);
308     }
309 }
310 
CreateImplicitAnimation(const std::shared_ptr<RSNode> & target,std::shared_ptr<RSPropertyBase> property,const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)311 std::shared_ptr<RSAnimation> RSImplicitAnimator::CreateImplicitAnimation(const std::shared_ptr<RSNode>& target,
312     std::shared_ptr<RSPropertyBase> property, const std::shared_ptr<RSPropertyBase>& startValue,
313     const std::shared_ptr<RSPropertyBase>& endValue)
314 {
315     if (globalImplicitParams_.empty() || implicitAnimations_.empty() || keyframeAnimations_.empty()) {
316         ROSEN_LOGE("Failed to create implicit animation, need to open implicit animation firstly!");
317         return {};
318     }
319 
320     if (target == nullptr || property == nullptr) {
321         return {};
322     }
323 
324     std::shared_ptr<RSAnimation> animation;
325     auto params = implicitAnimationParams_.top();
326     switch (params->GetType()) {
327         case ImplicitAnimationParamType::CURVE: {
328             auto curveImplicitParam = static_cast<RSImplicitCurveAnimationParam*>(params.get());
329             animation = curveImplicitParam->CreateAnimation(property, startValue, endValue);
330             break;
331         }
332         case ImplicitAnimationParamType::KEYFRAME: {
333             auto keyframeImplicitParam = static_cast<RSImplicitKeyframeAnimationParam*>(params.get());
334             auto& keyframeAnimations = keyframeAnimations_.top();
335             auto keyframeIter = keyframeAnimations.find({ target->GetId(), property->GetId() });
336             SetPropertyValue(property, endValue);
337             if (keyframeIter == keyframeAnimations.end()) {
338                 animation = keyframeImplicitParam->CreateAnimation(property, startValue, endValue);
339                 keyframeAnimations[{ target->GetId(), property->GetId() }] = animation;
340             } else {
341                 keyframeImplicitParam->AddKeyframe(keyframeIter->second, startValue, endValue);
342                 return keyframeIter->second;
343             }
344             break;
345         }
346         case ImplicitAnimationParamType::SPRING: {
347             auto springImplicitParam = static_cast<RSImplicitSpringAnimationParam*>(params.get());
348             animation = springImplicitParam->CreateAnimation(property, startValue, endValue);
349             break;
350         }
351         case ImplicitAnimationParamType::PATH: {
352             auto pathImplicitParam = static_cast<RSImplicitPathAnimationParam*>(params.get());
353             animation = pathImplicitParam->CreateAnimation(property, startValue, endValue);
354             break;
355         }
356         default:
357             ROSEN_LOGE("Failed to create animation, unknow type!");
358             break;
359     }
360 
361     if (animation == nullptr) {
362         ROSEN_LOGE("Failed to create animation!");
363         return nullptr;
364     }
365 
366     if (params->GetType() != ImplicitAnimationParamType::KEYFRAME) {
367         target->AddAnimation(animation);
368     }
369 
370     implicitAnimations_.top().push_back({ animation, target->GetId() });
371     return animation;
372 }
373 } // namespace Rosen
374 } // namespace OHOS
375