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