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.append("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() == RSPropertyType::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 property = std::static_pointer_cast<RSRenderProperty<float>>(target->GetProperty(rotationId_));
254 if (property != nullptr) {
255 property->Set(tangent);
256 }
257 }
258
GetPosTanValue(float fraction,Vector2f & position,float & tangent)259 void RSRenderPathAnimation::GetPosTanValue(float fraction, Vector2f& position, float& tangent)
260 {
261 float distance = animationPath_->GetDistance();
262 float progress = GetBeginFraction() * (FRACTION_MAX - fraction) + GetEndFraction() * fraction;
263 animationPath_->GetPosTan(distance * progress, position, tangent);
264 }
265
UpdateVector2fPathValue(Vector2f & value)266 void RSRenderPathAnimation::UpdateVector2fPathValue(Vector2f& value)
267 {
268 if (needAddOrigin_) {
269 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(GetOriginValue());
270 if (animatableProperty) {
271 value += animatableProperty->Get();
272 }
273 }
274 }
275
UpdateVector4fPathValue(Vector4f & value,const Vector2f & position)276 void RSRenderPathAnimation::UpdateVector4fPathValue(Vector4f& value, const Vector2f& position)
277 {
278 value[0] = position[0];
279 value[1] = position[1];
280 if (needAddOrigin_) {
281 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(GetOriginValue());
282 if (animatableProperty) {
283 value[0] += animatableProperty->Get()[0];
284 value[1] += animatableProperty->Get()[1];
285 }
286 }
287 }
288
InitValueEstimator()289 void RSRenderPathAnimation::InitValueEstimator()
290 {
291 if (valueEstimator_ == nullptr) {
292 valueEstimator_ = property_->CreateRSValueEstimator(RSValueEstimatorType::CURVE_VALUE_ESTIMATOR);
293 }
294
295 if (valueEstimator_ == nullptr) {
296 ROSEN_LOGE("RSRenderPathAnimation::InitValueEstimator, valueEstimator_ is nullptr.");
297 return;
298 }
299 valueEstimator_->InitCurveAnimationValue(property_, startValue_, endValue_, lastValue_);
300 }
301 } // namespace Rosen
302 } // namespace OHOS
303