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