• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifndef RENDER_SERVICE_BASE_MODIFIER_NG_RS_RENDER_MODIFIER_NG_H
17 #define RENDER_SERVICE_BASE_MODIFIER_NG_RS_RENDER_MODIFIER_NG_H
18 
19 #include "drawable/rs_misc_drawable.h"
20 #include "modifier/rs_render_property.h"
21 #include "modifier_ng/rs_modifier_ng_type.h"
22 #include "property/rs_properties.h"
23 
24 namespace OHOS::Rosen {
25 class RSRenderNode;
26 namespace ModifierNG {
27 class RSModifierContext {
28 public:
RSModifierContext(RSProperties & property)29     RSModifierContext(RSProperties& property) : properties_(property), canvas_(nullptr) {}
RSModifierContext(RSProperties & property,RSPaintFilterCanvas * canvas)30     RSModifierContext(RSProperties& property, RSPaintFilterCanvas* canvas) : properties_(property), canvas_(canvas) {}
31     RSProperties& properties_;
32     RSPaintFilterCanvas* canvas_;
33 };
34 // =============================================
35 // life cycle of RSRenderModifier
36 // 1. Create & animate
37 //   Create instance of RSRenderModifier and attach RSRenderProperty(s) to it, animate may change RSRenderProperty's
38 //   value
39 // 2. Apply
40 //   Apply RSRenderProperty(s) to staging value
41 class RSB_EXPORT RSRenderModifier : public std::enable_shared_from_this<RSRenderModifier> {
42 public:
43     RSRenderModifier() = default;
RSRenderModifier(ModifierId id)44     RSRenderModifier(ModifierId id) : id_(id) {}
45     virtual ~RSRenderModifier() = default;
46 
47     // RSRenderProperty(s) to staging value
Apply(RSPaintFilterCanvas * canvas,RSProperties & properties)48     virtual void Apply(RSPaintFilterCanvas* canvas, RSProperties& properties) {}
49     // Temporary solution, apply Modifier to RSProperties, used in legacy code
50     void ApplyLegacyProperty(RSProperties& properties);
51 
52     // For attaching/detaching RSRenderProperty to RSRenderModifier
53     void AttachProperty(RSPropertyType type, const std::shared_ptr<RSRenderPropertyBase>& property);
54     void DetachProperty(RSPropertyType type);
55 
56     // For attaching/detaching RSRenderModifier to RSRenderNode
57     bool IsAttached() const;
58     void OnAttachModifier(RSRenderNode& node);
59     void OnDetachModifier();
60     void SetDirty();
61 
62     // Only use in dump without consideration of time performance
63     RSPropertyType FindPropertyType(const std::shared_ptr<RSRenderPropertyBase> target) const;
64 
SetSingleFrameModifier(bool value)65     virtual void SetSingleFrameModifier(bool value) {}
66 
GetSingleFrameModifier()67     virtual bool GetSingleFrameModifier() const
68     {
69         return false;
70     }
71 
IsCustom()72     virtual bool IsCustom() const
73     {
74         return false;
75     }
76 
GetPropertyDrawCmdList()77     virtual Drawing::DrawCmdListPtr GetPropertyDrawCmdList() const
78     {
79         return nullptr;
80     }
81 
Dump(std::string & out,const std::string & splitStr)82     void Dump(std::string& out, const std::string& splitStr) const
83     {
84         for (auto& [type, property] : properties_) {
85             out += RSModifierTypeString::GetPropertyTypeString(type) + (IsCustom() ? ":[" : "");
86             property->Dump(out);
87             out += (IsCustom() ? "]" : "") + splitStr;
88         }
89     }
90 
91     template<typename T>
92     inline T Getter(RSPropertyType type, const T& defaultValue = {}) const
93     {
94         auto it = properties_.find(type);
95         if (it == properties_.end()) {
96             return defaultValue;
97         }
98         auto property = std::static_pointer_cast<RSRenderProperty<T>>(it->second);
99         return property->Get();
100     }
101 
102     template<typename T>
Setter(RSPropertyType type,const T & value)103     inline void Setter(RSPropertyType type, const T& value)
104     {
105         auto it = properties_.find(type);
106         if (it != properties_.end()) {
107             auto property = std::static_pointer_cast<RSRenderProperty<T>>(it->second);
108             property->Set(value);
109         } else {
110             // should not happen
111         }
112     }
113 
114     virtual RSModifierType GetType() const = 0;
115 
GetId()116     ModifierId GetId() const
117     {
118         return id_;
119     }
120 
GetProperty(RSPropertyType type)121     std::shared_ptr<RSRenderPropertyBase> GetProperty(RSPropertyType type)
122     {
123         auto it = properties_.find(type);
124         if (it == properties_.end()) {
125             return nullptr;
126         }
127         return it->second;
128     }
129 
130     bool Marshalling(Parcel& parcel) const;
131     [[nodiscard]] static std::shared_ptr<RSRenderModifier> Unmarshalling(Parcel& parcel);
132 
HasProperty(RSPropertyType type)133     inline bool HasProperty(RSPropertyType type) const
134     {
135         return properties_.count(type);
136     }
137 
GetPropertySize()138     size_t GetPropertySize()
139     {
140         size_t size = 0;
141         for (auto& [type, property] : properties_) {
142             if (property != nullptr) {
143                 size += property->GetSize();
144             }
145         }
146         return size;
147     }
148 
149     template<typename T>
150     static std::shared_ptr<RSRenderModifier> MakeRenderModifier(RSModifierType modifierType,
151         const std::shared_ptr<RSRenderProperty<T>>& property, ModifierId id = 0,
152         RSPropertyType propertyType = RSPropertyType::INVALID)
153     {
154         const auto& constructor = RSRenderModifier::ConstructorLUT_[static_cast<uint16_t>(modifierType)];
155         if (constructor == nullptr) {
156             return nullptr;
157         }
158         auto rawPointer = constructor();
159         if (rawPointer == nullptr) {
160             return nullptr;
161         }
162         std::shared_ptr<RSRenderModifier> renderModifier(rawPointer);
163         if (propertyType == RSPropertyType::INVALID) {
164             renderModifier->properties_.emplace(ModifierTypeConvertor::GetPropertyType(modifierType), property);
165         } else {
166             renderModifier->properties_.emplace(propertyType, property);
167         }
168         if (id > 0) {
169             renderModifier->id_ = id;
170         }
171         return renderModifier;
172     }
173 
174     using ResetFunc = void (*)(RSProperties& properties);
175     static const std::unordered_map<RSModifierType, ResetFunc>& GetResetFuncMap();
176 
177 protected:
178     // only accept properties on white list ?
179     ModifierId id_ = 0;
180     bool dirty_ = true;
181     std::weak_ptr<RSRenderNode> target_;
182 
183     // sub-class should not directly access properties_, use GetPropertyValue instead
184     std::map<RSPropertyType, std::shared_ptr<RSRenderPropertyBase>> properties_;
185 
186     template<typename T, auto Setter>
PropertyApplyHelper(RSProperties & properties,RSRenderPropertyBase & property)187     static void PropertyApplyHelper(RSProperties& properties, RSRenderPropertyBase& property)
188     {
189         const auto& value = static_cast<RSRenderProperty<T>&>(property).GetRef();
190         (properties.*Setter)(value);
191     }
192 
193     template<typename T, auto Setter, auto Getter>
PropertyApplyHelperAdd(RSProperties & properties,RSRenderPropertyBase & property)194     static void PropertyApplyHelperAdd(RSProperties& properties, RSRenderPropertyBase& property)
195     {
196         const auto& orig = (properties.*Getter)();
197         const auto& value = static_cast<RSRenderProperty<T>&>(property).GetRef();
198         const auto newValue = Add(orig, value);
199         (properties.*Setter)(newValue);
200     }
201 
202     template<typename T, auto Setter, auto Getter>
PropertyApplyHelperMultiply(RSProperties & properties,RSRenderPropertyBase & property)203     static void PropertyApplyHelperMultiply(RSProperties& properties, RSRenderPropertyBase& property)
204     {
205         const auto& orig = (properties.*Getter)();
206         const auto& value = static_cast<RSRenderProperty<T>&>(property).GetRef();
207         const auto newValue = Multiply(orig, value);
208         (properties.*Setter)(newValue);
209     }
210 
211     virtual void OnSetDirty();
212 
213     using LegacyPropertyApplier = std::function<void(RSProperties& context, RSRenderPropertyBase&)>;
214     using LegacyPropertyApplierMap = std::unordered_map<RSPropertyType, LegacyPropertyApplier>;
215 
216     static const LegacyPropertyApplierMap emptyLegacyPropertyApplierMap_;
217 
GetLegacyPropertyApplierMap()218     virtual const LegacyPropertyApplierMap& GetLegacyPropertyApplierMap() const
219     {
220         return emptyLegacyPropertyApplierMap_;
221     };
222 
223 private:
224     using Constructor = std::function<std::shared_ptr<RSRenderModifier>()>;
225     static std::array<Constructor, MODIFIER_TYPE_COUNT> ConstructorLUT_;
226 
227     template<typename T>
Add(const T & a,const T & b)228     static T Add(const T& a, const T& b)
229     {
230         return a + b;
231     }
232 
233     template<typename T>
Add(const std::optional<T> & a,const T & b)234     static T Add(const std::optional<T>& a, const T& b)
235     {
236         return a.has_value() ? *a + b : b;
237     }
238 
239     template<typename T>
Add(const std::optional<T> & a,const std::optional<T> & b)240     static T Add(const std::optional<T>& a, const std::optional<T>& b)
241     {
242         if (a.has_value() && b.has_value()) {
243             return *a + *b;
244         }
245         if (!a.has_value() && b.has_value()) {
246             return *b;
247         }
248         if (a.has_value() && !b.has_value()) {
249             return *a;
250         }
251         return {};
252     }
253 
254     template<typename T>
Multiply(const T & a,const T & b)255     static T Multiply(const T& a, const T& b)
256     {
257         return a * b;
258     }
259 
260     template<typename T>
Multiply(const std::optional<T> & a,const T & b)261     static T Multiply(const std::optional<T>& a, const T& b)
262     {
263         return a.has_value() ? *a * b : b;
264     }
265 
266     friend class RSModifier;
267     friend class OHOS::Rosen::DrawableV2::RSCustomClipToFrameDrawable;
268     friend class OHOS::Rosen::DrawableV2::RSEnvFGColorDrawable;
269     friend class OHOS::Rosen::DrawableV2::RSEnvFGColorStrategyDrawable;
270     friend class OHOS::Rosen::RSRenderNode;
271 };
272 
273 // =============================================
274 // modifiers that can be recorded as display list
275 class RSB_EXPORT RSDisplayListRenderModifier : public RSRenderModifier {
276 protected:
277     RSDisplayListRenderModifier() = default;
278     ~RSDisplayListRenderModifier() override = default;
279 };
280 
281 // Holds DrawCmdList
282 template<RSModifierType type>
283 class RSB_EXPORT RSCustomRenderModifier : public RSDisplayListRenderModifier {
284 public:
285     RSCustomRenderModifier() = default;
286     ~RSCustomRenderModifier() override = default;
287 
288     static inline constexpr auto Type = type;
289 
GetType()290     RSModifierType GetType() const override
291     {
292         return Type;
293     };
294 
IsCustom()295     bool IsCustom() const override
296     {
297         return true;
298     }
299 
SetSingleFrameModifier(bool value)300     void SetSingleFrameModifier(bool value) override
301     {
302         isSingleFrameModifier_ = value;
303     }
304 
GetSingleFrameModifier()305     bool GetSingleFrameModifier() const override
306     {
307         return isSingleFrameModifier_;
308     }
309 
GetPropertyDrawCmdList()310     Drawing::DrawCmdListPtr GetPropertyDrawCmdList() const override
311     {
312         return Getter<Drawing::DrawCmdListPtr>(ModifierTypeConvertor::GetPropertyType(GetType()), nullptr);
313     }
314 
315     void Apply(RSPaintFilterCanvas* canvas, RSProperties& properties) override;
316 
317 protected:
318     bool isSingleFrameModifier_ = false;
319 
320 private:
321     void OnSetDirty() override;
322 };
323 
324 class RSB_EXPORT RSFilterRenderModifier : public RSRenderModifier {
325 protected:
326     RSFilterRenderModifier() = default;
327     ~RSFilterRenderModifier() override = default;
328 
IsForeground()329     virtual bool IsForeground() const
330     {
331         return false;
332     }
333 };
334 } // namespace ModifierNG
335 } // namespace OHOS::Rosen
336 #endif // RENDER_SERVICE_BASE_MODIFIER_NG_RS_RENDER_MODIFIER_NG_H
337