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 #ifndef RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H
17 #define RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H
18 
19 #include <type_traits>
20 #include <unistd.h>
21 
22 #include "animation/rs_animation_callback.h"
23 #include "animation/rs_implicit_animator.h"
24 #include "animation/rs_implicit_animator_map.h"
25 #include "animation/rs_motion_path_option.h"
26 #include "command/rs_node_showing_command.h"
27 #include "common/rs_color.h"
28 #include "common/rs_common_def.h"
29 #include "common/rs_macros.h"
30 #include "common/rs_vector2.h"
31 #include "common/rs_vector4.h"
32 #include "modifier/rs_animatable_arithmetic.h"
33 #include "modifier/rs_modifier_type.h"
34 #include "modifier/rs_render_property.h"
35 #include "pipeline/rs_node_map.h"
36 #include "property/rs_properties_def.h"
37 #include "render/rs_border.h"
38 #include "render/rs_filter.h"
39 #include "render/rs_image.h"
40 #include "render/rs_mask.h"
41 #include "render/rs_path.h"
42 #include "render/rs_shader.h"
43 #include "transaction/rs_transaction_proxy.h"
44 #include "ui/rs_node.h"
45 
46 #ifdef _WIN32
47 #include <windows.h>
48 #define gettid GetCurrentThreadId
49 #endif
50 
51 #ifdef __APPLE__
52 #define gettid getpid
53 #endif
54 
55 #ifdef __gnu_linux__
56 #include <sys/types.h>
57 #include <sys/syscall.h>
58 #define gettid []() -> int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); }
59 #endif
60 
61 namespace OHOS {
62 namespace Rosen {
63 // used to determine when the spring animation ends visually
64 enum class ThresholdType {
65     LAYOUT,  // 0.5f for properties like position, as the difference in properties by 0.5 appears visually unchanged
66     COARSE,  // 1.0f / 256.0f
67     MEDIUM,  // 1.0f / 1000.0f
68     FINE,    // 1.0f / 3072.0f
69     COLOR,   // 0.0f
70     DEFAULT, // 1.0f / 256.0f
71     ZERO,    // 0.0f for noanimatable property
72 };
73 
74 namespace {
75 constexpr float DEFAULT_NEAR_ZERO_THRESHOLD = 1.0f / 256.0f;
76 constexpr float FLOAT_NEAR_ZERO_COARSE_THRESHOLD = 1.0f / 256.0f;
77 constexpr float FLOAT_NEAR_ZERO_MEDIUM_THRESHOLD = 1.0f / 1000.0f;
78 constexpr float FLOAT_NEAR_ZERO_FINE_THRESHOLD = 1.0f / 3072.0f;
79 constexpr float COLOR_NEAR_ZERO_THRESHOLD = 0.0f;
80 constexpr float LAYOUT_NEAR_ZERO_THRESHOLD = 0.5f;
81 constexpr float ZERO = 0.0f;
82 } // namespace
83 
84 template<class...>
85 struct make_void { using type = void; };
86 template<class... T>
87 using void_t = typename make_void<T...>::type;
88 
89 template<class T, class = void>
90 struct supports_arithmetic : std::false_type {};
91 template<class T>
92 struct supports_arithmetic<T,
93     void_t<decltype(std::declval<T>() == std::declval<T>())>>
94         : std::true_type {};
95 
96 template<class T, class = void>
97 struct supports_animatable_arithmetic : std::false_type {};
98 template<class T>
99 struct supports_animatable_arithmetic<T,
100     void_t<decltype(std::declval<T>() + std::declval<T>()),
101         decltype(std::declval<T>() - std::declval<T>()),
102         decltype(std::declval<T>() * std::declval<float>()),
103         decltype(std::declval<T>() == std::declval<T>())>>
104     : std::true_type {};
105 
106 class RSC_EXPORT RSPropertyBase : public std::enable_shared_from_this<RSPropertyBase> {
107 public:
108     RSPropertyBase();
109     virtual ~RSPropertyBase() = default;
110 
111     PropertyId GetId() const
112     {
113         return id_;
114     }
115 
116     virtual void SetThresholdType(ThresholdType thresholdType) {}
117     virtual float GetThreshold() const
118     {
119         return 0.0f;
120     }
121 
122     virtual void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) {};
123 
124 protected:
125     virtual void SetIsCustom(bool isCustom) {}
126 
127     virtual bool GetIsCustom() const
128     {
129         return false;
130     }
131 
132     virtual void SetValue(const std::shared_ptr<RSPropertyBase>& value) {}
133 
134     virtual std::shared_ptr<RSPropertyBase> Clone() const
135     {
136         return std::make_shared<RSPropertyBase>();
137     }
138 
139     virtual void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) {}
140 
141     virtual RSRenderPropertyType GetPropertyType() const
142     {
143         return RSRenderPropertyType::INVALID;
144     }
145 
146     float GetThresholdByModifierType() const;
147 
148     virtual void UpdateOnAllAnimationFinish() {}
149     virtual void UpdateCustomAnimation() {}
150 
151     virtual void AddPathAnimation() {}
152 
153     virtual void RemovePathAnimation() {}
154 
155     virtual void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) {}
156 
157     void AttachModifier(const std::shared_ptr<RSModifier>& modifier)
158     {
159         modifier_ = modifier;
160     }
161 
162     void MarkModifierDirty();
163 
164     void MarkNodeDirty();
165 
166     void UpdateExtendModifierForGeometry(const std::shared_ptr<RSNode>& node);
167 
168     virtual std::shared_ptr<RSRenderPropertyBase> GetRenderProperty()
169     {
170         return std::make_shared<RSRenderPropertyBase>(id_);
171     }
172 
173     virtual bool GetShowingValueAndCancelAnimation()
174     {
175         return false;
176     }
177 
178     float GetThresholdByThresholdType(ThresholdType thresholdType) const;
179 
180     PropertyId id_;
181     RSModifierType type_ { RSModifierType::INVALID };
182     std::weak_ptr<RSNode> target_;
183     std::weak_ptr<RSModifier> modifier_;
184 
185 private:
186     virtual std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value)
187     {
188         return shared_from_this();
189     }
190 
191     virtual std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value)
192     {
193         return shared_from_this();
194     }
195 
196     virtual std::shared_ptr<RSPropertyBase> Multiply(const float scale)
197     {
198         return shared_from_this();
199     }
200 
201     virtual bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const
202     {
203         return true;
204     }
205 
206     friend std::shared_ptr<RSPropertyBase> operator+=(
207         const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
208     friend std::shared_ptr<RSPropertyBase> operator-=(
209         const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
210     friend std::shared_ptr<RSPropertyBase> operator*=(const std::shared_ptr<RSPropertyBase>& value, const float scale);
211     friend std::shared_ptr<RSPropertyBase> operator+(
212         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
213     friend std::shared_ptr<RSPropertyBase> operator-(
214         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
215     friend std::shared_ptr<RSPropertyBase> operator*(
216         const std::shared_ptr<const RSPropertyBase>& value, const float scale);
217     friend bool operator==(
218         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
219     friend bool operator!=(
220         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
221     friend class RSTransition;
222     friend class RSSpringAnimation;
223     friend class RSPropertyAnimation;
224     friend class RSPathAnimation;
225     friend class RSModifier;
226     friend class RSKeyframeAnimation;
227     friend class RSInterpolatingSpringAnimation;
228     friend class RSImplicitTransitionParam;
229     friend class RSImplicitSpringAnimationParam;
230     friend class RSImplicitKeyframeAnimationParam;
231     friend class RSImplicitInterpolatingSpringAnimationParam;
232     friend class RSImplicitCancelAnimationParam;
233     friend class RSImplicitCurveAnimationParam;
234     friend class RSImplicitAnimator;
235     friend class RSGeometryTransModifier;
236     friend class RSExtendedModifier;
237     friend class RSCustomTransitionEffect;
238     friend class RSCurveAnimation;
239     template<typename T1>
240     friend class RSAnimatableProperty;
241     template<uint16_t commandType, uint16_t commandSubType>
242     friend class RSGetShowingValueAndCancelAnimationTask;
243 };
244 
245 template<typename T>
246 class RSProperty : public RSPropertyBase {
247     static_assert(std::is_base_of_v<RSArithmetic<T>, T> || supports_arithmetic<T>::value);
248 
249 public:
250     RSProperty() : RSPropertyBase() {}
251     explicit RSProperty(const T& value) : RSPropertyBase()
252     {
253         stagingValue_ = value;
254     }
255     virtual ~RSProperty() = default;
256 
257     virtual void Set(const T& value)
258     {
259         if (ROSEN_EQ(value, stagingValue_) || !IsValid(value)) {
260             return;
261         }
262 
263         stagingValue_ = value;
264         auto node = target_.lock();
265         if (node == nullptr) {
266             return;
267         }
268 
269         MarkNodeDirty();
270         UpdateExtendModifierForGeometry(node);
271         if (isCustom_) {
272             MarkModifierDirty();
273         } else {
274             UpdateToRender(stagingValue_, UPDATE_TYPE_OVERWRITE);
275         }
276     }
277 
278     virtual T Get() const
279     {
280         return stagingValue_;
281     }
282 
283 protected:
284     void UpdateToRender(const T& value, PropertyUpdateType type) const
285     {}
286 
287     void SetValue(const std::shared_ptr<RSPropertyBase>& value) override
288     {
289         auto property = std::static_pointer_cast<RSProperty<T>>(value);
290         if (property != nullptr) {
291             stagingValue_ = property->stagingValue_;
292         }
293     }
294 
295     std::shared_ptr<RSPropertyBase> Clone() const override
296     {
297         return std::make_shared<RSProperty<T>>(stagingValue_);
298     }
299 
300     bool IsValid(const T& value)
301     {
302         return true;
303     }
304 
305     void SetIsCustom(bool isCustom) override
306     {
307         isCustom_ = isCustom;
308     }
309 
310     bool GetIsCustom() const override
311     {
312         return isCustom_;
313     }
314 
315     std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override
316     {
317         return std::make_shared<RSRenderProperty<T>>(stagingValue_, id_);
318     }
319 
320     T stagingValue_ {};
321     bool isCustom_ { false };
322 
323     friend class RSPathAnimation;
324     friend class RSImplicitAnimator;
325     friend class RSExtendedModifier;
326     friend class RSModifier;
327 };
328 
329 template<typename T>
330 class RSAnimatableProperty : public RSProperty<T> {
331     static_assert(std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<Color, T> ||
332                   std::is_same_v<Matrix3f, T> || std::is_same_v<Vector2f, T> || std::is_same_v<Vector4f, T> ||
333                   std::is_same_v<Quaternion, T> || std::is_same_v<std::shared_ptr<RSFilter>, T> ||
334                   std::is_same_v<Vector4<Color>, T> || std::is_base_of_v<RSAnimatableArithmetic<T>, T> ||
335                   supports_animatable_arithmetic<T>::value || std::is_same_v<RRect, T>);
336 
337 public:
338     RSAnimatableProperty() : RSProperty<T>() {}
339     explicit RSAnimatableProperty(const T& value) : RSProperty<T>(value)
340     {
341         showingValue_ = value;
342     }
343 
344     virtual ~RSAnimatableProperty() = default;
345 
346     void Set(const T& value) override
347     {
348         if (ROSEN_EQ(value, RSProperty<T>::stagingValue_) || !RSProperty<T>::IsValid(value)) {
349             return;
350         }
351 
352         auto node = RSProperty<T>::target_.lock();
353         if (node == nullptr) {
354             RSProperty<T>::stagingValue_ = value;
355             return;
356         }
357 
358         RSProperty<T>::MarkNodeDirty();
359         RSProperty<T>::UpdateExtendModifierForGeometry(node);
360         auto implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
361         if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) {
362             auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
363             auto endValue = std::make_shared<RSAnimatableProperty<T>>(value);
364             if (motionPathOption_ != nullptr) {
365                 implicitAnimator->BeginImplicitPathAnimation(motionPathOption_);
366                 implicitAnimator->CreateImplicitAnimation(
367                     node, RSProperty<T>::shared_from_this(), startValue, endValue);
368                 implicitAnimator->EndImplicitPathAnimation();
369             } else {
370                 implicitAnimator->CreateImplicitAnimation(
371                     node, RSProperty<T>::shared_from_this(), startValue, endValue);
372             }
373             return;
374         }
375 
376         if (runningPathNum_ > 0) {
377             return;
378         }
379 
380         bool hasPropertyAnimation = node->HasPropertyAnimation(RSProperty<T>::id_);
381         T sendValue = value;
382         if (hasPropertyAnimation) {
383             sendValue = value - RSProperty<T>::stagingValue_;
384         }
385         RSProperty<T>::stagingValue_ = value;
386         if (RSProperty<T>::isCustom_) {
387             UpdateExtendedAnimatableProperty(sendValue, hasPropertyAnimation);
388         } else {
389             RSProperty<T>::UpdateToRender(
390                 sendValue, hasPropertyAnimation ? UPDATE_TYPE_INCREMENTAL : UPDATE_TYPE_OVERWRITE);
391         }
392     }
393 
394     void RequestCancelAnimation()
395     {
396         auto node = RSProperty<T>::target_.lock();
397         if (node == nullptr) {
398             return;
399         }
400         auto implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
401         if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) {
402             implicitAnimator->CancelImplicitAnimation(node, RSProperty<T>::shared_from_this());
403         }
404     }
405 
406     T Get() const override
407     {
408         if (RSProperty<T>::isCustom_) {
409             return showingValue_;
410         }
411         return RSProperty<T>::stagingValue_;
412     }
413 
414     T GetStagingValue() const
415     {
416         return RSProperty<T>::stagingValue_;
417     }
418 
419     bool GetShowingValueAndCancelAnimation() override
420     {
421         auto node = RSProperty<T>::target_.lock();
422         if (node == nullptr) {
423             return false;
424         }
425         if (!node->HasPropertyAnimation(this->id_) || this->GetIsCustom()) {
426             return true;
427         }
428         auto task = std::make_shared<RSNodeGetShowingPropertyAndCancelAnimation>(node->GetId(), GetRenderProperty());
429         RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(task, node->IsRenderServiceNode());
430         // when task is timeout, the caller need to decide whether to call this function again
431         if (!task || task->IsTimeout()) {
432             return false;
433         }
434 
435         // We also need to send a command to cancel animation, cause:
436         // case 1. some new animations have been added, but not flushed to render side,
437         // resulting these animations not canceled in task.
438         // case 2. the node or modifier has not yet been created on the render side, resulting in task failure.
439         node->CancelAnimationByProperty(this->id_, !RSProperty<T>::isCustom_);
440 
441         if (!task->IsSuccess()) {
442             // corresponding to case 2, as the new showing value is the same as staging value,
443             // need not to update the value
444             return true;
445         }
446 
447         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(task->GetProperty());
448         if (!renderProperty) {
449             return false;
450         }
451         RSProperty<T>::stagingValue_ = renderProperty->Get();
452         return true;
453     }
454 
455     void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) override
456     {
457         auto renderProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<T>>(rsRenderPropertyBase);
458         if (!renderProperty) {
459             return;
460         }
461         RSProperty<T>::stagingValue_ = renderProperty->Get();
462     }
463 
464     void SetUpdateCallback(const std::function<void(T)>& updateCallback)
465     {
466         propertyChangeListener_ = updateCallback;
467     }
468 
469     std::vector<std::shared_ptr<RSAnimation>> AnimateWithInitialVelocity(
470         const RSAnimationTimingProtocol& timingProtocol, const RSAnimationTimingCurve& timingCurve,
471         const std::shared_ptr<RSPropertyBase>& targetValue,
472         const std::shared_ptr<RSAnimatableProperty<T>>& velocity = nullptr,
473         const std::function<void()>& finishCallback = nullptr, const std::function<void()>& repeatCallback = nullptr)
474     {
475         auto endValue = std::static_pointer_cast<RSAnimatableProperty<T>>(targetValue);
476         if (!endValue) {
477             return {};
478         }
479 
480         auto node = RSProperty<T>::target_.lock();
481         if (!node) {
482             RSProperty<T>::stagingValue_ = endValue->Get();
483             return {};
484         }
485 
486         const auto& implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
487         if (!implicitAnimator) {
488             RSProperty<T>::stagingValue_ = endValue->Get();
489             return {};
490         }
491 
492         std::shared_ptr<AnimationFinishCallback> animationFinishCallback;
493         if (finishCallback) {
494             animationFinishCallback =
495                 std::make_shared<AnimationFinishCallback>(finishCallback, timingProtocol.GetFinishCallbackType());
496         }
497 
498         std::shared_ptr<AnimationRepeatCallback> animationRepeatCallback;
499         if (repeatCallback) {
500             animationRepeatCallback = std::make_shared<AnimationRepeatCallback>(repeatCallback);
501         }
502 
503         implicitAnimator->OpenImplicitAnimation(
504             timingProtocol, timingCurve, std::move(animationFinishCallback), std::move(animationRepeatCallback));
505         auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
506         if (velocity) {
507             implicitAnimator->CreateImplicitAnimationWithInitialVelocity(
508                 node, RSProperty<T>::shared_from_this(), startValue, endValue, velocity);
509         } else {
510             implicitAnimator->CreateImplicitAnimation(node, RSProperty<T>::shared_from_this(), startValue, endValue);
511         }
512 
513         return implicitAnimator->CloseImplicitAnimation();
514     }
515 
516     void SetPropertyUnit(RSPropertyUnit unit)
517     {
518         propertyUnit_ = unit;
519     }
520 
521 protected:
522     void UpdateOnAllAnimationFinish() override
523     {
524         RSProperty<T>::UpdateToRender(RSProperty<T>::stagingValue_, UPDATE_TYPE_FORCE_OVERWRITE);
525     }
526 
527     void UpdateCustomAnimation() override
528     {
529         if (RSProperty<T>::isCustom_) {
530             UpdateExtendedAnimatableProperty(RSProperty<T>::stagingValue_, false);
531         }
532     }
533 
534     void UpdateExtendedAnimatableProperty(const T& value, bool isDelta)
535     {
536         if (isDelta) {
537             if (renderProperty_ != nullptr) {
538                 renderProperty_->Set(renderProperty_->Get() + value);
539             }
540         } else {
541             showingValue_ = value;
542             RSProperty<T>::MarkModifierDirty();
543             if (renderProperty_ != nullptr) {
544                 renderProperty_->Set(value);
545             } else {
546                 NotifyPropertyChange();
547             }
548         }
549     }
550 
551     void AddPathAnimation() override
552     {
553         runningPathNum_ += 1;
554     }
555 
556     void RemovePathAnimation() override
557     {
558         runningPathNum_ -= 1;
559     }
560 
561     void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) override
562     {
563         auto renderProperty = std::static_pointer_cast<const RSRenderProperty<T>>(property);
564         if (renderProperty != nullptr) {
565             showingValue_ = renderProperty->Get();
566             NotifyPropertyChange();
567             RSProperty<T>::MarkModifierDirty();
568         }
569     }
570 
571     void SetValue(const std::shared_ptr<RSPropertyBase>& value) override
572     {
573         auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(value);
574         if (property != nullptr && property->GetPropertyType() == GetPropertyType()) {
575             RSProperty<T>::stagingValue_ = property->stagingValue_;
576         }
577     }
578 
579     std::shared_ptr<RSPropertyBase> Clone() const override
580     {
581         return std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
582     }
583 
584     void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) override
585     {
586         motionPathOption_ = motionPathOption;
587     }
588 
589     std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override
590     {
591         if (!RSProperty<T>::isCustom_) {
592             return std::make_shared<RSRenderAnimatableProperty<T>>(
593                 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType(), propertyUnit_);
594         }
595 
596         if (renderProperty_ == nullptr) {
597             renderProperty_ = std::make_shared<RSRenderAnimatableProperty<T>>(
598                 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType(), propertyUnit_);
599             auto weak = RSProperty<T>::weak_from_this();
600             renderProperty_->SetUpdateUIPropertyFunc(
601                 [weak](const std::shared_ptr<RSRenderPropertyBase>& renderProperty) {
602                     auto property = weak.lock();
603                     if (property == nullptr) {
604                         return;
605                     }
606                     property->UpdateShowingValue(renderProperty);
607                 });
608         }
609         return renderProperty_;
610     }
611 
612     void NotifyPropertyChange()
613     {
614         if (propertyChangeListener_) {
615             propertyChangeListener_(showingValue_);
616         }
617     }
618 
619     void SetThresholdType(ThresholdType thresholdType) override
620     {
621         thresholdType_ = thresholdType;
622     }
623 
624     float GetThreshold() const override
625     {
626         return RSProperty<T>::GetThresholdByThresholdType(thresholdType_);
627     }
628 
629     T showingValue_ {};
630     std::shared_ptr<RSRenderAnimatableProperty<T>> renderProperty_;
631     int runningPathNum_ { 0 };
632     std::shared_ptr<RSMotionPathOption> motionPathOption_ {};
633     std::function<void(T)> propertyChangeListener_;
634     ThresholdType thresholdType_ { ThresholdType::DEFAULT };
635     RSPropertyUnit propertyUnit_ { RSPropertyUnit::UNKNOWN };
636 
637 private:
638     RSRenderPropertyType GetPropertyType() const override
639     {
640         return RSRenderPropertyType::INVALID;
641     }
642 
643     std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) override
644     {
645         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
646         if (animatableProperty != nullptr) {
647             RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ + animatableProperty->stagingValue_;
648         }
649         return RSProperty<T>::shared_from_this();
650     }
651 
652     std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) override
653     {
654         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
655         if (animatableProperty != nullptr) {
656             RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ - animatableProperty->stagingValue_;
657         }
658         return RSProperty<T>::shared_from_this();
659     }
660 
661     std::shared_ptr<RSPropertyBase> Multiply(const float scale) override
662     {
663         RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ * scale;
664         return RSProperty<T>::shared_from_this();
665     }
666 
667     bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const override
668     {
669         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
670         if (animatableProperty != nullptr) {
671             return RSProperty<T>::stagingValue_ == animatableProperty->stagingValue_;
672         }
673         return true;
674     }
675 
676     friend class RSPropertyAnimation;
677     friend class RSPathAnimation;
678     friend class RSExtendedModifier;
679     friend class RSModifier;
680 };
681 
682 template<>
683 RSC_EXPORT void RSProperty<bool>::UpdateToRender(const bool& value, PropertyUpdateType type) const;
684 template<>
685 RSC_EXPORT void RSProperty<float>::UpdateToRender(const float& value, PropertyUpdateType type) const;
686 template<>
687 RSC_EXPORT void RSProperty<int>::UpdateToRender(const int& value, PropertyUpdateType type) const;
688 template<>
689 RSC_EXPORT void RSProperty<Color>::UpdateToRender(const Color& value, PropertyUpdateType type) const;
690 template<>
691 RSC_EXPORT void RSProperty<Gravity>::UpdateToRender(const Gravity& value, PropertyUpdateType type) const;
692 template<>
693 RSC_EXPORT void RSProperty<Matrix3f>::UpdateToRender(const Matrix3f& value, PropertyUpdateType type) const;
694 template<>
695 RSC_EXPORT void RSProperty<Quaternion>::UpdateToRender(const Quaternion& value, PropertyUpdateType type) const;
696 template<>
697 RSC_EXPORT void RSProperty<std::shared_ptr<RSFilter>>::UpdateToRender(
698     const std::shared_ptr<RSFilter>& value, PropertyUpdateType type) const;
699 template<>
700 RSC_EXPORT void RSProperty<std::shared_ptr<RSImage>>::UpdateToRender(
701     const std::shared_ptr<RSImage>& value, PropertyUpdateType type) const;
702 template<>
703 RSC_EXPORT void RSProperty<std::shared_ptr<RSMask>>::UpdateToRender(
704     const std::shared_ptr<RSMask>& value, PropertyUpdateType type) const;
705 template<>
706 RSC_EXPORT void RSProperty<std::shared_ptr<RSPath>>::UpdateToRender(
707     const std::shared_ptr<RSPath>& value, PropertyUpdateType type) const;
708 template<>
709 RSC_EXPORT void RSProperty<RSDynamicBrightnessPara>::UpdateToRender(
710     const RSDynamicBrightnessPara& value, PropertyUpdateType type) const;
711 template<>
712 RSC_EXPORT void RSProperty<RSWaterRipplePara>::UpdateToRender(
713     const RSWaterRipplePara& value, PropertyUpdateType type) const;
714 template<>
715 RSC_EXPORT void RSProperty<RSFlyOutPara>::UpdateToRender(
716     const RSFlyOutPara& value, PropertyUpdateType type) const;
717 template<>
718 RSC_EXPORT void RSProperty<std::shared_ptr<RSLinearGradientBlurPara>>::UpdateToRender(
719     const std::shared_ptr<RSLinearGradientBlurPara>& value, PropertyUpdateType type) const;
720 template<>
721 RSC_EXPORT void RSProperty<std::shared_ptr<MotionBlurParam>>::UpdateToRender(
722     const std::shared_ptr<MotionBlurParam>& value, PropertyUpdateType type) const;
723 template<>
724 RSC_EXPORT void RSProperty<std::shared_ptr<RSMagnifierParams>>::UpdateToRender(
725     const std::shared_ptr<RSMagnifierParams>& value, PropertyUpdateType type) const;
726 template<>
727 RSC_EXPORT void RSProperty<std::vector<std::shared_ptr<EmitterUpdater>>>::UpdateToRender(
728     const std::vector<std::shared_ptr<EmitterUpdater>>& value, PropertyUpdateType type) const;
729 template<>
730 RSC_EXPORT void RSProperty<std::shared_ptr<ParticleNoiseFields>>::UpdateToRender(
731     const std::shared_ptr<ParticleNoiseFields>& value, PropertyUpdateType type) const;
732 template<>
733 RSC_EXPORT void RSProperty<std::shared_ptr<RSShader>>::UpdateToRender(
734     const std::shared_ptr<RSShader>& value, PropertyUpdateType type) const;
735 template<>
736 RSC_EXPORT void RSProperty<Vector2f>::UpdateToRender(const Vector2f& value, PropertyUpdateType type) const;
737 template<>
738 RSC_EXPORT void RSProperty<Vector4<uint32_t>>::UpdateToRender(
739     const Vector4<uint32_t>& value, PropertyUpdateType type) const;
740 template<>
741 RSC_EXPORT void RSProperty<Vector4<Color>>::UpdateToRender(
742     const Vector4<Color>& value, PropertyUpdateType type) const;
743 template<>
744 RSC_EXPORT void RSProperty<Vector4f>::UpdateToRender(const Vector4f& value, PropertyUpdateType type) const;
745 template<>
746 RSC_EXPORT void RSProperty<RRect>::UpdateToRender(const RRect& value, PropertyUpdateType type) const;
747 
748 template<>
749 RSC_EXPORT bool RSProperty<float>::IsValid(const float& value);
750 template<>
751 RSC_EXPORT bool RSProperty<Vector2f>::IsValid(const Vector2f& value);
752 template<>
753 RSC_EXPORT bool RSProperty<Vector4f>::IsValid(const Vector4f& value);
754 
755 template<>
756 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<float>::GetPropertyType() const;
757 template<>
758 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Color>::GetPropertyType() const;
759 template<>
760 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Matrix3f>::GetPropertyType() const;
761 template<>
762 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector2f>::GetPropertyType() const;
763 template<>
764 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4f>::GetPropertyType() const;
765 template<>
766 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Quaternion>::GetPropertyType() const;
767 template<>
768 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<std::shared_ptr<RSFilter>>::GetPropertyType() const;
769 template<>
770 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4<Color>>::GetPropertyType() const;
771 template<>
772 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<RRect>::GetPropertyType() const;
773 } // namespace Rosen
774 } // namespace OHOS
775 
776 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H
777