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