• 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     return nullptr;
154 }
155 
AttachProperties()156 void ContentModifierAdapter::AttachProperties()
157 {
158     auto modifier = modifier_.Upgrade();
159     if (!hasAttached_ && modifier && modifier->GetAttachedProperties().size()) {
160         for (const auto& property : modifier->GetAttachedProperties()) {
161             auto rsProperty = ConvertToRSProperty(property);
162             AttachProperty(rsProperty);
163         }
164         hasAttached_ = true;
165     }
166 }
167 
Draw(RSDrawingContext & context) const168 void OverlayModifierAdapter::Draw(RSDrawingContext& context) const
169 {
170     // use dummy deleter avoid delete the SkCanvas by shared_ptr, its owned by context
171     CHECK_NULL_VOID(context.canvas);
172     auto modifier = modifier_.Upgrade();
173     CHECK_NULL_VOID(modifier);
174     DrawingContext context_ = { *context.canvas, context.width, context.height };
175     modifier->Draw(context_);
176 }
177 
AttachProperties()178 void OverlayModifierAdapter::AttachProperties()
179 {
180     auto modifier = modifier_.Upgrade();
181     if (!hasAttached_ && modifier && modifier->GetAttachedProperties().size()) {
182         for (const auto& property : modifier->GetAttachedProperties()) {
183             auto rsProperty = ConvertToRSProperty(property);
184             AttachProperty(rsProperty);
185         }
186         hasAttached_ = true;
187     }
188 }
189 
Draw(RSDrawingContext & context) const190 void ForegroundModifierAdapter::Draw(RSDrawingContext& context) const
191 {
192     // use dummy deleter avoid delete the SkCanvas by shared_ptr, its owned by context
193     CHECK_NULL_VOID(context.canvas);
194     auto modifier = modifier_.Upgrade();
195     CHECK_NULL_VOID(modifier);
196     DrawingContext context_ = { *context.canvas, context.width, context.height };
197     modifier->Draw(context_);
198 }
199 
AttachProperties()200 void ForegroundModifierAdapter::AttachProperties()
201 {
202     auto modifier = modifier_.Upgrade();
203     if (!hasAttached_ && modifier && modifier->GetAttachedProperties().size()) {
204         for (const auto& property : modifier->GetAttachedProperties()) {
205             auto rsProperty = ConvertToRSProperty(property);
206             AttachProperty(rsProperty);
207         }
208         hasAttached_ = true;
209     }
210 }
211 
AddProperty(const RefPtr<PropertyBase> & property)212 void RSNodeModifierImpl::AddProperty(const RefPtr<PropertyBase>& property)
213 {
214     if (!attachedProperty_) {
215         auto rsProperty = ConvertToRSProperty(property);
216         AttachProperty(rsProperty);
217         attachedProperty_ = rsProperty;
218     }
219 }
220 
221 namespace {
ToAnimationFinishCallbackType(const FinishCallbackType finishCallbackType)222 Rosen::FinishCallbackType ToAnimationFinishCallbackType(const FinishCallbackType finishCallbackType)
223 {
224     if (finishCallbackType == FinishCallbackType::LOGICALLY) {
225         return Rosen::FinishCallbackType::LOGICALLY;
226     } else if (finishCallbackType == FinishCallbackType::REMOVED) {
227         return Rosen::FinishCallbackType::TIME_SENSITIVE;
228     } else {
229         return Rosen::FinishCallbackType::TIME_SENSITIVE;
230     }
231 }
OptionToTimingProtocol(const AnimationOption & option)232 Rosen::RSAnimationTimingProtocol OptionToTimingProtocol(const AnimationOption& option)
233 {
234     Rosen::RSAnimationTimingProtocol timingProtocol;
235     timingProtocol.SetDuration(option.GetDuration());
236     timingProtocol.SetStartDelay(option.GetDelay());
237     timingProtocol.SetSpeed(option.GetTempo());
238     timingProtocol.SetRepeatCount(option.GetIteration());
239     timingProtocol.SetDirection(option.GetAnimationDirection() == AnimationDirection::NORMAL ||
240                                 option.GetAnimationDirection() == AnimationDirection::ALTERNATE);
241     timingProtocol.SetAutoReverse(option.GetAnimationDirection() == AnimationDirection::ALTERNATE ||
242                                   option.GetAnimationDirection() == AnimationDirection::ALTERNATE_REVERSE);
243     timingProtocol.SetFillMode(static_cast<Rosen::FillMode>(option.GetFillMode()));
244     timingProtocol.SetFinishCallbackType(ToAnimationFinishCallbackType(option.GetFinishCallbackType()));
245     return timingProtocol;
246 }
247 } // namespace
248 
249 // Common template implementation
250 template<typename T, typename S>
AnimateWithVelocity(const AnimationOption & option,T value,T velocity,const FinishCallback & finishCallback)251 void NodeAnimatableProperty<T, S>::AnimateWithVelocity(
252     const AnimationOption& option, T value, T velocity, const FinishCallback& finishCallback)
253 {
254     const auto& timingProtocol = OptionToTimingProtocol(option);
255     auto targetValue = std::make_shared<RSAnimatableProperty<T>>(value);
256     auto initialVelocity = std::make_shared<RSAnimatableProperty<T>>(velocity);
257     auto modifier = std::static_pointer_cast<RSNodeModifierImpl>(GetModifyImpl());
258     if (modifier) {
259         auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(modifier->GetProperty());
260         if (property) {
261             property->AnimateWithInitialVelocity(timingProtocol,
262                 NativeCurveHelper::ToNativeCurve(option.GetCurve()),
263                 targetValue, initialVelocity, finishCallback, nullptr);
264         }
265     }
266 }
267 
268 template<typename T, typename S>
SetThresholdType(ThresholdType type)269 void NodeAnimatableProperty<T, S>::SetThresholdType(ThresholdType type)
270 {
271     auto modifier = std::static_pointer_cast<RSNodeModifierImpl>(GetModifyImpl());
272     CHECK_NULL_VOID(modifier);
273     auto property = std::static_pointer_cast<RSPropertyBase>(modifier->GetProperty());
274     CHECK_NULL_VOID(property);
275     property->SetThresholdType(static_cast<Rosen::ThresholdType>(type));
276 }
277 
278 template<typename T, typename S>
SetPropertyUnit(PropertyUnit unit)279 void NodeAnimatableProperty<T, S>::SetPropertyUnit(PropertyUnit unit)
280 {
281     auto modifier = std::static_pointer_cast<RSNodeModifierImpl>(GetModifyImpl());
282     CHECK_NULL_VOID(modifier);
283     auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(modifier->GetProperty());
284     CHECK_NULL_VOID(property);
285     property->SetPropertyUnit(static_cast<Rosen::RSPropertyUnit>(unit));
286 }
287 
288 // Explicit template instantiations
289 template class NodeAnimatableProperty<float, AnimatablePropertyFloat>;
290 template class NodeAnimatableProperty<OffsetF, AnimatablePropertyOffsetF>;
291 } // namespace OHOS::Ace::NG
292