1 /*
2 * Copyright (c) 2022 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_property_animation.h"
17
18 #include "animation/rs_animation_trace_utils.h"
19 #include "animation/rs_render_animation.h"
20 #include "modifier/rs_property.h"
21 #include "platform/common/rs_log.h"
22 #include "ui/rs_node.h"
23
24 namespace OHOS {
25 namespace Rosen {
26 static constexpr int NUMBER_FOR_HALF = 2;
27
RSPropertyAnimation(std::shared_ptr<RSPropertyBase> property)28 RSPropertyAnimation::RSPropertyAnimation(std::shared_ptr<RSPropertyBase> property) : property_(property)
29 {
30 InitAdditiveMode();
31 }
32
SetIsCustom(const bool isCustom)33 void RSPropertyAnimation::SetIsCustom(const bool isCustom)
34 {
35 isCustom_ = isCustom;
36 }
37
SetAdditive(bool isAdditive)38 void RSPropertyAnimation::SetAdditive(bool isAdditive)
39 {
40 isAdditive_ = isAdditive;
41 }
42
GetAdditive() const43 bool RSPropertyAnimation::GetAdditive() const
44 {
45 return isAdditive_;
46 }
47
GetOriginValue() const48 const std::shared_ptr<RSPropertyBase> RSPropertyAnimation::GetOriginValue() const
49 {
50 return originValue_;
51 }
52
SetPropertyValue(const std::shared_ptr<RSPropertyBase> & value)53 void RSPropertyAnimation::SetPropertyValue(const std::shared_ptr<RSPropertyBase>& value)
54 {
55 if (property_ != nullptr) {
56 property_->SetValue(value);
57 }
58 }
59
GetPropertyValue() const60 const std::shared_ptr<RSPropertyBase> RSPropertyAnimation::GetPropertyValue() const
61 {
62 if (property_ != nullptr) {
63 return property_->Clone();
64 }
65
66 return nullptr;
67 }
68
GetPropertyId() const69 PropertyId RSPropertyAnimation::GetPropertyId() const
70 {
71 if (property_ != nullptr) {
72 return property_->GetId();
73 }
74
75 return {};
76 }
77
OnStart()78 void RSPropertyAnimation::OnStart()
79 {
80 if (!hasOriginValue_) {
81 originValue_ = GetPropertyValue();
82 hasOriginValue_ = true;
83 }
84 InitInterpolationValue();
85 }
86
SetOriginValue(const std::shared_ptr<RSPropertyBase> & originValue)87 void RSPropertyAnimation::SetOriginValue(const std::shared_ptr<RSPropertyBase>& originValue)
88 {
89 if (!hasOriginValue_ && originValue != nullptr) {
90 originValue_ = originValue->Clone();
91 hasOriginValue_ = true;
92 }
93 }
94
InitInterpolationValue()95 void RSPropertyAnimation::InitInterpolationValue()
96 {
97 if (isDelta_) {
98 startValue_ = originValue_->Clone();
99 endValue_ = originValue_ + byValue_;
100 } else {
101 byValue_ = endValue_ - startValue_;
102 }
103 }
104
OnUpdateStagingValue(bool isFirstStart)105 void RSPropertyAnimation::OnUpdateStagingValue(bool isFirstStart)
106 {
107 auto startValue = startValue_;
108 auto endValue = endValue_;
109 if (!GetDirection()) {
110 std::swap(startValue, endValue);
111 }
112 auto byValue = endValue - startValue;
113 auto targetValue = endValue;
114 if (isFirstStart) {
115 if (GetAutoReverse() && GetRepeatCount() % NUMBER_FOR_HALF == 0) {
116 targetValue = startValue;
117 RS_LOGI_LIMIT("For even AutoReverse repeats, end value reverts to start :pro[%{public}" PRIu64 "] "
118 "animate[%{public}" PRIu64 "] repeat[%{public}d]", GetPropertyId(), GetId(), GetRepeatCount());
119 } else {
120 targetValue = endValue;
121 }
122 } else {
123 auto currentValue = GetPropertyValue();
124 if (GetAutoReverse() && GetRepeatCount() % NUMBER_FOR_HALF == 0) {
125 targetValue = IsReversed() ? currentValue + byValue : currentValue - byValue;
126 } else {
127 targetValue = IsReversed() ? currentValue - byValue : currentValue + byValue;
128 }
129 }
130
131 SetPropertyValue(targetValue);
132 }
133
UpdateStagingValueOnInteractiveFinish(RSInteractiveAnimationPosition pos)134 void RSPropertyAnimation::UpdateStagingValueOnInteractiveFinish(RSInteractiveAnimationPosition pos)
135 {
136 auto targetValue = endValue_;
137 if (pos ==RSInteractiveAnimationPosition::START) {
138 targetValue = startValue_;
139 } else if (pos ==RSInteractiveAnimationPosition::END) {
140 targetValue = endValue_;
141 } else if (pos ==RSInteractiveAnimationPosition::CURRENT) {
142 if (IsUiAnimation() && property_ != nullptr) {
143 property_->SetValueFromRender(property_->GetRenderProperty());
144 return;
145 }
146 }
147 SetPropertyValue(targetValue);
148 }
149
SetPropertyOnAllAnimationFinish()150 void RSPropertyAnimation::SetPropertyOnAllAnimationFinish()
151 {
152 if (property_ != nullptr) {
153 property_->UpdateOnAllAnimationFinish();
154 }
155 }
156
InitAdditiveMode()157 void RSPropertyAnimation::InitAdditiveMode()
158 {
159 if (property_ == nullptr) {
160 return;
161 }
162
163 switch (property_->GetPropertyTypeNG()) {
164 case ModifierNG::RSPropertyType::QUATERNION:
165 SetAdditive(false);
166 break;
167 default:
168 break;
169 }
170 }
171
DumpAnimationInfo(std::string & dumpInfo) const172 void RSPropertyAnimation::DumpAnimationInfo(std::string& dumpInfo) const
173 {
174 dumpInfo.append(", isCustom:").append(std::to_string(isCustom_));
175 if (property_) {
176 dumpInfo.append(", PropertyType: ").append(
177 std::to_string(static_cast<int16_t>(property_->GetPropertyTypeNG())));
178 }
179 if (startValue_) {
180 dumpInfo.append(", StartValue: ").append(
181 RSAnimationTraceUtils::GetInstance().ParseRenderPropertyValue(startValue_->GetRenderProperty()));
182 }
183 if (endValue_) {
184 dumpInfo.append(", EndValue: ").append(
185 RSAnimationTraceUtils::GetInstance().ParseRenderPropertyValue(endValue_->GetRenderProperty()));
186 }
187 }
188 } // namespace Rosen
189 } // namespace OHOS
190