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