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