• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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 #include "core/components_ng/render/adapter/rosen_modifier_adapter.h"
16 
17 #include "interfaces/inner_api/ace_kit/src/view/draw/modifier_adapter.h"
18 #include "ui/view/draw/content_modifier.h"
19 
20 #include "core/animation/native_curve_helper.h"
21 #include "core/components_ng/animation/animatable_arithmetic_proxy.h"
22 
23 namespace OHOS::Ace::NG {
24 
25 std::unordered_map<int32_t, std::shared_ptr<RSModifier>> g_ModifiersMap;
26 std::mutex g_ModifiersMapLock;
27 
ConvertKitContentModifier(const RefPtr<Kit::Modifier> & modifier)28 std::shared_ptr<RSModifier> ConvertKitContentModifier(const RefPtr<Kit::Modifier>& modifier)
29 {
30     auto kitModifier = AceType::DynamicCast<Kit::ContentModifier>(modifier);
31     CHECK_NULL_RETURN(kitModifier, nullptr);
32     return kitModifier->GetRSModifier();
33 }
34 
ConvertContentModifier(const RefPtr<Modifier> & modifier)35 std::shared_ptr<RSModifier> ConvertContentModifier(const RefPtr<Modifier>& modifier)
36 {
37     CHECK_NULL_RETURN(modifier, nullptr);
38     std::lock_guard<std::mutex> lock(g_ModifiersMapLock);
39     const auto& iter = g_ModifiersMap.find(modifier->GetId());
40     if (iter != g_ModifiersMap.end()) {
41         return iter->second;
42     }
43     auto modifierAdapter = std::make_shared<ContentModifierAdapter>(modifier);
44     g_ModifiersMap.emplace(modifier->GetId(), modifierAdapter);
45     return modifierAdapter;
46 }
47 
ConvertOverlayModifier(const RefPtr<Modifier> & modifier)48 std::shared_ptr<RSModifier> ConvertOverlayModifier(const RefPtr<Modifier>& modifier)
49 {
50     CHECK_NULL_RETURN(modifier, nullptr);
51     std::lock_guard<std::mutex> lock(g_ModifiersMapLock);
52     const auto& iter = g_ModifiersMap.find(modifier->GetId());
53     if (iter != g_ModifiersMap.end()) {
54         return iter->second;
55     }
56     auto modifierAdapter = std::make_shared<OverlayModifierAdapter>(modifier);
57     g_ModifiersMap.emplace(modifier->GetId(), modifierAdapter);
58     return modifierAdapter;
59 }
60 
ConvertForegroundModifier(const RefPtr<Modifier> & modifier)61 std::shared_ptr<RSModifier> ConvertForegroundModifier(const RefPtr<Modifier>& modifier)
62 {
63     CHECK_NULL_RETURN(modifier, nullptr);
64     std::lock_guard<std::mutex> lock(g_ModifiersMapLock);
65     const auto& iter = g_ModifiersMap.find(modifier->GetId());
66     if (iter != g_ModifiersMap.end()) {
67         return iter->second;
68     }
69     auto modifierAdapter = std::make_shared<ForegroundModifierAdapter>(modifier);
70     g_ModifiersMap.emplace(modifier->GetId(), modifierAdapter);
71     return modifierAdapter;
72 }
73 
RemoveModifier(int32_t modifierId)74 void ModifierAdapter::RemoveModifier(int32_t modifierId)
75 {
76     std::lock_guard<std::mutex> lock(g_ModifiersMapLock);
77     g_ModifiersMap.erase(modifierId);
78 }
79 
Draw(RSDrawingContext & context) const80 void ContentModifierAdapter::Draw(RSDrawingContext& context) const
81 {
82     // use dummy deleter avoid delete the SkCanvas by shared_ptr, its owned by context
83     CHECK_NULL_VOID(context.canvas);
84     auto modifier = modifier_.Upgrade();
85     CHECK_NULL_VOID(modifier);
86     DrawingContext context_ = { *context.canvas, context.width, context.height };
87     modifier->Draw(context_);
88 }
89 
90 #define CONVERT_PROP(prop, srcType, propType)                                      \
91     if (AceType::InstanceOf<srcType>(prop)) {                                      \
92         auto castProp = AceType::DynamicCast<srcType>(prop);                       \
93         auto rsProp = std::make_shared<RSProperty<propType>>(castProp->Get());     \
94         castProp->SetUpCallbacks([rsProp]() -> propType { return rsProp->Get(); }, \
95             [rsProp](const propType& value) { rsProp->Set(value); },               \
96             [rsProp]() -> propType { return rsProp->Get(); });                     \
97         return rsProp;                                                             \
98     }
99 
100 #define CONVERT_ANIMATABLE_PROP(prop, srcType, propType)                                 \
101     if (AceType::InstanceOf<srcType>(prop)) {                                            \
102         auto castProp = AceType::DynamicCast<srcType>(prop);                             \
103         auto rsProp = std::make_shared<RSAnimatableProperty<propType>>(castProp->Get()); \
104         castProp->SetUpCallbacks([rsProp]() -> propType { return rsProp->Get(); },       \
105             [rsProp](const propType& value) { rsProp->Set(value); },                     \
106             [rsProp]() -> propType { return rsProp->GetStagingValue(); });               \
107         rsProp->SetUpdateCallback(castProp->GetUpdateCallback());                        \
108         return rsProp;                                                                   \
109     }
110 
ConvertToRSProperty(const RefPtr<PropertyBase> & property)111 inline std::shared_ptr<RSPropertyBase> ConvertToRSProperty(const RefPtr<PropertyBase>& property)
112 {
113     // should manually add convert type here
114     CONVERT_PROP(property, PropertyBool, bool);
115     CONVERT_PROP(property, PropertySizeF, SizeF);
116     CONVERT_PROP(property, PropertyOffsetF, OffsetF);
117     CONVERT_PROP(property, PropertyInt, int32_t);
118     CONVERT_PROP(property, PropertyFloat, float);
119     CONVERT_PROP(property, PropertyString, std::string);
120     CONVERT_PROP(property, PropertyColor, Color);
121     CONVERT_PROP(property, PropertyRectF, RectF);
122     CONVERT_PROP(property, PropertyVectorFloat, LinearVector<float>);
123     CONVERT_PROP(property, PropertyCanvasImageModifierWrapper, CanvasImageModifierWrapper);
124     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyOffsetF, OffsetF);
125     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyUint8, uint8_t);
126     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyFloat, float);
127     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyColor, LinearColor);
128     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyVectorColor, GradientArithmetic);
129     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyVectorFloat, LinearVector<float>);
130     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyVectorLinearVector, LinearVector<LinearColor>);
131     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertySizeF, SizeF);
132 
133     if (AceType::InstanceOf<AnimatableArithmeticProperty>(property)) {
134         auto castProp = AceType::DynamicCast<AnimatableArithmeticProperty>(property);
135         if (!castProp && !castProp->Get()) {
136             LOGE("ConvertToRSProperty: Failed converting to RSProperty - AnimatableArithmeticProperty is null");
137             return nullptr;
138         }
139         AnimatableArithmeticProxy proxy(castProp->Get());
140         auto rsProp = std::make_shared<RSAnimatableProperty<AnimatableArithmeticProxy>>(proxy);
141         auto getter = [rsProp]() -> RefPtr<CustomAnimatableArithmetic> { return rsProp->Get().GetObject(); };
142         auto setter = [rsProp](const RefPtr<CustomAnimatableArithmetic>& value) {
143             rsProp->Set(AnimatableArithmeticProxy(value));
144         };
145         castProp->SetUpCallbacks(getter, setter);
146         if (castProp->GetUpdateCallback()) {
147             rsProp->SetUpdateCallback([cb = castProp->GetUpdateCallback()](
148                                           const AnimatableArithmeticProxy& value) { cb(value.GetObject()); });
149         }
150         return rsProp;
151     }
152 
153     LOGE("ConvertToRSProperty failed!");
154     return nullptr;
155 }
156 
AttachProperties()157 void ContentModifierAdapter::AttachProperties()
158 {
159     auto modifier = modifier_.Upgrade();
160     if (!hasAttached_ && modifier && modifier->GetAttachedProperties().size()) {
161         for (const auto& property : modifier->GetAttachedProperties()) {
162             auto rsProperty = ConvertToRSProperty(property);
163             AttachProperty(rsProperty);
164         }
165         hasAttached_ = true;
166     }
167 }
168 
Draw(RSDrawingContext & context) const169 void OverlayModifierAdapter::Draw(RSDrawingContext& context) const
170 {
171     // use dummy deleter avoid delete the SkCanvas by shared_ptr, its owned by context
172     CHECK_NULL_VOID(context.canvas);
173     auto modifier = modifier_.Upgrade();
174     CHECK_NULL_VOID(modifier);
175     DrawingContext context_ = { *context.canvas, context.width, context.height };
176     modifier->Draw(context_);
177 }
178 
AttachProperties()179 void OverlayModifierAdapter::AttachProperties()
180 {
181     auto modifier = modifier_.Upgrade();
182     if (!hasAttached_ && modifier && modifier->GetAttachedProperties().size()) {
183         for (const auto& property : modifier->GetAttachedProperties()) {
184             auto rsProperty = ConvertToRSProperty(property);
185             AttachProperty(rsProperty);
186         }
187         hasAttached_ = true;
188     }
189 }
190 
Draw(RSDrawingContext & context) const191 void ForegroundModifierAdapter::Draw(RSDrawingContext& context) const
192 {
193     // use dummy deleter avoid delete the SkCanvas by shared_ptr, its owned by context
194     CHECK_NULL_VOID(context.canvas);
195     auto modifier = modifier_.Upgrade();
196     CHECK_NULL_VOID(modifier);
197     DrawingContext context_ = { *context.canvas, context.width, context.height };
198     modifier->Draw(context_);
199 }
200 
AttachProperties()201 void ForegroundModifierAdapter::AttachProperties()
202 {
203     auto modifier = modifier_.Upgrade();
204     if (!hasAttached_ && modifier && modifier->GetAttachedProperties().size()) {
205         for (const auto& property : modifier->GetAttachedProperties()) {
206             auto rsProperty = ConvertToRSProperty(property);
207             AttachProperty(rsProperty);
208         }
209         hasAttached_ = true;
210     }
211 }
212 
AddProperty(const RefPtr<PropertyBase> & property)213 void RSNodeModifierImpl::AddProperty(const RefPtr<PropertyBase>& property)
214 {
215     if (!attachedProperty_) {
216         auto rsProperty = ConvertToRSProperty(property);
217         AttachProperty(rsProperty);
218         attachedProperty_ = rsProperty;
219     }
220 }
221 
222 namespace {
ToAnimationFinishCallbackType(const FinishCallbackType finishCallbackType)223 Rosen::FinishCallbackType ToAnimationFinishCallbackType(const FinishCallbackType finishCallbackType)
224 {
225     if (finishCallbackType == FinishCallbackType::LOGICALLY) {
226         return Rosen::FinishCallbackType::LOGICALLY;
227     } else if (finishCallbackType == FinishCallbackType::REMOVED) {
228         return Rosen::FinishCallbackType::TIME_SENSITIVE;
229     } else {
230         return Rosen::FinishCallbackType::TIME_SENSITIVE;
231     }
232 }
OptionToTimingProtocol(const AnimationOption & option)233 Rosen::RSAnimationTimingProtocol OptionToTimingProtocol(const AnimationOption& option)
234 {
235     Rosen::RSAnimationTimingProtocol timingProtocol;
236     timingProtocol.SetDuration(option.GetDuration());
237     timingProtocol.SetStartDelay(option.GetDelay());
238     timingProtocol.SetSpeed(option.GetTempo());
239     timingProtocol.SetRepeatCount(option.GetIteration());
240     timingProtocol.SetDirection(option.GetAnimationDirection() == AnimationDirection::NORMAL ||
241                                 option.GetAnimationDirection() == AnimationDirection::ALTERNATE);
242     timingProtocol.SetAutoReverse(option.GetAnimationDirection() == AnimationDirection::ALTERNATE ||
243                                   option.GetAnimationDirection() == AnimationDirection::ALTERNATE_REVERSE);
244     timingProtocol.SetFillMode(static_cast<Rosen::FillMode>(option.GetFillMode()));
245     timingProtocol.SetFinishCallbackType(ToAnimationFinishCallbackType(option.GetFinishCallbackType()));
246     return timingProtocol;
247 }
248 } // namespace
249 
250 template<>
AnimateWithVelocity(const AnimationOption & option,float value,float velocity,const FinishCallback & finishCallback)251 void NodeAnimatableProperty<float, AnimatablePropertyFloat>::AnimateWithVelocity(
252     const AnimationOption& option, float value, float velocity, const FinishCallback& finishCallback)
253 {
254     const auto& timingProtocol = OptionToTimingProtocol(option);
255     auto targetValue = std::make_shared<RSAnimatableProperty<float>>(value);
256     auto initialVelocity = std::make_shared<RSAnimatableProperty<float>>(velocity);
257     auto modify = std::static_pointer_cast<RSNodeModifierImpl>(GetModifyImpl());
258     if (modify) {
259         auto property = std::static_pointer_cast<RSAnimatableProperty<float>>(modify->GetProperty());
260         if (property) {
261             property->AnimateWithInitialVelocity(timingProtocol, NativeCurveHelper::ToNativeCurve(option.GetCurve()),
262                 targetValue, initialVelocity, finishCallback, nullptr);
263         }
264     }
265 }
266 
267 template<>
SetThresholdType(ThresholdType type)268 void NodeAnimatableProperty<float, AnimatablePropertyFloat>::SetThresholdType(ThresholdType type)
269 {
270     auto modify = std::static_pointer_cast<RSNodeModifierImpl>(GetModifyImpl());
271     CHECK_NULL_VOID(modify);
272     auto property = std::static_pointer_cast<RSPropertyBase>(modify->GetProperty());
273     CHECK_NULL_VOID(property);
274     property->SetThresholdType(static_cast<Rosen::ThresholdType>(type));
275 }
276 
277 template<>
SetPropertyUnit(PropertyUnit unit)278 void NodeAnimatableProperty<float, AnimatablePropertyFloat>::SetPropertyUnit(PropertyUnit unit)
279 {
280     auto modify = std::static_pointer_cast<RSNodeModifierImpl>(GetModifyImpl());
281     CHECK_NULL_VOID(modify);
282     auto property = std::static_pointer_cast<RSAnimatableProperty<float>>(modify->GetProperty());
283     CHECK_NULL_VOID(property);
284     property->SetPropertyUnit(static_cast<Rosen::RSPropertyUnit>(unit));
285 }
286 } // namespace OHOS::Ace::NG
287