• 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 #ifndef RENDER_SERVICE_BASE_EFFECT_RS_RENDER_EFFECT_TEMPLATE_H
16 #define RENDER_SERVICE_BASE_EFFECT_RS_RENDER_EFFECT_TEMPLATE_H
17 #include <tuple>
18 #include <type_traits>
19 
20 #ifdef USE_M133_SKIA
21 #include "src/core/SkChecksum.h"
22 #else
23 #include "src/core/SkOpts.h"
24 #endif
25 
26 #include "common/rs_optional_trace.h"
27 #include "effect/rs_render_property_tag.h"
28 #include "transaction/rs_marshalling_helper.h"
29 
30 namespace OHOS {
31 namespace Rosen {
32 
33 // forward declarations
34 namespace Drawing {
35 class GEVisualEffectContainer;
36 class GEVisualEffect;
37 } // namespace Drawing
38 class RSNGRenderMaskBase;
39 
40 class RSB_EXPORT RSNGRenderEffectHelper {
41 public:
42     template<typename Tag>
UpdateVisualEffectParam(std::shared_ptr<Drawing::GEVisualEffect> geFilter,const Tag & propTag)43     static void UpdateVisualEffectParam(std::shared_ptr<Drawing::GEVisualEffect> geFilter, const Tag& propTag)
44     {
45         if (!geFilter) {
46             return;
47         }
48         UpdateVisualEffectParamImpl(*geFilter, Tag::NAME, propTag.value_->Get());
49     }
50 
51     template<typename Tag>
CalculatePropTagHash(uint32_t & hash,const Tag & propTag)52     static void CalculatePropTagHash(uint32_t& hash, const Tag& propTag)
53     {
54         CalculatePropTagHashImpl(hash, propTag.value_->Get());
55     }
56 
GetEffectTypeString(RSNGEffectType type)57     static std::string GetEffectTypeString(RSNGEffectType type)
58     {
59         switch (type) {
60             case RSNGEffectType::INVALID: return "Invalid";
61             case RSNGEffectType::NONE: return "None";
62             case RSNGEffectType::BLUR: return "Blur";
63             case RSNGEffectType::DISPLACEMENT_DISTORT: return "DispDistort";
64             case RSNGEffectType::SOUND_WAVE: return "SoundWave";
65             case RSNGEffectType::EDGE_LIGHT: return "EdgeLight";
66             case RSNGEffectType::DISPERSION: return "Dispersion";
67             case RSNGEffectType::DIRECTION_LIGHT: return "DirectionLight";
68             case RSNGEffectType::BEZIER_WARP: return "BezierWarp";
69             case RSNGEffectType::COLOR_GRADIENT: return "ColorGradient";
70             case RSNGEffectType::RIPPLE_MASK: return "RippleMask";
71             case RSNGEffectType::DOUBLE_RIPPLE_MASK: return "DoubleRippleMask";
72             case RSNGEffectType::PIXEL_MAP_MASK: return "PixelMapMask";
73             case RSNGEffectType::CONTOUR_DIAGONAL_FLOW_LIGHT: return "ContourDiagonalFlowLight";
74             case RSNGEffectType::WAVY_RIPPLE_LIGHT: return "WavyRippleLight";
75             case RSNGEffectType::AURORA_NOISE: return "AuroraNoise";
76             case RSNGEffectType::PARTICLE_CIRCULAR_HALO: return "ParticleCircularHalo";
77             case RSNGEffectType::RADIAL_GRADIENT_MASK: return "RadialGradientMask";
78             case RSNGEffectType::WAVE_GRADIENT_MASK: return "WaveGradientMask";
79             case RSNGEffectType::MASK_TRANSITION: return "MaskTransition";
80             case RSNGEffectType::VARIABLE_RADIUS_BLUR: return "VariableRadiusBlur";
81             case RSNGEffectType::COLOR_GRADIENT_EFFECT: return "ColorGradientEffect";
82             case RSNGEffectType::LIGHT_CAVE: return "LightCave";
83             case RSNGEffectType::CONTENT_LIGHT: return "ContentLight";
84             case RSNGEffectType::BORDER_LIGHT: return "BorderLight";
85             default:
86                 return "UNKNOWN";
87         }
88     }
89 
90     static std::shared_ptr<Drawing::GEVisualEffect> CreateGEVisualEffect(RSNGEffectType type);
91     static void AppendToGEContainer(std::shared_ptr<Drawing::GEVisualEffectContainer>& ge,
92         std::shared_ptr<Drawing::GEVisualEffect> geShader);
93 
94 private:
95     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
96         const std::string& desc, float value);
97 
98     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
99         const std::string& desc, bool value);
100 
101     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
102         const std::string& desc, const Vector4f& value);
103 
104     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
105         const std::string& desc, const Vector3f& value);
106 
107     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
108         const std::string& desc, const Vector2f& value);
109 
110     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
111         const std::string& desc, std::shared_ptr<RSNGRenderMaskBase> value);
112 
113     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
114         const std::string& desc, const VectorVector2F& value);
115 
116     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
117         const std::string& desc, std::shared_ptr<Media::PixelMap> value);
118 
119     static void UpdateVisualEffectParamImpl(Drawing::GEVisualEffect& geFilter,
120         const std::string& desc, const std::vector<float>& value);
121 
122     static void CalculatePropTagHashImpl(uint32_t& hash, float value);
123 
124     static void CalculatePropTagHashImpl(uint32_t& hash, bool value);
125 
126     static void CalculatePropTagHashImpl(uint32_t& hash, const Vector4f& value);
127 
128     static void CalculatePropTagHashImpl(uint32_t& hash, const Vector3f& value);
129 
130     static void CalculatePropTagHashImpl(uint32_t& hash, const Vector2f& value);
131 
132     static void CalculatePropTagHashImpl(uint32_t& hash, std::shared_ptr<RSNGRenderMaskBase> value);
133 
134     static void CalculatePropTagHashImpl(uint32_t& hash, const VectorVector2F& value);
135 
136     static void CalculatePropTagHashImpl(uint32_t& hash, std::shared_ptr<Media::PixelMap> value);
137 
138     static void CalculatePropTagHashImpl(uint32_t& hash, const std::vector<float>& value);
139 
140 #ifdef USE_M133_SKIA
141     static constexpr auto hashFunc_ = SkChecksum::Hash32;
142 #else
143     static constexpr auto hashFunc_ = SkOpts::hash;
144 #endif
145 };
146 
147 template <typename Derived, size_t EffectCountLimit = 1000>
148 class RSNGRenderEffectBase : public std::enable_shared_from_this<Derived> {
149 public:
150     static constexpr size_t EFFECT_COUNT_LIMIT = EffectCountLimit;
151 
152     virtual ~RSNGRenderEffectBase() = default;
153     virtual RSNGEffectType GetType() const = 0;
154     virtual bool Marshalling(Parcel& parcel) const = 0;
155     virtual void Attach(RSRenderNode& node, const std::weak_ptr<ModifierNG::RSRenderModifier>& modifier) = 0;
156     virtual void Detach() = 0;
157     virtual void Dump(std::string& out) const = 0;
158     virtual std::string Dump() const = 0;
159     virtual uint32_t CalculateHash() = 0;
160     virtual void CalculateHashInner(uint32_t& hash) = 0;
ContainsType(RSNGEffectType type)161     bool ContainsType(RSNGEffectType type)
162     {
163         auto current = this;
164         while (current) {
165             if (current->GetType() == type) {
166                 return true;
167             }
168             current = current->nextEffect_.get();
169         }
170         return false;
171     }
172 
173 protected:
174     [[nodiscard]] virtual bool OnUnmarshalling(Parcel& parcel) = 0;
175 
DumpProperties(std::string & out)176     virtual void DumpProperties(std::string& out) const {}
177     virtual std::string DumpProperties() const = 0;
178 
GetEffectCount()179     size_t GetEffectCount() const
180     {
181         size_t count = 1;
182         auto current = nextEffect_;
183         while (current && count < EFFECT_COUNT_LIMIT) {
184             count++;
185             current = current->nextEffect_;
186         }
187         return count;
188     }
189 
190     std::shared_ptr<Derived> nextEffect_ = nullptr;
191 
192     template <typename U, typename R>
193     friend class RSNGEffectBase;
194 
195     template <typename U, RSNGEffectType T, typename... Tags>
196     friend class RSNGEffectTemplate;
197 };
198 
199 template <typename T>
200 struct is_render_property_tag : std::false_type {};
201 
202 template <const char* Name, class PropertyType>
203 struct is_render_property_tag<RenderPropertyTagBase<Name, PropertyType>> : std::true_type {};
204 
205 template <typename T>
206 inline constexpr bool is_render_property_tag_v = is_render_property_tag<T>::value;
207 
208 template <typename Base, RSNGEffectType Type, typename... PropertyTags>
209 class RSNGRenderEffectTemplate : public Base {
210     static_assert(std::is_base_of_v<RSNGRenderEffectBase<Base>, Base>,
211         "RSNGRenderEffectTemplate: Base must be a subclass of RSNGRenderEffectBase<Base>");
212     static_assert(Type != RSNGEffectType::INVALID, "RSNGRenderEffectTemplate: Type cannot be INVALID");
213     static_assert((is_render_property_tag_v<PropertyTags> && ...),
214         "RSNGRenderEffectTemplate: All properties must be render property tags");
215 
216 public:
217     RSNGRenderEffectTemplate() = default;
218     ~RSNGRenderEffectTemplate() override = default;
219     RSNGRenderEffectTemplate(std::tuple<PropertyTags...> properties) noexcept : properties_(std::move(properties)) {}
220     RSNGEffectType GetType() const override
221     {
222         return Type;
223     }
224 
225     template<typename Tag>
226     static constexpr bool Contains()
227     {
228         static_assert(is_render_property_tag_v<Tag>, "Tag must be a render property tag");
229         return (std::is_same_v<Tag, PropertyTags> || ...);
230     };
231 
232     template<typename Tag>
233     constexpr const auto& Getter() const
234     {
235         static_assert(is_render_property_tag_v<Tag>, "Tag must be a render property tag");
236         static_assert(sizeof...(PropertyTags) > 0, "Cannot call Getter: No properties are defined in this group.");
237         static_assert(Contains<Tag>(), "Target property not registered.");
238         return std::get<Tag>(properties_).value_;
239     }
240 
241     template<typename Tag>
242     constexpr void Setter(typename Tag::ValueType value)
243     {
244         static_assert(is_render_property_tag_v<Tag>, "Tag must be a render property tag");
245         static_assert(sizeof...(PropertyTags) > 0, "Cannot call Setter: No properties are defined in this group.");
246         static_assert(Contains<Tag>(), "Target property not registered.");
247         return std::get<Tag>(properties_).value_->Set(value);
248     }
249 
250     template<typename Tag>
251     void Dump(std::string& out) const
252     {
253         static_assert(is_render_property_tag_v<Tag>, "Tag must be a render property tag");
254         std::string tagName = Tag::NAME;
255         size_t pos = tagName.rfind('_');
256         if (pos != std::string::npos) {
257             tagName = tagName.substr(pos + 1);
258         }
259         out += tagName;
260         out += "[";
261         Getter<Tag>()->Dump(out);
262         out += "]";
263     }
264 
265     bool Marshalling(Parcel& parcel) const override
266     {
267         auto count = Base::GetEffectCount();
268         if (count > Base::EFFECT_COUNT_LIMIT) {
269             return false;
270         }
271 
272         if (!RSMarshallingHelper::Marshalling(parcel, static_cast<RSNGEffectTypeUnderlying>(Type))) {
273             return false;
274         }
275 
276         if (!std::apply(
277             [&parcel](const auto&... propTag) {
278                 return (RSMarshallingHelper::Marshalling(parcel, propTag.value_) && ...);
279             },
280             properties_)) {
281             return false;
282         }
283 
284         if (Base::nextEffect_) {
285             return Base::nextEffect_->Marshalling(parcel);
286         }
287 
288         return RSMarshallingHelper::Marshalling(parcel, END_OF_CHAIN);
289     }
290 
291     void Attach(RSRenderNode& node, const std::weak_ptr<ModifierNG::RSRenderModifier>& modifier) override
292     {
293         RS_OPTIONAL_TRACE_FMT("RSNGRenderEffectTemplate::Attach, Type:%s",
294             RSNGRenderEffectHelper::GetEffectTypeString(Type).c_str());
295         std::apply([&node, &modifier](const auto&... props) {
296                 (props.value_->Attach(node, modifier), ...);
297             },
298             properties_);
299         if (Base::nextEffect_) {
300             Base::nextEffect_->Attach(node, modifier);
301         }
302     }
303 
304     void Detach() override
305     {
306         RS_OPTIONAL_TRACE_FMT("RSNGRenderEffectTemplate::Detach, Type:%s",
307             RSNGRenderEffectHelper::GetEffectTypeString(Type).c_str());
308         std::apply([](const auto&... props) { (props.value_->Detach(), ...); }, properties_);
309         if (Base::nextEffect_) {
310             Base::nextEffect_->Detach();
311         }
312     }
313 
314     void Dump(std::string& out) const override
315     {
316         std::string descStr = ": ";
317         std::string splitStr = "--";
318 
319         out += RSNGRenderEffectHelper::GetEffectTypeString(GetType());
320         out += descStr;
321         DumpProperties(out);
322         if (Base::nextEffect_) {
323             out += splitStr;
324             Base::nextEffect_->Dump(out);
325         }
326     }
327 
328     std::string Dump() const override
329     {
330         std::string result;
331         Dump(result);
332         return result;
333     }
334 
335     uint32_t CalculateHash() override
336     {
337         uint32_t hash_ = 0;
338         CalculateHashInner(hash_);
339         return hash_;
340     }
341 
342     void CalculateHashInner(uint32_t& hash) override
343     {
344         std::apply(
345             [&hash](const auto&... props) {
346                 (RSNGRenderEffectHelper::CalculatePropTagHash(hash, props), ...);
347             },
348             properties_);
349 
350         if (Base::nextEffect_) {
351             Base::nextEffect_->CalculateHashInner(hash);
352         }
353     }
354 
355 protected:
356     [[nodiscard]] bool OnUnmarshalling(Parcel& parcel) override
357     {
358         // Type has been covered in Unmarshalling
359         if (!std::apply(
360             [&parcel](auto&... propTag) {
361                 return (RSMarshallingHelper::Unmarshalling(parcel, propTag.value_) && ...);
362             },
363             properties_)) {
364             return false;
365         }
366         return true;
367     }
368 
369     void DumpProperties(std::string& out) const override
370     {
371         std::string startStr = "[";
372         std::string splitStr = ", ";
373         std::string endStr = "]";
374 
375         out += startStr;
376         bool first = true;
377 
378         auto dumpFunc = [&](auto& out, const auto& tag) {
379             if (!first) out += splitStr;
380             first = false;
381             Dump<std::decay_t<decltype(tag)>>(out);
382         };
383         std::apply([&](const auto&... props) { (dumpFunc(out, props), ...); }, properties_);
384 
385         out += endStr;
386     }
387 
388     std::string DumpProperties() const override
389     {
390         std::string result;
391         DumpProperties(result);
392         return result;
393     }
394 
395     std::tuple<PropertyTags...> properties_;
396 
397     template <typename U, typename R>
398     friend class RSNGEffectBase;
399 
400     template <typename U, RSNGEffectType T, typename... Tags>
401     friend class RSNGEffectTemplate;
402 };
403 } // namespace Rosen
404 } // namespace OHOS
405 
406 #endif // RENDER_SERVICE_BASE_EFFECT_RS_RENDER_EFFECT_TEMPLATE_H
407