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 "animation/rs_render_path_animation.h"
17
18 #include "animation/rs_value_estimator.h"
19 #include "pipeline/rs_canvas_render_node.h"
20 #include "platform/common/rs_log.h"
21 #include "render/rs_path.h"
22 #include "rs_profiler.h"
23
24 namespace OHOS {
25 namespace Rosen {
RSRenderPathAnimation(AnimationId id,const PropertyId & propertyId,const std::shared_ptr<RSRenderPropertyBase> & originPosition,const std::shared_ptr<RSRenderPropertyBase> & startPosition,const std::shared_ptr<RSRenderPropertyBase> & endPosition,float originRotation,const std::shared_ptr<RSPath> & animationPath)26 RSRenderPathAnimation::RSRenderPathAnimation(AnimationId id, const PropertyId& propertyId,
27 const std::shared_ptr<RSRenderPropertyBase>& originPosition,
28 const std::shared_ptr<RSRenderPropertyBase>& startPosition,
29 const std::shared_ptr<RSRenderPropertyBase>& endPosition, float originRotation,
30 const std::shared_ptr<RSPath>& animationPath) : RSRenderPropertyAnimation(id, propertyId, originPosition),
31 originRotation_(originRotation), startValue_(startPosition), endValue_(endPosition),
32 animationPath_(animationPath)
33 {}
34
DumpAnimationType(std::string & out) const35 void RSRenderPathAnimation::DumpAnimationType(std::string& out) const
36 {
37 out += "Type:RSRenderPathAnimation";
38 }
39
SetInterpolator(const std::shared_ptr<RSInterpolator> & interpolator)40 void RSRenderPathAnimation::SetInterpolator(const std::shared_ptr<RSInterpolator>& interpolator)
41 {
42 interpolator_ = interpolator;
43 }
44
GetInterpolator() const45 const std::shared_ptr<RSInterpolator>& RSRenderPathAnimation::GetInterpolator() const
46 {
47 return interpolator_;
48 }
49
SetRotationMode(const RotationMode & rotationMode)50 void RSRenderPathAnimation::SetRotationMode(const RotationMode& rotationMode)
51 {
52 if (IsStarted()) {
53 ROSEN_LOGE("Failed to enable rotate, path animation has started!");
54 return;
55 }
56
57 rotationMode_ = rotationMode;
58 }
59
GetRotationMode() const60 RotationMode RSRenderPathAnimation::GetRotationMode() const
61 {
62 return rotationMode_;
63 }
64
SetBeginFraction(float fraction)65 void RSRenderPathAnimation::SetBeginFraction(float fraction)
66 {
67 if (IsStarted()) {
68 ROSEN_LOGE("Failed to set begin fraction, path animation has started!");
69 return;
70 }
71
72 if (fraction < FRACTION_MIN || fraction > FRACTION_MAX || fraction > endFraction_) {
73 ROSEN_LOGE("Failed to set begin fraction, invalid value:%{public}f", fraction);
74 return;
75 }
76
77 beginFraction_ = fraction;
78 }
79
GetBeginFraction() const80 float RSRenderPathAnimation::GetBeginFraction() const
81 {
82 return beginFraction_;
83 }
84
SetEndFraction(float fraction)85 void RSRenderPathAnimation::SetEndFraction(float fraction)
86 {
87 if (IsStarted()) {
88 ROSEN_LOGE("Failed to set end fraction, path animation has started!");
89 return;
90 }
91
92 if (fraction < FRACTION_MIN || fraction > FRACTION_MAX || fraction < beginFraction_) {
93 ROSEN_LOGE("Failed to set end fraction, invalid value:%{public}f", fraction);
94 return;
95 }
96
97 endFraction_ = fraction;
98 }
99
GetEndFraction() const100 float RSRenderPathAnimation::GetEndFraction() const
101 {
102 return endFraction_;
103 }
104
SetIsNeedPath(const bool isNeedPath)105 void RSRenderPathAnimation::SetIsNeedPath(const bool isNeedPath)
106 {
107 isNeedPath_ = isNeedPath;
108 }
109
SetPathNeedAddOrigin(bool needAddOrigin)110 void RSRenderPathAnimation::SetPathNeedAddOrigin(bool needAddOrigin)
111 {
112 if (IsStarted()) {
113 ROSEN_LOGE("Failed to set need Add Origin, path animation has started!");
114 return;
115 }
116
117 needAddOrigin_ = needAddOrigin;
118 }
119
SetRotationId(const PropertyId id)120 void RSRenderPathAnimation::SetRotationId(const PropertyId id)
121 {
122 rotationId_ = id;
123 }
124
Marshalling(Parcel & parcel) const125 bool RSRenderPathAnimation::Marshalling(Parcel& parcel) const
126 {
127 if (!RSRenderPropertyAnimation::Marshalling(parcel)) {
128 ROSEN_LOGE("RSRenderPathAnimation::Marshalling, RenderPropertyAnimation failed");
129 return false;
130 }
131 if (!(parcel.WriteFloat(originRotation_) && parcel.WriteFloat(beginFraction_) && parcel.WriteFloat(endFraction_) &&
132 RSMarshallingHelper::Marshalling(parcel, animationPath_) &&
133 parcel.WriteInt32(static_cast<std::underlying_type<RotationMode>::type>(rotationMode_)) &&
134 parcel.WriteBool(isNeedPath_) && parcel.WriteBool(needAddOrigin_) && interpolator_ != nullptr &&
135 interpolator_->Marshalling(parcel) && RSRenderPropertyBase::Marshalling(parcel, startValue_) &&
136 RSRenderPropertyBase::Marshalling(parcel, endValue_) && parcel.WriteUint64(rotationId_))) {
137 ROSEN_LOGE("RSRenderPathAnimation::Marshalling, write failed");
138 return false;
139 }
140 return true;
141 }
142
Unmarshalling(Parcel & parcel)143 RSRenderPathAnimation* RSRenderPathAnimation::Unmarshalling(Parcel& parcel)
144 {
145 RSRenderPathAnimation* renderPathAnimation = new RSRenderPathAnimation();
146
147 if (!renderPathAnimation->ParseParam(parcel)) {
148 ROSEN_LOGE("RSRenderPathAnimation::Unmarshalling, Parse RenderProperty Fail");
149 delete renderPathAnimation;
150 return nullptr;
151 }
152 return renderPathAnimation;
153 }
154
ParseParam(Parcel & parcel)155 bool RSRenderPathAnimation::ParseParam(Parcel& parcel)
156 {
157 if (!RSRenderPropertyAnimation::ParseParam(parcel)) {
158 ROSEN_LOGE("RSRenderPathAnimation::ParseParam, Parse RenderProperty Fail");
159 return false;
160 }
161
162 int32_t rotationMode = 0;
163 bool isNeedPath = true;
164 if (!(parcel.ReadFloat(originRotation_) && parcel.ReadFloat(beginFraction_) &&
165 parcel.ReadFloat(endFraction_) && RSMarshallingHelper::Unmarshalling(parcel, animationPath_) &&
166 parcel.ReadInt32(rotationMode) && parcel.ReadBool(isNeedPath) && parcel.ReadBool(needAddOrigin_))) {
167 ROSEN_LOGE("RSRenderPathAnimation::ParseParam, Parse PathAnimation Failed");
168 return false;
169 }
170
171 std::shared_ptr<RSInterpolator> interpolator(RSInterpolator::Unmarshalling(parcel));
172 if (interpolator == nullptr) {
173 ROSEN_LOGE("RSRenderPathAnimation::ParseParam, Unmarshalling interpolator failed");
174 return false;
175 }
176
177 if (!(RSRenderPropertyBase::Unmarshalling(parcel, startValue_) &&
178 RSRenderPropertyBase::Unmarshalling(parcel, endValue_) && parcel.ReadUint64(rotationId_))) {
179 ROSEN_LOGE("RSRenderPathAnimation::ParseParam, Parse values failed");
180 return false;
181 }
182 RS_PROFILER_PATCH_NODE_ID(parcel, rotationId_);
183 SetInterpolator(interpolator);
184 SetRotationMode(static_cast<RotationMode>(rotationMode));
185 SetIsNeedPath(isNeedPath);
186 return true;
187 }
188
OnAnimate(float fraction)189 void RSRenderPathAnimation::OnAnimate(float fraction)
190 {
191 if (animationPath_ == nullptr) {
192 ROSEN_LOGE("Failed to animate motion path, path is null!");
193 return;
194 }
195
196 Vector2f position;
197 float tangent = 0.0;
198 GetPosTanValue(fraction, position, tangent);
199 auto valueVector2f = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(GetOriginValue());
200 if (GetOriginValue()->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR2F) {
201 UpdateVector2fPathValue(position);
202 SetPathValue(position, tangent);
203 return;
204 }
205
206 if (!isNeedPath_) {
207 if (valueEstimator_ == nullptr) {
208 return;
209 }
210 valueEstimator_->UpdateAnimationValue(interpolator_->Interpolate(fraction), GetAdditive());
211 return;
212 }
213
214 auto vector4fValueEstimator = std::static_pointer_cast<RSCurveValueEstimator<Vector4f>>(valueEstimator_);
215 if (vector4fValueEstimator != nullptr) {
216 auto animationValue =
217 vector4fValueEstimator->GetAnimationValue(interpolator_->Interpolate(fraction), GetAdditive());
218 UpdateVector4fPathValue(animationValue, position);
219 SetPathValue(animationValue, tangent);
220 }
221 }
222
OnRemoveOnCompletion()223 void RSRenderPathAnimation::OnRemoveOnCompletion()
224 {
225 auto target = GetTarget();
226 if (target == nullptr) {
227 ROSEN_LOGE("Failed to remove on completion, target is null!");
228 return;
229 }
230
231 target->GetMutableRenderProperties().SetRotation(originRotation_);
232 RSRenderPropertyAnimation::OnRemoveOnCompletion();
233 }
234
OnAttach()235 void RSRenderPathAnimation::OnAttach()
236 {
237 auto target = GetTarget();
238 if (target == nullptr) {
239 ROSEN_LOGE("RSRenderPathAnimation::OnAttach, target is nullptr");
240 return;
241 }
242 // check if any other path animation running on this property
243 auto propertyId = GetPropertyId();
244 auto prevAnimation = target->GetAnimationManager().QueryPathAnimation(propertyId);
245 target->GetAnimationManager().RegisterPathAnimation(propertyId, GetAnimationId());
246
247 // return if no other path animation(s) running
248 if (prevAnimation == nullptr) {
249 return;
250 }
251
252 // set previous path animation to FINISHED
253 prevAnimation->Finish();
254 }
255
OnDetach()256 void RSRenderPathAnimation::OnDetach()
257 {
258 auto target = GetTarget();
259 if (target == nullptr) {
260 ROSEN_LOGE("RSRenderPathAnimation::OnDetach, target is nullptr");
261 return;
262 }
263 auto propertyId = GetPropertyId();
264 auto id = GetAnimationId();
265 target->GetAnimationManager().UnregisterPathAnimation(propertyId, id);
266 }
267
SetPathValue(const Vector2f & value,float tangent)268 void RSRenderPathAnimation::SetPathValue(const Vector2f& value, float tangent)
269 {
270 SetRotationValue(tangent);
271 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(property_);
272 if (animatableProperty != nullptr) {
273 animatableProperty->Set(value);
274 }
275 }
276
SetPathValue(const Vector4f & value,float tangent)277 void RSRenderPathAnimation::SetPathValue(const Vector4f& value, float tangent)
278 {
279 SetRotationValue(tangent);
280 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(property_);
281 if (animatableProperty != nullptr) {
282 animatableProperty->Set(value);
283 }
284 }
285
SetRotationValue(const float tangent)286 void RSRenderPathAnimation::SetRotationValue(const float tangent)
287 {
288 switch (GetRotationMode()) {
289 case RotationMode::ROTATE_AUTO:
290 SetRotation(tangent);
291 break;
292 case RotationMode::ROTATE_AUTO_REVERSE:
293 SetRotation(tangent + 180.0f);
294 break;
295 case RotationMode::ROTATE_NONE:
296 break;
297 default:
298 ROSEN_LOGE("Unknow rotate mode!");
299 break;
300 }
301 }
302
SetRotation(const float tangent)303 void RSRenderPathAnimation::SetRotation(const float tangent)
304 {
305 auto target = GetTarget();
306 if (target == nullptr) {
307 ROSEN_LOGE("Failed to set rotation value, target is null!");
308 return;
309 }
310
311 auto modifier = target->GetModifier(rotationId_);
312 if (modifier != nullptr) {
313 auto property = std::static_pointer_cast<RSRenderProperty<float>>(modifier->GetProperty());
314 if (property != nullptr) {
315 property->Set(tangent);
316 }
317 }
318 }
319
GetPosTanValue(float fraction,Vector2f & position,float & tangent)320 void RSRenderPathAnimation::GetPosTanValue(float fraction, Vector2f& position, float& tangent)
321 {
322 float distance = animationPath_->GetDistance();
323 float progress = GetBeginFraction() * (FRACTION_MAX - fraction) + GetEndFraction() * fraction;
324 animationPath_->GetPosTan(distance * progress, position, tangent);
325 }
326
UpdateVector2fPathValue(Vector2f & value)327 void RSRenderPathAnimation::UpdateVector2fPathValue(Vector2f& value)
328 {
329 if (needAddOrigin_) {
330 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(GetOriginValue());
331 if (animatableProperty) {
332 value += animatableProperty->Get();
333 }
334 }
335 }
336
UpdateVector4fPathValue(Vector4f & value,const Vector2f & position)337 void RSRenderPathAnimation::UpdateVector4fPathValue(Vector4f& value, const Vector2f& position)
338 {
339 value[0] = position[0];
340 value[1] = position[1];
341 if (needAddOrigin_) {
342 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(GetOriginValue());
343 if (animatableProperty) {
344 value[0] += animatableProperty->Get()[0];
345 value[1] += animatableProperty->Get()[1];
346 }
347 }
348 }
349
InitValueEstimator()350 void RSRenderPathAnimation::InitValueEstimator()
351 {
352 if (valueEstimator_ == nullptr) {
353 valueEstimator_ = property_->CreateRSValueEstimator(RSValueEstimatorType::CURVE_VALUE_ESTIMATOR);
354 }
355
356 if (valueEstimator_ == nullptr) {
357 ROSEN_LOGE("RSRenderPathAnimation::InitValueEstimator, valueEstimator_ is nullptr.");
358 return;
359 }
360 valueEstimator_->InitCurveAnimationValue(property_, startValue_, endValue_, lastValue_);
361 }
362 } // namespace Rosen
363 } // namespace OHOS
364