1 /*
2 * Copyright (c) 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 "animation/rs_render_particle_animation.h"
17
18 #include <memory>
19
20 #include "animation/rs_value_estimator.h"
21 #include "command/rs_animation_command.h"
22 #include "common/rs_optional_trace.h"
23 #include "platform/common/rs_log.h"
24 #include "transaction/rs_marshalling_helper.h"
25
26 namespace OHOS {
27 namespace Rosen {
RSRenderParticleAnimation(AnimationId id,const PropertyId & propertyId,const std::vector<std::shared_ptr<ParticleRenderParams>> & particlesRenderParams)28 RSRenderParticleAnimation::RSRenderParticleAnimation(AnimationId id, const PropertyId& propertyId,
29 const std::vector<std::shared_ptr<ParticleRenderParams>>& particlesRenderParams)
30 : RSRenderPropertyAnimation(id, propertyId), particlesRenderParams_(particlesRenderParams),
31 particleSystem_(std::make_shared<RSRenderParticleSystem>(particlesRenderParams_))
32 {}
33
DumpAnimationInfo(std::string & out) const34 void RSRenderParticleAnimation::DumpAnimationInfo(std::string& out) const
35 {
36 out.append("Type:RSRenderParticleAnimation");
37 }
38
Animate(int64_t time,int64_t & minLeftDelayTime)39 bool RSRenderParticleAnimation::Animate(int64_t time, int64_t& minLeftDelayTime)
40 {
41 RS_OPTIONAL_TRACE_NAME("RSRenderParticleAnimation::Animate");
42 minLeftDelayTime = 0;
43 auto target = GetTarget();
44 if (!target) {
45 return true;
46 } else if (!target->GetRenderProperties().GetVisible()) {
47 if (auto modifierNG = property_->GetModifierNG().lock()) {
48 target->RemoveModifierNG(modifierNG->GetId());
49 }
50 return true;
51 }
52
53 int64_t deltaTime = time - animationFraction_.GetLastFrameTime();
54 animationFraction_.SetLastFrameTime(time);
55 if (particleSystem_ != nullptr) {
56 particleSystem_->Emit(
57 deltaTime, renderParticleVector_.renderParticleVector_, renderParticleVector_.imageVector_);
58 particleSystem_->UpdateParticle(deltaTime, renderParticleVector_.renderParticleVector_);
59 }
60 auto property = std::static_pointer_cast<RSRenderProperty<RSRenderParticleVector>>(property_);
61 if (property) {
62 property->Set(renderParticleVector_);
63 }
64
65 if (particleSystem_ == nullptr || particleSystem_->IsFinish(renderParticleVector_.renderParticleVector_)) {
66 if (!target) {
67 return true;
68 }
69 if (auto modifierNG = property_->GetModifierNG().lock()) {
70 target->RemoveModifierNG(modifierNG->GetId());
71 }
72 return true;
73 }
74 return false;
75 }
76
UpdateEmitter(const std::vector<std::shared_ptr<EmitterUpdater>> & emitterUpdaters)77 void RSRenderParticleAnimation::UpdateEmitter(const std::vector<std::shared_ptr<EmitterUpdater>>& emitterUpdaters)
78 {
79 if (emitterUpdaters.empty()) {
80 return;
81 }
82 for (auto emitterUpdater : emitterUpdaters) {
83 if (emitterUpdater) {
84 uint32_t index = emitterUpdater->emitterIndex_;
85 if (index >= particlesRenderParams_.size()) {
86 continue;
87 }
88 if (particlesRenderParams_[index] == nullptr) {
89 continue;
90 }
91 if (emitterUpdater->position_.has_value() &&
92 emitterUpdater->position_.value() != particlesRenderParams_[index]->emitterConfig_.position_) {
93 particlesRenderParams_[index]->emitterConfig_.position_ = emitterUpdater->position_.value();
94 }
95 if (emitterUpdater->emitSize_.has_value() &&
96 emitterUpdater->emitSize_.value() != particlesRenderParams_[index]->emitterConfig_.emitSize_) {
97 particlesRenderParams_[index]->emitterConfig_.emitSize_ = emitterUpdater->emitSize_.value();
98 }
99 if (emitterUpdater->emitRate_.has_value() &&
100 emitterUpdater->emitRate_.value() != particlesRenderParams_[index]->emitterConfig_.emitRate_) {
101 particlesRenderParams_[index]->emitterConfig_.emitRate_ = emitterUpdater->emitRate_.value();
102 }
103 UpdateParamsIfChanged(emitterUpdater->shape_, particlesRenderParams_[index]->emitterConfig_.shape_);
104 }
105 }
106 if (particleSystem_) {
107 particleSystem_->UpdateEmitter(particlesRenderParams_);
108 } else {
109 particleSystem_ = std::make_shared<RSRenderParticleSystem>(particlesRenderParams_);
110 }
111 }
112
UpdateNoiseField(const std::shared_ptr<ParticleNoiseFields> & particleNoiseFields)113 void RSRenderParticleAnimation::UpdateNoiseField(const std::shared_ptr<ParticleNoiseFields>& particleNoiseFields)
114 {
115 if (particleNoiseFields == nullptr) {
116 return;
117 } else if (particleNoiseFields_ != nullptr && *particleNoiseFields_ == *particleNoiseFields) {
118 return;
119 }
120 particleNoiseFields_ = particleNoiseFields;
121 if (particleSystem_) {
122 particleSystem_->UpdateNoiseField(particleNoiseFields);
123 }
124 }
125
OnAttach()126 void RSRenderParticleAnimation::OnAttach()
127 {
128 auto target = GetTarget();
129 if (target == nullptr) {
130 ROSEN_LOGE("RSRenderParticleAnimation::OnAttach, target is nullptr");
131 return;
132 }
133 auto particleAnimations = target->GetAnimationManager().GetParticleAnimations();
134 if (!particleAnimations.empty()) {
135 for (const auto& pair : particleAnimations) {
136 auto property = target->GetProperty(pair.first);
137 auto modifierNG = property != nullptr ? property->GetModifierNG().lock() : nullptr;
138 if (modifierNG != nullptr) {
139 target->RemoveModifierNG(modifierNG->GetId());
140 }
141 target->GetAnimationManager().RemoveAnimation(pair.second);
142 target->GetAnimationManager().UnregisterParticleAnimation(pair.first, pair.second);
143 }
144 }
145 target->GetAnimationManager().RegisterParticleAnimation(GetPropertyId(), GetAnimationId());
146 }
147
OnDetach()148 void RSRenderParticleAnimation::OnDetach()
149 {
150 auto target = GetTarget();
151 if (target == nullptr) {
152 ROSEN_LOGE("RSRenderParticleAnimation::OnDetach, target is nullptr");
153 return;
154 }
155 if (particleSystem_ != nullptr) {
156 particleSystem_->ClearEmitter();
157 particleSystem_.reset();
158 }
159 auto propertyId = GetPropertyId();
160 auto id = GetAnimationId();
161 target->GetAnimationManager().UnregisterParticleAnimation(propertyId, id);
162 }
163
Marshalling(Parcel & parcel) const164 bool RSRenderParticleAnimation::Marshalling(Parcel& parcel) const
165 {
166 auto id = GetAnimationId();
167 if (!(parcel.WriteUint64(id))) {
168 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write id failed");
169 return false;
170 }
171 if (!parcel.WriteUint64(propertyId_)) {
172 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write PropertyId failed");
173 return false;
174 }
175 if (!RSMarshallingHelper::Marshalling(parcel, particlesRenderParams_)) {
176 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write particlesRenderParams failed");
177 return false;
178 }
179 return true;
180 }
181
Unmarshalling(Parcel & parcel)182 RSRenderParticleAnimation* RSRenderParticleAnimation::Unmarshalling(Parcel& parcel)
183 {
184 RSRenderParticleAnimation* renderParticleAnimation = new RSRenderParticleAnimation();
185 if (!renderParticleAnimation->ParseParam(parcel)) {
186 ROSEN_LOGE("RSRenderParticleAnimation::Unmarshalling, failed");
187 delete renderParticleAnimation;
188 return nullptr;
189 }
190 return renderParticleAnimation;
191 }
192
ParseParam(Parcel & parcel)193 bool RSRenderParticleAnimation::ParseParam(Parcel& parcel)
194 {
195 AnimationId id = 0;
196 if (!RSMarshallingHelper::UnmarshallingPidPlusId(parcel, id)) {
197 ROSEN_LOGE("RSRenderParticleAnimation::ParseParam, Unmarshalling animationId failed");
198 return false;
199 }
200 SetAnimationId(id);
201 if (!(RSMarshallingHelper::UnmarshallingPidPlusId(parcel, propertyId_) &&
202 RSMarshallingHelper::Unmarshalling(parcel, particlesRenderParams_))) {
203 ROSEN_LOGE("RSRenderParticleAnimation::ParseParam, Unmarshalling failed");
204 return false;
205 }
206 particleSystem_ = std::make_shared<RSRenderParticleSystem>(particlesRenderParams_);
207 return true;
208 }
209
210 } // namespace Rosen
211 } // namespace OHOS
212