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