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_transition_effect.h"
17 
18 #include <climits>
19 
20 #include "animation/rs_animation_common.h"
21 #include "animation/rs_value_estimator.h"
22 #include "modifier/rs_render_modifier.h"
23 #include "platform/common/rs_log.h"
24 #include "transaction/rs_marshalling_helper.h"
25 
26 namespace OHOS {
27 namespace Rosen {
28 namespace {
29 enum RSTransitionEffectType : uint16_t {
30     FADE = 1,
31     SCALE,
32     TRANSLATE,
33     ROTATE,
34     UNDEFINED,
35 };
36 constexpr int PID_SHIFT = 32;
37 
GenerateTransitionPropertyId()38 PropertyId GenerateTransitionPropertyId()
39 {
40     // manually set pid to INT_MAX to avoid conflict with other process (note: valid pid is smaller than 2^22)
41     static pid_t pid_ = INT_MAX;
42     static std::atomic<uint32_t> currentId_ = 1;
43 
44     auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
45     if (currentId == UINT32_MAX) {
46         // [PLANNING]:process the overflow situations
47         ROSEN_LOGE("Property Id overflow");
48     }
49 
50     return ((PropertyId)pid_ << PID_SHIFT) | currentId;
51 }
52 } // namespace
53 
Unmarshalling(Parcel & parcel)54 RSRenderTransitionEffect* RSRenderTransitionEffect::Unmarshalling(Parcel& parcel)
55 {
56     uint16_t transitionType = 0;
57     if (!parcel.ReadUint16(transitionType)) {
58         ROSEN_LOGE("RSRenderTransitionEffect::Unmarshalling, ParseParam Failed");
59         return nullptr;
60     }
61     switch (transitionType) {
62         case RSTransitionEffectType::FADE:
63             return RSTransitionFade::Unmarshalling(parcel);
64         case RSTransitionEffectType::SCALE:
65             return RSTransitionScale::Unmarshalling(parcel);
66         case RSTransitionEffectType::TRANSLATE:
67             return RSTransitionTranslate::Unmarshalling(parcel);
68         case RSTransitionEffectType::ROTATE:
69             return RSTransitionRotate::Unmarshalling(parcel);
70         default:
71             return nullptr;
72     }
73 }
74 
GetModifier()75 const std::shared_ptr<RSRenderModifier>& RSRenderTransitionEffect::GetModifier()
76 {
77     if (modifier_ == nullptr) {
78         modifier_ = CreateModifier();
79     }
80     return modifier_;
81 }
82 
Marshalling(Parcel & parcel) const83 bool RSTransitionFade::Marshalling(Parcel& parcel) const
84 {
85     return parcel.WriteUint16(RSTransitionEffectType::FADE) && parcel.WriteFloat(alpha_);
86 }
87 
Unmarshalling(Parcel & parcel)88 RSRenderTransitionEffect* RSTransitionFade::Unmarshalling(Parcel& parcel)
89 {
90     float alpha;
91     if (!RSMarshallingHelper::Unmarshalling(parcel, alpha)) {
92         ROSEN_LOGE("RSTransitionFade::Unmarshalling, unmarshalling alpha failed");
93         return nullptr;
94     }
95     return new RSTransitionFade(alpha);
96 }
97 
Marshalling(Parcel & parcel) const98 bool RSTransitionScale::Marshalling(Parcel& parcel) const
99 {
100     return parcel.WriteUint16(RSTransitionEffectType::SCALE) && parcel.WriteFloat(scaleX_) &&
101            parcel.WriteFloat(scaleY_) && parcel.WriteFloat(scaleZ_);
102 }
103 
Unmarshalling(Parcel & parcel)104 RSRenderTransitionEffect* RSTransitionScale::Unmarshalling(Parcel& parcel)
105 {
106     float scaleX = 0.0;
107     float scaleY = 0.0;
108     float scaleZ = 0.0;
109     if (!parcel.ReadFloat(scaleX) || !parcel.ReadFloat(scaleY) || !parcel.ReadFloat(scaleZ)) {
110         ROSEN_LOGE("RSTransitionScale::Unmarshalling, unmarshalling failed");
111         return nullptr;
112     }
113     return new RSTransitionScale(scaleX, scaleY, scaleZ);
114 }
115 
Marshalling(Parcel & parcel) const116 bool RSTransitionTranslate::Marshalling(Parcel& parcel) const
117 {
118     return parcel.WriteUint16(RSTransitionEffectType::TRANSLATE) && parcel.WriteFloat(translateX_) &&
119            parcel.WriteFloat(translateY_) && parcel.WriteFloat(translateZ_);
120 }
121 
Unmarshalling(Parcel & parcel)122 RSRenderTransitionEffect* RSTransitionTranslate::Unmarshalling(Parcel& parcel)
123 {
124     float translateX;
125     float translateY;
126     float translateZ;
127     if (!parcel.ReadFloat(translateX) || !parcel.ReadFloat(translateY) || !parcel.ReadFloat(translateZ)) {
128         ROSEN_LOGE("RSTransitionTranslate::Unmarshalling, unmarshalling failed");
129         return nullptr;
130     }
131     return new RSTransitionTranslate(translateX, translateY, translateZ);
132 }
133 
Marshalling(Parcel & parcel) const134 bool RSTransitionRotate::Marshalling(Parcel& parcel) const
135 {
136     return parcel.WriteUint16(RSTransitionEffectType::ROTATE) && parcel.WriteFloat(dx_) && parcel.WriteFloat(dy_) &&
137            parcel.WriteFloat(dz_) && parcel.WriteFloat(radian_);
138 }
139 
Unmarshalling(Parcel & parcel)140 RSRenderTransitionEffect* RSTransitionRotate::Unmarshalling(Parcel& parcel)
141 {
142     Quaternion quaternion;
143     float dx;
144     float dy;
145     float dz;
146     float radian;
147     if (!parcel.ReadFloat(dx) || !parcel.ReadFloat(dy) || !parcel.ReadFloat(dz) || !parcel.ReadFloat(radian)) {
148         ROSEN_LOGE("RSTransitionRotate::Unmarshalling, unmarshalling failed");
149         return nullptr;
150     }
151     return new RSTransitionRotate(dx, dy, dz, radian);
152 }
153 
CreateModifier()154 const std::shared_ptr<RSRenderModifier> RSTransitionFade::CreateModifier()
155 {
156     property_ = std::make_shared<RSRenderAnimatableProperty<float>>(0, GenerateTransitionPropertyId());
157     return std::make_shared<RSAlphaRenderModifier>(property_);
158 }
159 
UpdateFraction(float fraction) const160 void RSTransitionFade::UpdateFraction(float fraction) const
161 {
162     if (property_ == nullptr) {
163         return;
164     }
165     float startValue(1.0f);
166     float endValue(alpha_);
167     auto value = startValue * (1.0f - fraction) + endValue * fraction;
168     property_->Set(value);
169 }
170 
CreateModifier()171 const std::shared_ptr<RSRenderModifier> RSTransitionScale::CreateModifier()
172 {
173     property_ =
174         std::make_shared<RSRenderAnimatableProperty<Vector2f>>(Vector2f { 0, 0 }, GenerateTransitionPropertyId());
175     return std::make_shared<RSScaleRenderModifier>(property_);
176 }
177 
UpdateFraction(float fraction) const178 void RSTransitionScale::UpdateFraction(float fraction) const
179 {
180     if (property_ == nullptr) {
181         return;
182     }
183     Vector2f startValue(1.0f, 1.0f);
184     Vector2f endValue(scaleX_, scaleY_);
185     auto value = startValue * (1.0f - fraction) + endValue * fraction;
186     property_->Set(value);
187 }
188 
CreateModifier()189 const std::shared_ptr<RSRenderModifier> RSTransitionTranslate::CreateModifier()
190 {
191     property_ =
192         std::make_shared<RSRenderAnimatableProperty<Vector2f>>(Vector2f { 0, 0 }, GenerateTransitionPropertyId());
193     return std::make_shared<RSTranslateRenderModifier>(property_);
194 }
195 
UpdateFraction(float fraction) const196 void RSTransitionTranslate::UpdateFraction(float fraction) const
197 {
198     if (property_ == nullptr) {
199         return;
200     }
201     Vector2f startValue(0.0f, 0.0f);
202     Vector2f endValue(translateX_, translateY_);
203     auto value = startValue * (1.0f - fraction) + endValue * fraction;
204     property_->Set(value);
205 }
206 
CreateModifier()207 const std::shared_ptr<RSRenderModifier> RSTransitionRotate::CreateModifier()
208 {
209     property_ = std::make_shared<RSRenderAnimatableProperty<Quaternion>>(Quaternion {}, GenerateTransitionPropertyId());
210     return std::make_shared<RSQuaternionRenderModifier>(property_);
211 }
212 
UpdateFraction(float fraction) const213 void RSTransitionRotate::UpdateFraction(float fraction) const
214 {
215     if (property_ == nullptr) {
216         return;
217     }
218     auto radian = radian_ * fraction;
219     float factor = std::sin(radian / 2);
220     float qx = dx_ * factor;
221     float qy = dy_ * factor;
222     float qz = dz_ * factor;
223     float qw = std::cos(radian / 2);
224     Quaternion value(qx, qy, qz, qw);
225     property_->Set(value);
226 }
227 } // namespace Rosen
228 } // namespace OHOS
229