• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components_ng/render/adapter/rosen_modifier_adapter.h"
16 
17 #include <mutex>
18 #include <unordered_map>
19 
20 #include "base/utils/utils.h"
21 #include "core/components_ng/animation/animatable_arithmetic_proxy.h"
22 #include "core/components_ng/render/modifier_adapter.h"
23 
24 namespace OHOS::Ace::NG {
25 
26 std::unordered_map<int32_t, std::shared_ptr<RSModifier>> g_ModifiersMap;
27 std::mutex g_ModifiersMapLock;
28 
ConvertContentModifier(const RefPtr<Modifier> & modifier)29 std::shared_ptr<RSModifier> ConvertContentModifier(const RefPtr<Modifier>& modifier)
30 {
31     CHECK_NULL_RETURN(modifier, nullptr);
32     std::lock_guard<std::mutex> lock(g_ModifiersMapLock);
33     const auto& iter = g_ModifiersMap.find(modifier->GetId());
34     if (iter != g_ModifiersMap.end()) {
35         return iter->second;
36     }
37     auto modifierAdapter = std::make_shared<ContentModifierAdapter>(modifier);
38     g_ModifiersMap.emplace(modifier->GetId(), modifierAdapter);
39     return modifierAdapter;
40 }
41 
ConvertOverlayModifier(const RefPtr<Modifier> & modifier)42 std::shared_ptr<RSModifier> ConvertOverlayModifier(const RefPtr<Modifier>& modifier)
43 {
44     CHECK_NULL_RETURN(modifier, nullptr);
45     std::lock_guard<std::mutex> lock(g_ModifiersMapLock);
46     const auto& iter = g_ModifiersMap.find(modifier->GetId());
47     if (iter != g_ModifiersMap.end()) {
48         return iter->second;
49     }
50     auto modifierAdapter = std::make_shared<OverlayModifierAdapter>(modifier);
51     g_ModifiersMap.emplace(modifier->GetId(), modifierAdapter);
52     return modifierAdapter;
53 }
54 
RemoveModifier(int32_t modifierId)55 void ModifierAdapter::RemoveModifier(int32_t modifierId)
56 {
57     std::lock_guard<std::mutex> lock(g_ModifiersMapLock);
58     g_ModifiersMap.erase(modifierId);
59 }
60 
Draw(RSDrawingContext & context) const61 void ContentModifierAdapter::Draw(RSDrawingContext& context) const
62 {
63     // use dummy deleter avoid delete the SkCanvas by shared_ptr, its owned by context
64 #ifndef USE_ROSEN_DRAWING
65     std::shared_ptr<SkCanvas> skCanvas { context.canvas, [](SkCanvas*) {} };
66     RSCanvas canvas(&skCanvas);
67 #else
68     CHECK_NULL_VOID_NOLOG(context.canvas);
69 #endif
70     auto modifier = modifier_.Upgrade();
71     CHECK_NULL_VOID_NOLOG(modifier);
72 #ifndef USE_ROSEN_DRAWING
73     DrawingContext context_ = { canvas, context.width, context.height };
74 #else
75     DrawingContext context_ = { *context.canvas, context.width, context.height };
76 #endif
77     modifier->onDraw(context_);
78 }
79 
80 #define CONVERT_PROP(prop, srcType, propType)                                      \
81     if (AceType::InstanceOf<srcType>(prop)) {                                      \
82         auto castProp = AceType::DynamicCast<srcType>(prop);                       \
83         auto rsProp = std::make_shared<RSProperty<propType>>(castProp->Get());     \
84         castProp->SetUpCallbacks([rsProp]() -> propType { return rsProp->Get(); }, \
85             [rsProp](const propType& value) { rsProp->Set(value); });              \
86         return rsProp;                                                             \
87     }
88 
89 #define CONVERT_ANIMATABLE_PROP(prop, srcType, propType)                                 \
90     if (AceType::InstanceOf<srcType>(prop)) {                                            \
91         auto castProp = AceType::DynamicCast<srcType>(prop);                             \
92         auto rsProp = std::make_shared<RSAnimatableProperty<propType>>(castProp->Get()); \
93         castProp->SetUpCallbacks([rsProp]() -> propType { return rsProp->Get(); },       \
94             [rsProp](const propType& value) { rsProp->Set(value); },                     \
95             [rsProp]() -> propType { return rsProp->GetStagingValue(); });               \
96         rsProp->SetUpdateCallback(castProp->GetUpdateCallback());                        \
97         return rsProp;                                                                   \
98     }
99 
ConvertToRSProperty(const RefPtr<PropertyBase> & property)100 inline std::shared_ptr<RSPropertyBase> ConvertToRSProperty(const RefPtr<PropertyBase>& property)
101 {
102     // should manually add convert type here
103     CONVERT_PROP(property, PropertyBool, bool);
104     CONVERT_PROP(property, PropertySizeF, SizeF);
105     CONVERT_PROP(property, PropertyOffsetF, OffsetF);
106     CONVERT_PROP(property, PropertyInt, int32_t);
107     CONVERT_PROP(property, PropertyFloat, float);
108     CONVERT_PROP(property, PropertyString, std::string);
109     CONVERT_PROP(property, PropertyColor, Color);
110     CONVERT_PROP(property, PropertyRectF, RectF);
111     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyOffsetF, OffsetF);
112     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyUint8, uint8_t);
113     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyFloat, float);
114     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyColor, LinearColor);
115     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyVectorColor, GradientArithmetic);
116     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertyVectorFloat, LinearVector<float>);
117     CONVERT_ANIMATABLE_PROP(property, AnimatablePropertySizeF, SizeF);
118 
119     if (AceType::InstanceOf<AnimatableArithmeticProperty>(property)) {
120         auto castProp = AceType::DynamicCast<AnimatableArithmeticProperty>(property);
121         if (!castProp && !castProp->Get()) {
122             LOGE("ConvertToRSProperty: Failed converting to RSProperty - AnimatableArithmeticProperty is null");
123             return nullptr;
124         }
125         AnimatableArithmeticProxy proxy(castProp->Get());
126         auto rsProp = std::make_shared<RSAnimatableProperty<AnimatableArithmeticProxy>>(proxy);
127         auto getter = [rsProp]() -> RefPtr<CustomAnimatableArithmetic> { return rsProp->Get().GetObject(); };
128         auto setter = [rsProp](const RefPtr<CustomAnimatableArithmetic>& value) {
129             rsProp->Set(AnimatableArithmeticProxy(value));
130         };
131         castProp->SetUpCallbacks(getter, setter);
132         rsProp->SetUpdateCallback(
133             [cb = castProp->GetUpdateCallback()](const AnimatableArithmeticProxy& value) { cb(value.GetObject()); });
134         return rsProp;
135     }
136 
137     LOGE("ConvertToRSProperty failed!");
138     return nullptr;
139 }
140 
AttachProperties()141 void ContentModifierAdapter::AttachProperties()
142 {
143     auto modifier = modifier_.Upgrade();
144     if (!attachedProperties_.size() && modifier) {
145         for (const auto& property : modifier->GetAttachedProperties()) {
146             auto rsProperty = ConvertToRSProperty(property);
147             AttachProperty(rsProperty);
148             attachedProperties_.emplace_back(rsProperty);
149         }
150     }
151 }
152 
Draw(RSDrawingContext & context) const153 void OverlayModifierAdapter::Draw(RSDrawingContext& context) const
154 {
155     // use dummy deleter avoid delete the SkCanvas by shared_ptr, its owned by context
156 #ifndef USE_ROSEN_DRAWING
157     std::shared_ptr<SkCanvas> skCanvas { context.canvas, [](SkCanvas*) {} };
158     RSCanvas canvas(&skCanvas);
159 #else
160     CHECK_NULL_VOID_NOLOG(context.canvas);
161 #endif
162     auto modifier = modifier_.Upgrade();
163     CHECK_NULL_VOID_NOLOG(modifier);
164 #ifndef USE_ROSEN_DRAWING
165     DrawingContext context_ = { canvas, context.width, context.height };
166 #else
167     DrawingContext context_ = { *context.canvas, context.width, context.height };
168 #endif
169     modifier->onDraw(context_);
170 }
171 
AttachProperties()172 void OverlayModifierAdapter::AttachProperties()
173 {
174     auto modifier = modifier_.Upgrade();
175     if (attachedProperties_.empty() && modifier) {
176         for (const auto& property : modifier->GetAttachedProperties()) {
177             auto rsProperty = ConvertToRSProperty(property);
178             AttachProperty(rsProperty);
179             attachedProperties_.emplace_back(rsProperty);
180         }
181     }
182 }
183 
AddProperty(const RefPtr<PropertyBase> & property)184 void RSNodeModifierImpl::AddProperty(const RefPtr<PropertyBase>& property)
185 {
186     if (!attachedProperty_) {
187         auto rsProperty = ConvertToRSProperty(property);
188         AttachProperty(rsProperty);
189         attachedProperty_ = rsProperty;
190     }
191 }
192 } // namespace OHOS::Ace::NG
193