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 "command/rs_animation_command.h"
17 
18 #include <memory>
19 
20 #include "animation/rs_render_interactive_implict_animator_map.h"
21 #include "animation/rs_render_interactive_implict_animator.h"
22 #include "animation/rs_render_particle.h"
23 #include "common/rs_common_def.h"
24 #include "common/rs_common_hook.h"
25 #include "modifier/rs_render_modifier.h"
26 #include "modifier/rs_render_property.h"
27 #include "platform/common/rs_log.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 
32 namespace {
33 static AnimationCommandHelper::AnimationCallbackProcessor animationCallbackProcessor = nullptr;
34 }
35 
AnimationCallback(RSContext & context,NodeId targetId,AnimationId animId,AnimationCallbackEvent event)36 void AnimationCommandHelper::AnimationCallback(
37     RSContext& context, NodeId targetId, AnimationId animId, AnimationCallbackEvent event)
38 {
39     if (animationCallbackProcessor != nullptr) {
40         animationCallbackProcessor(targetId, animId, event);
41     }
42 }
43 
SetAnimationCallbackProcessor(AnimationCallbackProcessor processor)44 void AnimationCommandHelper::SetAnimationCallbackProcessor(AnimationCallbackProcessor processor)
45 {
46     animationCallbackProcessor = processor;
47 }
48 
CreateAnimation(RSContext & context,NodeId targetId,const std::shared_ptr<RSRenderAnimation> & animation)49 void AnimationCommandHelper::CreateAnimation(
50     RSContext& context, NodeId targetId, const std::shared_ptr<RSRenderAnimation>& animation)
51 {
52     if (animation == nullptr) {
53         RS_LOGE("AnimationCommandHelper::CreateAnimation, animation is nullptr");
54         return;
55     }
56     auto node = context.GetNodeMap().GetRenderNode<RSRenderNode>(targetId);
57     if (node == nullptr) {
58         RS_LOGE("AnimationCommandHelper::CreateAnimation, node[%{public}" PRIu64 "] is nullptr,"
59             " animation is %{public}" PRIu64, targetId, animation->GetAnimationId());
60         context.AddSyncFinishAnimationList(targetId, animation->GetAnimationId());
61         return;
62     }
63     RsCommonHook::Instance().OnStartNewAnimation();
64     node->GetAnimationManager().AddAnimation(animation);
65     auto modifier = node->GetModifier(animation->GetPropertyId());
66     if (modifier != nullptr) {
67         animation->AttachRenderProperty(modifier->GetProperty());
68     }
69     auto currentTime = context.GetCurrentTimestamp();
70     animation->SetStartTime(currentTime);
71     animation->Attach(node.get());
72     // register node as animating node
73     context.RegisterAnimatingRenderNode(node);
74 }
75 
CreateParticleAnimation(RSContext & context,NodeId targetId,const std::shared_ptr<RSRenderParticleAnimation> & animation)76 void AnimationCommandHelper::CreateParticleAnimation(
77     RSContext& context, NodeId targetId, const std::shared_ptr<RSRenderParticleAnimation>& animation)
78 {
79     if (animation == nullptr) {
80         RS_LOGE("AnimationCommandHelper::CreateParticleAnimation, animation is nullptr");
81         return;
82     }
83     auto node = context.GetNodeMap().GetRenderNode<RSRenderNode>(targetId);
84     if (node == nullptr) {
85         return;
86     }
87     RsCommonHook::Instance().OnStartNewAnimation();
88     auto propertyId = animation->GetPropertyId();
89     node->GetAnimationManager().AddAnimation(animation);
90     auto property = std::make_shared<RSRenderProperty<RSRenderParticleVector>>(
91         animation->GetRenderParticle(), propertyId);
92     auto modifier = std::make_shared<RSParticlesRenderModifier>(property);
93     node->AddModifier(modifier);
94     animation->AttachRenderProperty(property);
95     auto currentTime = context.GetCurrentTimestamp();
96     animation->SetStartTime(currentTime);
97     animation->Attach(node.get());
98     // register node as animating node
99     context.RegisterAnimatingRenderNode(node);
100 }
101 
CancelAnimation(RSContext & context,NodeId targetId,PropertyId propertyId)102 void AnimationCommandHelper::CancelAnimation(RSContext& context, NodeId targetId, PropertyId propertyId)
103 {
104     auto node = context.GetNodeMap().GetRenderNode<RSRenderNode>(targetId);
105     if (node == nullptr) {
106         return;
107     }
108 
109     auto& animationManager = node->GetAnimationManager();
110     animationManager.CancelAnimationByPropertyId(propertyId);
111 }
112 
CreateInteractiveAnimator(RSContext & context,InteractiveImplictAnimatorId targetId,std::vector<std::pair<NodeId,AnimationId>> animations,bool startImmediately)113 void AnimationCommandHelper::CreateInteractiveAnimator(RSContext& context,
114     InteractiveImplictAnimatorId targetId, std::vector<std::pair<NodeId, AnimationId>> animations,
115     bool startImmediately)
116 {
117     auto animator = context.GetInteractiveImplictAnimatorMap().GetInteractiveImplictAnimator(targetId);
118     if (animator == nullptr) {
119         animator = std::make_shared<RSRenderInteractiveImplictAnimator>(targetId, context.weak_from_this());
120         context.GetInteractiveImplictAnimatorMap().RegisterInteractiveImplictAnimator(animator);
121     }
122     animator->AddAnimations(animations);
123     if (startImmediately) {
124         animator->ContinueAnimator();
125     }
126 }
127 
DestoryInteractiveAnimator(RSContext & context,InteractiveImplictAnimatorId targetId)128 void AnimationCommandHelper::DestoryInteractiveAnimator(RSContext& context, InteractiveImplictAnimatorId targetId)
129 {
130     auto animator = context.GetInteractiveImplictAnimatorMap().GetInteractiveImplictAnimator(targetId);
131     if (animator == nullptr) {
132         return;
133     }
134     context.GetInteractiveImplictAnimatorMap().UnregisterInteractiveImplictAnimator(targetId);
135 }
136 
InteractiveAnimatorAddAnimations(RSContext & context,InteractiveImplictAnimatorId targetId,std::vector<std::pair<NodeId,AnimationId>> animations)137 void AnimationCommandHelper::InteractiveAnimatorAddAnimations(RSContext& context,
138     InteractiveImplictAnimatorId targetId, std::vector<std::pair<NodeId, AnimationId>> animations)
139 {
140     auto animator = context.GetInteractiveImplictAnimatorMap().GetInteractiveImplictAnimator(targetId);
141     if (animator == nullptr) {
142         return;
143     }
144     animator->AddAnimations(animations);
145 }
146 
PauseInteractiveAnimator(RSContext & context,InteractiveImplictAnimatorId targetId)147 void AnimationCommandHelper::PauseInteractiveAnimator(RSContext& context, InteractiveImplictAnimatorId targetId)
148 {
149     auto animator = context.GetInteractiveImplictAnimatorMap().GetInteractiveImplictAnimator(targetId);
150     if (animator == nullptr) {
151         return;
152     }
153     animator->PauseAnimator();
154 }
155 
ContinueInteractiveAnimator(RSContext & context,InteractiveImplictAnimatorId targetId)156 void AnimationCommandHelper::ContinueInteractiveAnimator(RSContext& context, InteractiveImplictAnimatorId targetId)
157 {
158     auto animator = context.GetInteractiveImplictAnimatorMap().GetInteractiveImplictAnimator(targetId);
159     if (animator == nullptr) {
160         return;
161     }
162     animator->ContinueAnimator();
163 }
164 
FinishInteractiveAnimator(RSContext & context,InteractiveImplictAnimatorId targetId,RSInteractiveAnimationPosition finishPos)165 void AnimationCommandHelper::FinishInteractiveAnimator(RSContext& context,
166     InteractiveImplictAnimatorId targetId, RSInteractiveAnimationPosition finishPos)
167 {
168     auto animator = context.GetInteractiveImplictAnimatorMap().GetInteractiveImplictAnimator(targetId);
169     if (animator == nullptr) {
170         return;
171     }
172     animator->FinishAnimator(finishPos);
173 }
174 
ReverseInteractiveAnimator(RSContext & context,InteractiveImplictAnimatorId targetId)175 void AnimationCommandHelper::ReverseInteractiveAnimator(RSContext& context, InteractiveImplictAnimatorId targetId)
176 {
177     auto animator = context.GetInteractiveImplictAnimatorMap().GetInteractiveImplictAnimator(targetId);
178     if (animator == nullptr) {
179         return;
180     }
181     animator->ReverseAnimator();
182 }
183 
SetFractionInteractiveAnimator(RSContext & context,InteractiveImplictAnimatorId targetId,float fraction)184 void AnimationCommandHelper::SetFractionInteractiveAnimator(RSContext& context,
185     InteractiveImplictAnimatorId targetId, float fraction)
186 {
187     auto animator = context.GetInteractiveImplictAnimatorMap().GetInteractiveImplictAnimator(targetId);
188     if (animator == nullptr) {
189         return;
190     }
191     animator->SetFractionAnimator(fraction);
192 }
193 } // namespace Rosen
194 } // namespace OHOS
195