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