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