• 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 
16 /**
17  * @addtogroup RenderNodeDisplay
18  * @{
19  *
20  * @brief Display render nodes.
21  */
22 
23 /**
24  * @file rs_property.h
25  *
26  * @brief Defines the properties and methods of RSPropertyBase and its derived classes.
27  */
28 
29 #ifndef RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H
30 #define RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H
31 
32 #include <type_traits>
33 #include <unistd.h>
34 
35 #include "animation/rs_animation_callback.h"
36 #include "animation/rs_animation_trace_utils.h"
37 #include "animation/rs_implicit_animator.h"
38 #include "animation/rs_implicit_animator_map.h"
39 #include "animation/rs_motion_path_option.h"
40 #include "command/rs_node_showing_command.h"
41 #include "common/rs_color.h"
42 #include "common/rs_common_def.h"
43 #include "common/rs_macros.h"
44 #include "common/rs_vector2.h"
45 #include "common/rs_vector4.h"
46 #include "modifier/rs_animatable_arithmetic.h"
47 #include "modifier/rs_render_property.h"
48 #include "pipeline/rs_node_map.h"
49 #include "transaction/rs_transaction_proxy.h"
50 #include "ui/rs_node.h"
51 #include "ui/rs_ui_context.h"
52 
53 #ifdef _WIN32
54 #include <windows.h>
55 #define gettid GetCurrentThreadId
56 #endif
57 
58 #ifdef __APPLE__
59 #define gettid getpid
60 #endif
61 
62 #ifdef __gnu_linux__
63 #include <sys/types.h>
64 #include <sys/syscall.h>
65 #define gettid []() -> int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); }
66 #endif
67 
68 namespace OHOS {
69 namespace Rosen {
70 namespace ModifierNG {
71 class RSModifier;
72 class RSForegroundFilterModifier;
73 class RSBackgroundFilterModifier;
74 }
75 class RSFilter;
76 class RSImage;
77 class RSMask;
78 class RSPath;
79 class RSNGFilterBase;
80 class RSNGMaskBase;
81 class RSLinearGradientBlurPara;
82 class MotionBlurParam;
83 class RSMagnifierParams;
84 class ParticleNoiseFields;
85 class RSShader;
86 class RSNGEffectUtils;
87 
88 /**
89  * @brief Defines different types of thresholds for spring animation.
90  *
91  * Used to determine when the spring animation ends visually
92  */
93 enum class ThresholdType {
94     /** 0.5f for properties like position, as the difference in properties by 0.5 appears visually unchanged. */
95     LAYOUT,
96     /** 1.0f / 256.0f */
97     COARSE,
98     /** 1.0f / 1000.0f */
99     MEDIUM,
100     /** 1.0f / 3072.0f */
101     FINE,
102     /** 0.0f */
103     COLOR,
104     /** 1.0f / 256.0f */
105     DEFAULT,
106     /** 0.0f for noanimatable property */
107     ZERO,
108 };
109 
110 /**
111  * @class RSPropertyBase
112  *
113  * @brief The base class for properties.
114  *
115  * This class provides a common interface for all property types.
116  */
117 class RSC_EXPORT RSPropertyBase : public std::enable_shared_from_this<RSPropertyBase> {
118 public:
119     /**
120      * @brief Constructor for RSPropertyBase.
121      */
122     RSPropertyBase();
123 
124     /**
125      * @brief Destructor for RSPropertyBase.
126      */
127     virtual ~RSPropertyBase() = default;
128 
129     /**
130      * @brief Gets the ID of the property.
131      *
132      * @return The ID of the property.
133      */
GetId()134     PropertyId GetId() const
135     {
136         return id_;
137     }
138 
139     /**
140      * @brief Sets the threshold type for the property.
141      *
142      * @param thresholdType Indicates the threshold type to be set.
143      */
SetThresholdType(ThresholdType thresholdType)144     virtual void SetThresholdType(ThresholdType thresholdType) {}
145 
146     /**
147      * @brief Gets the threshold type for the property.
148      *
149      * @return The threshold type of the property.
150      */
GetThreshold()151     virtual float GetThreshold() const
152     {
153         return 0.0f;
154     }
155 
156     /**
157      * @brief Sets the value of the property from the render.
158      *
159      * @param rsRenderPropertyBase A shared pointer to the RSRenderPropertyBase object.
160      */
SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase> & rsRenderPropertyBase)161     virtual void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) {}
162 
GetPropertyTypeNG()163     virtual ModifierNG::RSPropertyType GetPropertyTypeNG() const
164     {
165         return ModifierNG::RSPropertyType::INVALID;
166     }
167 
SetPropertyTypeNG(const ModifierNG::RSPropertyType type)168     virtual void SetPropertyTypeNG(const ModifierNG::RSPropertyType type) {}
169 
IsPathAnimatable()170     inline bool IsPathAnimatable() const
171     {
172         auto type = GetPropertyTypeNG();
173         return (type == ModifierNG::RSPropertyType::BOUNDS || type == ModifierNG::RSPropertyType::FRAME ||
174             type == ModifierNG::RSPropertyType::TRANSLATE);
175     }
176 
177 protected:
178     virtual void SetIsCustom(bool isCustom) = 0;
179     virtual bool GetIsCustom() const = 0;
180     virtual void SetValue(const std::shared_ptr<RSPropertyBase>& value) = 0;
181     virtual std::shared_ptr<RSPropertyBase> Clone() const = 0;
SetMotionPathOption(const std::shared_ptr<RSMotionPathOption> & motionPathOption)182     virtual void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) {}
183 
184     virtual RSPropertyType GetPropertyType() const = 0;
185 
186     float GetThresholdByModifierType() const;
187 
UpdateOnAllAnimationFinish()188     virtual void UpdateOnAllAnimationFinish() {}
UpdateCustomAnimation()189     virtual void UpdateCustomAnimation() {}
AddPathAnimation()190     virtual void AddPathAnimation() {}
RemovePathAnimation()191     virtual void RemovePathAnimation() {}
192 
UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase> & property)193     virtual void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) {}
194 
195     void Attach(RSNode& node, std::weak_ptr<ModifierNG::RSModifier> modifier = {})
196     {
197         target_ = node.weak_from_this();
198         modifierNG_ = modifier;
199         node.RegisterProperty(shared_from_this());
200         OnAttach(node, modifier);
201     }
202 
OnAttach(RSNode & node,std::weak_ptr<ModifierNG::RSModifier> modifier)203     virtual void OnAttach(RSNode& node, std::weak_ptr<ModifierNG::RSModifier> modifier) {}
204 
Detach()205     void Detach()
206     {
207         if (auto node = target_.lock()) {
208             node->UnregisterProperty(GetId());
209         }
210         OnDetach();
211         target_.reset();
212         modifierNG_.reset();
213     }
214 
OnDetach()215     virtual void OnDetach() {}
216 
AttachModifier(const std::shared_ptr<ModifierNG::RSModifier> & modifier)217     void AttachModifier(const std::shared_ptr<ModifierNG::RSModifier>& modifier)
218     {
219         modifierNG_ = modifier;
220     }
221 
222     void MarkCustomModifierDirty();
223 
224     void MarkNodeDirty();
225 
226     void UpdateExtendModifierForGeometry(const std::shared_ptr<RSNode>& node);
227 
228     virtual std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() = 0;
229 
GetShowingValueAndCancelAnimation()230     virtual bool GetShowingValueAndCancelAnimation()
231     {
232         return false;
233     }
234 
235     float GetThresholdByThresholdType(ThresholdType thresholdType) const;
236 
237     PropertyId id_;
238     std::weak_ptr<RSNode> target_;
239     std::weak_ptr<ModifierNG::RSModifier> modifierNG_;
240 
241 private:
Add(const std::shared_ptr<const RSPropertyBase> & value)242     virtual std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value)
243     {
244         return shared_from_this();
245     }
246 
Minus(const std::shared_ptr<const RSPropertyBase> & value)247     virtual std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value)
248     {
249         return shared_from_this();
250     }
251 
Multiply(const float scale)252     virtual std::shared_ptr<RSPropertyBase> Multiply(const float scale)
253     {
254         return shared_from_this();
255     }
256 
IsEqual(const std::shared_ptr<const RSPropertyBase> & value)257     virtual bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const
258     {
259         return true;
260     }
261 
262     friend std::shared_ptr<RSPropertyBase> operator+=(
263         const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
264     friend std::shared_ptr<RSPropertyBase> operator-=(
265         const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
266     friend std::shared_ptr<RSPropertyBase> operator*=(const std::shared_ptr<RSPropertyBase>& value, const float scale);
267     friend std::shared_ptr<RSPropertyBase> operator+(
268         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
269     friend std::shared_ptr<RSPropertyBase> operator-(
270         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
271     friend std::shared_ptr<RSPropertyBase> operator*(
272         const std::shared_ptr<const RSPropertyBase>& value, const float scale);
273     friend bool operator==(
274         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
275     friend bool operator!=(
276         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
277     friend class RSTransition;
278     friend class RSSpringAnimation;
279     friend class RSPropertyAnimation;
280     friend class RSPathAnimation;
281     friend class RSModifier;
282     friend class ModifierNG::RSModifier;
283     friend class RSNode;
284     friend class RSBackgroundUIFilterModifier;
285     friend class RSForegroundUIFilterModifier;
286     friend class RSKeyframeAnimation;
287     friend class RSInterpolatingSpringAnimation;
288     friend class RSImplicitTransitionParam;
289     friend class RSImplicitSpringAnimationParam;
290     friend class RSImplicitKeyframeAnimationParam;
291     friend class RSImplicitInterpolatingSpringAnimationParam;
292     friend class RSImplicitCancelAnimationParam;
293     friend class RSImplicitCurveAnimationParam;
294     friend class RSImplicitAnimator;
295     friend class RSGeometryTransModifier;
296     friend class RSExtendedModifier;
297     friend class RSCustomTransitionEffect;
298     friend class RSCurveAnimation;
299     friend class ModifierNG::RSForegroundFilterModifier;
300     friend class ModifierNG::RSBackgroundFilterModifier;
301     template<typename T>
302     friend class RSAnimatableProperty;
303     template<uint16_t commandType, uint16_t commandSubType>
304     friend class RSGetShowingValueAndCancelAnimationTask;
305     friend class RSNGEffectUtils;
306 };
307 
308 /**
309  * @struct RSRenderPropertyTraits
310  *
311  * @brief Helper for getting type of RSRenderProperty.
312  */
313 template<typename T>
314 struct RSRenderPropertyTraits {
315     using Type = RSRenderProperty<T>;
316 };
317 
318 template<>
319 struct RSRenderPropertyTraits<std::shared_ptr<RSNGFilterBase>> {
320     using Type = RSRenderProperty<std::shared_ptr<RSNGRenderFilterBase>>;
321 };
322 
323 template<>
324 struct RSRenderPropertyTraits<std::shared_ptr<RSNGShaderBase>> {
325     using Type = RSRenderProperty<std::shared_ptr<RSNGRenderShaderBase>>;
326 };
327 
328 template<>
329 struct RSRenderPropertyTraits<std::shared_ptr<RSNGMaskBase>> {
330     using Type = RSRenderProperty<std::shared_ptr<RSNGRenderMaskBase>>;
331 };
332 
333 /**
334  * @class RSProperty
335  *
336  * @brief The class for properties.
337  */
338 template<typename T>
339 class RSProperty : public RSPropertyBase {
340     static_assert(std::is_base_of_v<RSArithmetic<T>, T> || supports_arithmetic<T>::value);
341 
342 public:
343     /**
344      * @brief Constructor for RSProperty.
345      */
346     RSProperty() : RSPropertyBase() {}
347 
348     /**
349      * @brief Constructor for RSProperty.
350      *
351      * @param value Indicates the staging value.
352      */
353     explicit RSProperty(const T& value) : RSPropertyBase()
354     {
355         stagingValue_ = value;
356     }
357 
358     /**
359      * @brief Destructor for RSProperty.
360      */
361     ~RSProperty() override = default;
362 
363     using ValueType = T;
364 
365     using RenderPropertyType = typename RSRenderPropertyTraits<T>::Type;
366 
367     virtual void Set(const T& value)
368     {
369         if (ROSEN_EQ(value, stagingValue_) || !IsValid(value)) {
370             return;
371         }
372 
373         stagingValue_ = value;
374         auto node = target_.lock();
375         if (node == nullptr) {
376             return;
377         }
378 
379         MarkNodeDirty();
380         UpdateExtendModifierForGeometry(node);
381         if (isCustom_) {
382             MarkCustomModifierDirty();
383         } else {
384             UpdateToRender(stagingValue_, UPDATE_TYPE_OVERWRITE);
385         }
386     }
387 
388     /**
389      * @brief Gets the value of the staging.
390      *
391      * @return The value of the staging.
392      */
393     virtual T Get() const
394     {
395         return stagingValue_;
396     }
397 
398     ModifierNG::RSPropertyType GetPropertyTypeNG() const override
399     {
400         return typeNG_;
401     }
402 
403     void SetPropertyTypeNG(const ModifierNG::RSPropertyType type) override
404     {
405         typeNG_ = type;
406     }
407 
408 protected:
409     RSPropertyType GetPropertyType() const override { return type_; }
410 
411     void UpdateToRender(const T& value, PropertyUpdateType type) const
412     {}
413 
414     void SetValue(const std::shared_ptr<RSPropertyBase>& value) override
415     {
416         auto property = std::static_pointer_cast<RSProperty<T>>(value);
417         if (property != nullptr) {
418             stagingValue_ = property->stagingValue_;
419         }
420     }
421 
422     std::shared_ptr<RSPropertyBase> Clone() const override
423     {
424         return std::make_shared<RSProperty<T>>(stagingValue_);
425     }
426 
427     void OnAttach(RSNode& node, std::weak_ptr<ModifierNG::RSModifier> modifier) override {}
428 
429     void OnDetach() override {}
430 
431     bool IsValid(const T& value)
432     {
433         return true;
434     }
435 
436     void SetIsCustom(bool isCustom) override
437     {
438         isCustom_ = isCustom;
439     }
440 
441     bool GetIsCustom() const override
442     {
443         return isCustom_;
444     }
445 
446     std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override
447     {
448         return std::make_shared<RSRenderProperty<T>>(stagingValue_, id_);
449     }
450 
451     inline static const RSPropertyType type_ = RSPropertyType::INVALID;
452     ModifierNG::RSPropertyType typeNG_ = ModifierNG::RSPropertyType::INVALID;
453 
454     T stagingValue_ {};
455     bool isCustom_ { false };
456 
457     friend class RSPathAnimation;
458     friend class RSImplicitAnimator;
459     friend class RSExtendedModifier;
460     friend class RSModifier;
461     friend class RSNGEffectUtils;
462 };
463 
464 /**
465  * @class RSAnimatableProperty
466  *
467  * @brief The class for animatable properties.
468  */
469 template<typename T>
470 class RSAnimatableProperty : public RSProperty<T> {
471     static_assert(std::is_floating_point_v<T> || std::is_same_v<Color, T> || std::is_same_v<Matrix3f, T> ||
472                   std::is_same_v<Vector2f, T> || std::is_same_v<Vector3f, T> || std::is_same_v<Vector4f, T> ||
473                   std::is_same_v<Quaternion, T> || std::is_same_v<Vector4<Color>, T> ||
474                   supports_animatable_arithmetic<T>::value || std::is_base_of_v<RSAnimatableArithmetic<T>, T> ||
475                   std::is_same_v<RRect, T>);
476 
477 public:
478     /**
479      * @brief Constructor for RSAnimatableProperty.
480      */
481     RSAnimatableProperty() : RSProperty<T>() {}
482 
483     /**
484      * @brief Constructor for RSAnimatableProperty.
485      *
486      * @param value Indicates the showing value.
487      */
488     explicit RSAnimatableProperty(const T& value) : RSProperty<T>(value)
489     {
490         showingValue_ = value;
491     }
492 
493     /**
494      * @brief Destructor for RSAnimatableProperty.
495      */
496     virtual ~RSAnimatableProperty() = default;
497 
498     using ValueType = T;
499 
500     using RenderPropertyType = RSRenderAnimatableProperty<T>;
501 
502     void Set(const T& value) override
503     {
504         if (ROSEN_EQ(value, RSProperty<T>::stagingValue_) || !RSProperty<T>::IsValid(value)) {
505             return;
506         }
507 
508         auto node = RSProperty<T>::target_.lock();
509         if (node == nullptr) {
510             RSProperty<T>::stagingValue_ = value;
511             return;
512         }
513 
514         RSProperty<T>::MarkNodeDirty();
515         RSProperty<T>::UpdateExtendModifierForGeometry(node);
516         auto rsUIContext = node->GetRSUIContext();
517         auto implicitAnimator = rsUIContext ? rsUIContext->GetRSImplicitAnimator() :
518             RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
519         if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) {
520             auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
521             auto endValue = std::make_shared<RSAnimatableProperty<T>>(value);
522             if (motionPathOption_ != nullptr) {
523                 implicitAnimator->BeginImplicitPathAnimation(motionPathOption_);
524                 implicitAnimator->CreateImplicitAnimation(
525                     node, RSProperty<T>::shared_from_this(), startValue, endValue);
526                 implicitAnimator->EndImplicitPathAnimation();
527             } else {
528                 implicitAnimator->CreateImplicitAnimation(
529                     node, RSProperty<T>::shared_from_this(), startValue, endValue);
530             }
531             return;
532         }
533 
534         if (runningPathNum_ > 0) {
535             return;
536         }
537 
538         bool hasPropertyAnimation = node->HasPropertyAnimation(RSProperty<T>::id_);
539         T sendValue = value;
540         if (hasPropertyAnimation) {
541             sendValue = value - RSProperty<T>::stagingValue_;
542             auto endValue = std::make_shared<RSAnimatableProperty<T>>(value);
543             RSAnimationTraceUtils::GetInstance().AddChangeAnimationValueTrace(
544                 RSProperty<T>::id_, endValue->GetRenderProperty());
545         }
546         RSProperty<T>::stagingValue_ = value;
547         if (RSProperty<T>::isCustom_) {
548             UpdateExtendedAnimatableProperty(sendValue, hasPropertyAnimation);
549         } else {
550             RSProperty<T>::UpdateToRender(
551                 sendValue, hasPropertyAnimation ? UPDATE_TYPE_INCREMENTAL : UPDATE_TYPE_OVERWRITE);
552         }
553     }
554 
555     /**
556      * @brief Requests the cancellation of an ongoing implicit animation.
557      */
558     void RequestCancelAnimation()
559     {
560         auto node = RSProperty<T>::target_.lock();
561         if (node == nullptr) {
562             return;
563         }
564         auto rsUIContext = node->GetRSUIContext();
565         auto implicitAnimator = rsUIContext ? rsUIContext->GetRSImplicitAnimator()
566                                             : RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
567         if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) {
568             implicitAnimator->CancelImplicitAnimation(node, RSProperty<T>::shared_from_this());
569         }
570     }
571 
572     T Get() const override
573     {
574         if (RSProperty<T>::isCustom_) {
575             return showingValue_;
576         }
577         return RSProperty<T>::stagingValue_;
578     }
579 
580     /**
581      * @brief Gets the staging value of the property.
582      * @return The staging value.
583      */
584     T GetStagingValue() const
585     {
586         return RSProperty<T>::stagingValue_;
587     }
588 
589     /**
590      * @brief Gets the showing value of the property and cancels the animation.
591      *
592      * @return true if the showing value was successfully got and the animation was canceled, or if no
593      *         animation was present or the property is custom; false if the task timed out or the property
594      *         could not be retrieved.
595      */
596     bool GetShowingValueAndCancelAnimation() override
597     {
598         auto node = RSProperty<T>::target_.lock();
599         if (node == nullptr) {
600             return false;
601         }
602         if (!node->HasPropertyAnimation(this->id_) || this->GetIsCustom()) {
603             return true;
604         }
605         auto task = std::make_shared<RSNodeGetShowingPropertyAndCancelAnimation>(node->GetId(), GetRenderProperty());
606         auto rsUIContext = node->GetRSUIContext();
607         if (rsUIContext != nullptr) {
608             auto transaction = rsUIContext->GetRSTransaction();
609             if (transaction != nullptr) {
610                 transaction->ExecuteSynchronousTask(task, node->IsRenderServiceNode());
611             }
612         } else {
613             auto transactionProxy = RSTransactionProxy::GetInstance();
614             if (transactionProxy != nullptr) {
615                 transactionProxy->ExecuteSynchronousTask(task, node->IsRenderServiceNode());
616             }
617         }
618 
619         // when task is timeout, the caller need to decide whether to call this function again
620         if (!task || task->IsTimeout()) {
621             return false;
622         }
623 
624         // We also need to send a command to cancel animation, cause:
625         // case 1. some new animations have been added, but not flushed to render side,
626         // resulting these animations not canceled in task.
627         // case 2. the node or modifier has not yet been created on the render side, resulting in task failure.
628         node->CancelAnimationByProperty(this->id_, !RSProperty<T>::isCustom_);
629 
630         if (!task->IsSuccess()) {
631             // corresponding to case 2, as the new showing value is the same as staging value,
632             // need not to update the value
633             return true;
634         }
635 
636         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(task->GetProperty());
637         if (!renderProperty) {
638             return false;
639         }
640         RSProperty<T>::stagingValue_ = renderProperty->Get();
641         return true;
642     }
643 
644     /**
645      * @brief Sets the value of the property from render.
646      *
647      * @param rsRenderPropertyBase A shared pointer to the RSRenderPropertyBase object.
648      */
649     void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) override
650     {
651         auto renderProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<T>>(rsRenderPropertyBase);
652         if (!renderProperty) {
653             return;
654         }
655         RSProperty<T>::stagingValue_ = renderProperty->Get();
656     }
657 
658     /**
659      * @brief Sets the callback function to be called when the property is updated.
660      *
661      * @param updateCallback The callback function to be set.
662      */
663     void SetUpdateCallback(const std::function<void(T)>& updateCallback)
664     {
665         propertyChangeListener_ = updateCallback;
666     }
667 
668     /**
669      * @brief Plays the animation.
670      *
671      * @param timingProtocol The protocol specifying the timing parameters for the animation (e.g., duration, delay).
672      * @param timingCurve The curve defining the pacing of the animation (e.g., linear, ease-in, custom).
673      * @param targetValue The target value to animate to, wrapped in a shared pointer to RSPropertyBase.
674      * @param velocity (Optional) The initial velocity for the animation, wrapped in a shared pointer to RSAnimatableProperty<T>.
675      * @param finishCallback (Optional) A callback function to be invoked when the animation finishes.
676      * @param repeatCallback (Optional) A callback function to be invoked when the animation repeats.
677      * @return std::vector<std::shared_ptr<RSAnimation>> A vector of shared pointers to the created RSAnimation objects.
678      *         Returns an empty vector if the animation could not be created.
679      */
680     std::vector<std::shared_ptr<RSAnimation>> AnimateWithInitialVelocity(
681         const RSAnimationTimingProtocol& timingProtocol, const RSAnimationTimingCurve& timingCurve,
682         const std::shared_ptr<RSPropertyBase>& targetValue,
683         const std::shared_ptr<RSAnimatableProperty<T>>& velocity = nullptr,
684         const std::function<void()>& finishCallback = nullptr, const std::function<void()>& repeatCallback = nullptr)
685     {
686         auto endValue = std::static_pointer_cast<RSAnimatableProperty<T>>(targetValue);
687         if (!endValue) {
688             return {};
689         }
690 
691         auto node = RSProperty<T>::target_.lock();
692         if (!node) {
693             RSProperty<T>::stagingValue_ = endValue->Get();
694             return {};
695         }
696         auto rsUIContext = node->GetRSUIContext();
697         const auto& implicitAnimator = rsUIContext ? rsUIContext->GetRSImplicitAnimator() :
698             RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
699         if (!implicitAnimator) {
700             RSProperty<T>::stagingValue_ = endValue->Get();
701             return {};
702         }
703 
704         std::shared_ptr<AnimationFinishCallback> animationFinishCallback;
705         if (finishCallback) {
706             animationFinishCallback =
707                 std::make_shared<AnimationFinishCallback>(finishCallback, timingProtocol.GetFinishCallbackType());
708         }
709 
710         std::shared_ptr<AnimationRepeatCallback> animationRepeatCallback;
711         if (repeatCallback) {
712             animationRepeatCallback = std::make_shared<AnimationRepeatCallback>(repeatCallback);
713         }
714 
715         implicitAnimator->OpenImplicitAnimation(
716             timingProtocol, timingCurve, std::move(animationFinishCallback), std::move(animationRepeatCallback));
717         auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
718         if (velocity) {
719             implicitAnimator->CreateImplicitAnimationWithInitialVelocity(
720                 node, RSProperty<T>::shared_from_this(), startValue, endValue, velocity);
721         } else {
722             implicitAnimator->CreateImplicitAnimation(node, RSProperty<T>::shared_from_this(), startValue, endValue);
723         }
724 
725         return implicitAnimator->CloseImplicitAnimation();
726     }
727 
728     /**
729      * @brief Sets the property unit.
730      *
731      * @param unit The property unit to be set.
732      */
733     void SetPropertyUnit(RSPropertyUnit unit)
734     {
735         propertyUnit_ = unit;
736     }
737 
738 protected:
739     void UpdateOnAllAnimationFinish() override
740     {
741         RSProperty<T>::UpdateToRender(RSProperty<T>::stagingValue_, UPDATE_TYPE_FORCE_OVERWRITE);
742     }
743 
744     void UpdateCustomAnimation() override
745     {
746         if (RSProperty<T>::isCustom_) {
747             UpdateExtendedAnimatableProperty(RSProperty<T>::stagingValue_, false);
748         }
749     }
750 
751     void UpdateExtendedAnimatableProperty(const T& value, bool isDelta)
752     {
753         if (isDelta) {
754             if (renderProperty_ != nullptr) {
755                 renderProperty_->Set(renderProperty_->Get() + value);
756             }
757         } else {
758             showingValue_ = value;
759             RSProperty<T>::MarkCustomModifierDirty();
760             if (renderProperty_ != nullptr) {
761                 renderProperty_->Set(value);
762             } else {
763                 NotifyPropertyChange();
764             }
765         }
766     }
767 
768     void AddPathAnimation() override
769     {
770         runningPathNum_ += 1;
771     }
772 
773     void RemovePathAnimation() override
774     {
775         runningPathNum_ -= 1;
776     }
777 
778     void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) override
779     {
780         auto renderProperty = std::static_pointer_cast<const RSRenderProperty<T>>(property);
781         if (renderProperty != nullptr) {
782             showingValue_ = renderProperty->Get();
783             NotifyPropertyChange();
784             RSProperty<T>::MarkCustomModifierDirty();
785         }
786     }
787 
788     void SetValue(const std::shared_ptr<RSPropertyBase>& value) override
789     {
790         auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(value);
791         if (property != nullptr && property->GetPropertyType() == RSProperty<T>::GetPropertyType()) {
792             RSProperty<T>::stagingValue_ = property->stagingValue_;
793         }
794     }
795 
796     std::shared_ptr<RSPropertyBase> Clone() const override
797     {
798         return std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
799     }
800 
801     void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) override
802     {
803         motionPathOption_ = motionPathOption;
804     }
805 
806     std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override
807     {
808         if (!RSProperty<T>::isCustom_) {
809             return std::make_shared<RSRenderAnimatableProperty<T>>(
810                 RSProperty<T>::stagingValue_, RSProperty<T>::id_, propertyUnit_);
811         }
812 
813         if (renderProperty_ == nullptr) {
814             renderProperty_ = std::make_shared<RSRenderAnimatableProperty<T>>(
815                 RSProperty<T>::stagingValue_, RSProperty<T>::id_, propertyUnit_);
816             auto weak = RSProperty<T>::weak_from_this();
817             renderProperty_->SetUpdateUIPropertyFunc(
818                 [weak](const std::shared_ptr<RSRenderPropertyBase>& renderProperty) {
819                     auto property = weak.lock();
820                     if (property == nullptr) {
821                         return;
822                     }
823                     property->UpdateShowingValue(renderProperty);
824                 });
825         }
826         return renderProperty_;
827     }
828 
829     void NotifyPropertyChange()
830     {
831         if (propertyChangeListener_) {
832             propertyChangeListener_(showingValue_);
833         }
834     }
835 
836     void SetThresholdType(ThresholdType thresholdType) override
837     {
838         thresholdType_ = thresholdType;
839     }
840 
841     float GetThreshold() const override
842     {
843         return RSProperty<T>::GetThresholdByThresholdType(thresholdType_);
844     }
845 
846     T showingValue_ {};
847     std::shared_ptr<RSRenderAnimatableProperty<T>> renderProperty_;
848     int runningPathNum_ { 0 };
849     std::shared_ptr<RSMotionPathOption> motionPathOption_ {};
850     std::function<void(T)> propertyChangeListener_;
851     ThresholdType thresholdType_ { ThresholdType::DEFAULT };
852     RSPropertyUnit propertyUnit_ { RSPropertyUnit::UNKNOWN };
853 
854 private:
855     std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) override
856     {
857         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
858         if (animatableProperty != nullptr) {
859             RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ + animatableProperty->stagingValue_;
860         }
861         return RSProperty<T>::shared_from_this();
862     }
863 
864     std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) override
865     {
866         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
867         if (animatableProperty != nullptr) {
868             RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ - animatableProperty->stagingValue_;
869         }
870         return RSProperty<T>::shared_from_this();
871     }
872 
873     std::shared_ptr<RSPropertyBase> Multiply(const float scale) override
874     {
875         RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ * scale;
876         return RSProperty<T>::shared_from_this();
877     }
878 
879     bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const override
880     {
881         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
882         if (animatableProperty != nullptr) {
883             return RSProperty<T>::stagingValue_ == animatableProperty->stagingValue_;
884         }
885         return true;
886     }
887 
888     friend class RSPropertyAnimation;
889     friend class RSPathAnimation;
890     friend class RSExtendedModifier;
891     friend class RSModifier;
892     friend class RSNGEffectUtils;
893 };
894 
895 template<>
896 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGFilterBase>>::OnAttach(RSNode& node,
897     std::weak_ptr<ModifierNG::RSModifier> modifier);
898 template<>
899 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGFilterBase>>::OnDetach();
900 template<>
901 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGFilterBase>>::Set(const std::shared_ptr<RSNGFilterBase>& value);
902 template<>
903 RSC_EXPORT std::shared_ptr<RSRenderPropertyBase> RSProperty<std::shared_ptr<RSNGFilterBase>>::GetRenderProperty();
904 template<>
905 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGShaderBase>>::OnAttach(RSNode& node,
906     std::weak_ptr<ModifierNG::RSModifier> modifier);
907 template<>
908 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGShaderBase>>::OnDetach();
909 template<>
910 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGShaderBase>>::Set(const std::shared_ptr<RSNGShaderBase>& value);
911 template<>
912 RSC_EXPORT std::shared_ptr<RSRenderPropertyBase> RSProperty<std::shared_ptr<RSNGShaderBase>>::GetRenderProperty();
913 
914 template<>
915 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGMaskBase>>::OnAttach(RSNode& node,
916     std::weak_ptr<ModifierNG::RSModifier> modifier);
917 template<>
918 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGMaskBase>>::OnDetach();
919 template<>
920 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGMaskBase>>::Set(const std::shared_ptr<RSNGMaskBase>& value);
921 template<>
922 RSC_EXPORT std::shared_ptr<RSRenderPropertyBase> RSProperty<std::shared_ptr<RSNGMaskBase>>::GetRenderProperty();
923 
924 template<>
925 RSC_EXPORT void RSProperty<bool>::UpdateToRender(const bool& value, PropertyUpdateType type) const;
926 template<>
927 RSC_EXPORT void RSProperty<float>::UpdateToRender(const float& value, PropertyUpdateType type) const;
928 template <>
929 RSC_EXPORT void RSProperty<std::vector<float>>::UpdateToRender(
930     const std::vector<float> &value, PropertyUpdateType type) const;
931 template <>
932 RSC_EXPORT void RSProperty<int>::UpdateToRender(const int &value, PropertyUpdateType type) const;
933 template<>
934 RSC_EXPORT void RSProperty<Color>::UpdateToRender(const Color& value, PropertyUpdateType type) const;
935 template<>
936 RSC_EXPORT void RSProperty<Gravity>::UpdateToRender(const Gravity& value, PropertyUpdateType type) const;
937 template<>
938 RSC_EXPORT void RSProperty<Matrix3f>::UpdateToRender(const Matrix3f& value, PropertyUpdateType type) const;
939 template<>
940 RSC_EXPORT void RSProperty<Quaternion>::UpdateToRender(const Quaternion& value, PropertyUpdateType type) const;
941 template<>
942 RSC_EXPORT void RSProperty<std::shared_ptr<RSImage>>::UpdateToRender(
943     const std::shared_ptr<RSImage>& value, PropertyUpdateType type) const;
944 template<>
945 RSC_EXPORT void RSProperty<std::shared_ptr<RSMask>>::UpdateToRender(
946     const std::shared_ptr<RSMask>& value, PropertyUpdateType type) const;
947 template<>
948 RSC_EXPORT void RSProperty<std::shared_ptr<RSPath>>::UpdateToRender(
949     const std::shared_ptr<RSPath>& value, PropertyUpdateType type) const;
950 template<>
951 RSC_EXPORT void RSProperty<RSWaterRipplePara>::UpdateToRender(
952     const RSWaterRipplePara& value, PropertyUpdateType type) const;
953 template<>
954 RSC_EXPORT void RSProperty<RSFlyOutPara>::UpdateToRender(
955     const RSFlyOutPara& value, PropertyUpdateType type) const;
956 template<>
957 RSC_EXPORT void RSProperty<std::shared_ptr<RSLinearGradientBlurPara>>::UpdateToRender(
958     const std::shared_ptr<RSLinearGradientBlurPara>& value, PropertyUpdateType type) const;
959 template<>
960 RSC_EXPORT void RSProperty<std::shared_ptr<MotionBlurParam>>::UpdateToRender(
961     const std::shared_ptr<MotionBlurParam>& value, PropertyUpdateType type) const;
962 template<>
963 RSC_EXPORT void RSProperty<std::shared_ptr<RSMagnifierParams>>::UpdateToRender(
964     const std::shared_ptr<RSMagnifierParams>& value, PropertyUpdateType type) const;
965 template<>
966 RSC_EXPORT void RSProperty<std::vector<std::shared_ptr<EmitterUpdater>>>::UpdateToRender(
967     const std::vector<std::shared_ptr<EmitterUpdater>>& value, PropertyUpdateType type) const;
968 template<>
969 RSC_EXPORT void RSProperty<std::shared_ptr<ParticleNoiseFields>>::UpdateToRender(
970     const std::shared_ptr<ParticleNoiseFields>& value, PropertyUpdateType type) const;
971 template<>
972 RSC_EXPORT void RSProperty<std::shared_ptr<RSShader>>::UpdateToRender(
973     const std::shared_ptr<RSShader>& value, PropertyUpdateType type) const;
974 template<>
975 RSC_EXPORT void RSProperty<Vector2f>::UpdateToRender(const Vector2f& value, PropertyUpdateType type) const;
976 template<>
977 RSC_EXPORT void RSProperty<Vector3f>::UpdateToRender(const Vector3f& value, PropertyUpdateType type) const;
978 template<>
979 RSC_EXPORT void RSProperty<Vector4<uint32_t>>::UpdateToRender(
980     const Vector4<uint32_t>& value, PropertyUpdateType type) const;
981 template<>
982 RSC_EXPORT void RSProperty<Vector4<Color>>::UpdateToRender(
983     const Vector4<Color>& value, PropertyUpdateType type) const;
984 template<>
985 RSC_EXPORT void RSProperty<Vector4f>::UpdateToRender(const Vector4f& value, PropertyUpdateType type) const;
986 template<>
987 RSC_EXPORT void RSProperty<RRect>::UpdateToRender(const RRect& value, PropertyUpdateType type) const;
988 template<>
989 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGFilterBase>>::UpdateToRender(
990     const std::shared_ptr<RSNGFilterBase>& value, PropertyUpdateType type) const;
991 template<>
992 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGShaderBase>>::UpdateToRender(
993     const std::shared_ptr<RSNGShaderBase>& value, PropertyUpdateType type) const;
994 template<>
995 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGMaskBase>>::UpdateToRender(
996     const std::shared_ptr<RSNGMaskBase>& value, PropertyUpdateType type) const;
997 
998 template<>
999 RSC_EXPORT bool RSProperty<float>::IsValid(const float& value);
1000 template<>
1001 RSC_EXPORT bool RSProperty<Vector2f>::IsValid(const Vector2f& value);
1002 template<>
1003 RSC_EXPORT bool RSProperty<Vector4f>::IsValid(const Vector4f& value);
1004 
1005 #define DECLARE_PROPERTY(T, TYPE_ENUM) \
1006 template<>                             \
1007 inline const RSPropertyType RSProperty<T>::type_ = RSPropertyType::TYPE_ENUM
1008 #define DECLARE_ANIMATABLE_PROPERTY(T, TYPE_ENUM) DECLARE_PROPERTY(T, TYPE_ENUM)
1009 
1010 #include "modifier/rs_property_def.in"
1011 
1012 #undef DECLARE_PROPERTY
1013 #undef DECLARE_ANIMATABLE_PROPERTY
1014 
1015 } // namespace Rosen
1016 } // namespace OHOS
1017 
1018 /** @} */
1019 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H
1020