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