1 /*
2 * Copyright (c) 2022-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_property_animation.h"
17
18 #include "animation/rs_animation_trace_utils.h"
19 #include "modifier/rs_render_property.h"
20 #include "platform/common/rs_log.h"
21 #include "transaction/rs_marshalling_helper.h"
22 #include "rs_profiler.h"
23
24 namespace OHOS {
25 namespace Rosen {
RSRenderPropertyAnimation(AnimationId id,const PropertyId & propertyId,const std::shared_ptr<RSRenderPropertyBase> & originValue)26 RSRenderPropertyAnimation::RSRenderPropertyAnimation(
27 AnimationId id, const PropertyId& propertyId, const std::shared_ptr<RSRenderPropertyBase>& originValue)
28 : RSRenderAnimation(id), propertyId_(propertyId)
29 {
30 if (originValue) {
31 originValue_ = originValue->Clone();
32 lastValue_ = originValue->Clone();
33 } else {
34 originValue_ = std::make_shared<RSRenderAnimatableProperty<float>>();
35 lastValue_ = std::make_shared<RSRenderAnimatableProperty<float>>();
36 }
37 }
38
DumpAnimationInfo(std::string & out) const39 void RSRenderPropertyAnimation::DumpAnimationInfo(std::string& out) const
40 {
41 out.append("Type:RSRenderPropertyAnimation");
42 DumpProperty(out);
43 }
44
DumpProperty(std::string & out) const45 void RSRenderPropertyAnimation::DumpProperty(std::string& out) const
46 {
47 if (property_ != nullptr) {
48 if (auto modifierNG = property_->GetModifierNG().lock()) {
49 out.append(", ModifierType: ").append(
50 std::to_string(static_cast<int16_t>(modifierNG->FindPropertyType(property_))));
51 } else {
52 out.append(", ModifierType: INVALID");
53 }
54 } else {
55 out.append(", ModifierType: INVALID");
56 }
57 }
58
GetPropertyId() const59 PropertyId RSRenderPropertyAnimation::GetPropertyId() const
60 {
61 return propertyId_;
62 }
63
SetAdditive(bool isAdditive)64 void RSRenderPropertyAnimation::SetAdditive(bool isAdditive)
65 {
66 if (IsStarted()) {
67 ROSEN_LOGE("Failed to set additive, animation has started!");
68 return;
69 }
70
71 isAdditive_ = isAdditive;
72 }
73
GetAdditive()74 bool RSRenderPropertyAnimation::GetAdditive()
75 {
76 return isAdditive_;
77 }
78
AttachRenderProperty(const std::shared_ptr<RSRenderPropertyBase> & property)79 void RSRenderPropertyAnimation::AttachRenderProperty(const std::shared_ptr<RSRenderPropertyBase>& property)
80 {
81 property_ = property;
82 if (property_ == nullptr) {
83 return;
84 }
85 InitValueEstimator();
86 }
87
SetPropertyValue(const std::shared_ptr<RSRenderPropertyBase> & value)88 void RSRenderPropertyAnimation::SetPropertyValue(const std::shared_ptr<RSRenderPropertyBase>& value)
89 {
90 if (property_ != nullptr) {
91 property_->SetValue(value);
92 }
93 }
94
GetPropertyValue() const95 const std::shared_ptr<RSRenderPropertyBase> RSRenderPropertyAnimation::GetPropertyValue() const
96 {
97 if (property_ != nullptr) {
98 return property_->Clone();
99 }
100
101 if (lastValue_ != nullptr) {
102 return lastValue_->Clone();
103 }
104
105 return nullptr;
106 }
107
GetOriginValue() const108 const std::shared_ptr<RSRenderPropertyBase>& RSRenderPropertyAnimation::GetOriginValue() const
109 {
110 return originValue_;
111 }
112
GetLastValue() const113 const std::shared_ptr<RSRenderPropertyBase>& RSRenderPropertyAnimation::GetLastValue() const
114 {
115 return lastValue_;
116 }
117
SetAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & value)118 void RSRenderPropertyAnimation::SetAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& value)
119 {
120 if (value == nullptr) {
121 ROSEN_LOGD("RSRenderPropertyAnimation::SetAnimationValue, input is null!");
122 return;
123 }
124 std::shared_ptr<RSRenderPropertyBase> animationValue;
125 if (GetAdditive() && (property_ != nullptr)) {
126 animationValue = property_->Clone() + (value - lastValue_);
127 lastValue_ = value->Clone();
128 } else {
129 animationValue = value->Clone();
130 lastValue_ = value->Clone();
131 }
132 SetPropertyValue(animationValue);
133 }
134
GetAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & value)135 const std::shared_ptr<RSRenderPropertyBase> RSRenderPropertyAnimation::GetAnimationValue(
136 const std::shared_ptr<RSRenderPropertyBase>& value)
137 {
138 if (value == nullptr) {
139 ROSEN_LOGD("RSRenderPropertyAnimation::GetAnimationValue, input is null!");
140 return value;
141 }
142 std::shared_ptr<RSRenderPropertyBase> animationValue;
143 if (GetAdditive()) {
144 animationValue = GetPropertyValue() + (value - lastValue_);
145 } else {
146 animationValue = value->Clone();
147 }
148
149 lastValue_ = value->Clone();
150 return animationValue;
151 }
152
OnRemoveOnCompletion()153 void RSRenderPropertyAnimation::OnRemoveOnCompletion()
154 {
155 std::shared_ptr<RSRenderPropertyBase> backwardValue;
156 if (GetAdditive()) {
157 backwardValue = GetPropertyValue() + (GetOriginValue() - lastValue_);
158 } else {
159 backwardValue = GetOriginValue();
160 }
161
162 SetPropertyValue(backwardValue);
163 }
164
RecordLastAnimateValue()165 void RSRenderPropertyAnimation::RecordLastAnimateValue()
166 {
167 if (!RSRenderAnimation::isCalcAnimateVelocity_) {
168 return;
169 }
170 animateVelocity_.reset();
171 lastAnimateValue_.reset();
172 if (property_ != nullptr) {
173 lastAnimateValue_ = property_->Clone();
174 }
175 }
176
UpdateAnimateVelocity(float frameInterval)177 void RSRenderPropertyAnimation::UpdateAnimateVelocity(float frameInterval)
178 {
179 if (!RSRenderAnimation::isCalcAnimateVelocity_ ||
180 !lastAnimateValue_ || !property_ || ROSEN_EQ<float>(frameInterval, 0)) {
181 return;
182 }
183
184 if (property_->GetPropertyUnit() == RSPropertyUnit::ANGLE_ROTATION) {
185 ProcessAnimateVelocityUnderAngleRotation(frameInterval);
186 return;
187 }
188
189 if (property_->GetPropertyUnit() > RSPropertyUnit::UNKNOWN) {
190 auto currAnimateValue = property_->Clone();
191 animateVelocity_ = (currAnimateValue - lastAnimateValue_) * (1 / frameInterval);
192 ROSEN_LOGD("%{public}s, currAnimateValue: %{public}f, lastAnimateValue: %{public}f, "
193 "animateVelocity: %{public}f", __func__, currAnimateValue->ToFloat(),
194 lastAnimateValue_->ToFloat(), animateVelocity_->ToFloat());
195 }
196 }
197
ProcessAnimateVelocityUnderAngleRotation(float frameInterval)198 void RSRenderPropertyAnimation::ProcessAnimateVelocityUnderAngleRotation(float frameInterval)
199 {
200 auto currAnimateValue = property_->Clone();
201 if (currAnimateValue == nullptr) {
202 ROSEN_LOGE("%{public}s, currAnimateValue is null", __func__);
203 return;
204 }
205 float currAnimateFloatValue = currAnimateValue->ToFloat();
206 auto diffValue = currAnimateValue - lastAnimateValue_;
207 auto diffFloatValue = currAnimateFloatValue - lastAnimateValue_->ToFloat();
208 // 150 means 150 angle.
209 // The angle of the representation varies greatly between two frames.
210 int32_t factor = std::abs(diffFloatValue) / 150;
211 if (factor > 0) {
212 if (ROSEN_EQ<float>(currAnimateFloatValue, 0)) {
213 ROSEN_LOGE("%{public}s, currAnimateFloatValue is 0", __func__);
214 return;
215 }
216 // 180 means 180 angle, relative to pi radian.
217 auto circleValue = currAnimateValue * (180 * factor / currAnimateFloatValue);
218 diffValue = diffFloatValue < 0 ? (currAnimateValue + circleValue) - lastAnimateValue_
219 : currAnimateValue - (lastAnimateValue_ + circleValue);
220 }
221 if (ROSEN_EQ<float>(frameInterval, 0)) {
222 ROSEN_LOGE("%{public}s, frameInterval is 0", __func__);
223 return;
224 }
225 animateVelocity_ = diffValue * (1 / frameInterval);
226 ROSEN_LOGD("%{public}s, currAnimateValue: %{public}f, lastAnimateValue: %{public}f, "
227 "diffFloatValue: %{public}f, factor: %{public}d, animateVelocity: %{public}f",
228 __func__, currAnimateValue->ToFloat(), lastAnimateValue_->ToFloat(), diffFloatValue,
229 factor, animateVelocity_->ToFloat());
230 }
231
DumpFraction(float fraction,int64_t time)232 void RSRenderPropertyAnimation::DumpFraction(float fraction, int64_t time)
233 {
234 RSAnimationTraceUtils::GetInstance().AddAnimationFrameTrace(GetTarget(), GetTargetId(), GetTargetName(),
235 GetAnimationId(), GetPropertyId(), fraction, GetPropertyValue(), time, GetDuration(), GetRepeatCount());
236 }
237 } // namespace Rosen
238 } // namespace OHOS
239