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