• 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 
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 UpdateExtendModifierForGeometry(const std::shared_ptr<RSNode>& node);
165 
166     virtual std::shared_ptr<RSRenderPropertyBase> GetRenderProperty()
167     {
168         return std::make_shared<RSRenderPropertyBase>(id_);
169     }
170 
171     virtual bool GetShowingValueAndCancelAnimation()
172     {
173         return false;
174     }
175 
176     float GetThresholdByThresholdType(ThresholdType thresholdType) const;
177 
178     PropertyId id_;
179     RSModifierType type_ { RSModifierType::INVALID };
180     std::weak_ptr<RSNode> target_;
181     std::weak_ptr<RSModifier> modifier_;
182 
183 private:
184     virtual std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value)
185     {
186         return shared_from_this();
187     }
188 
189     virtual std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value)
190     {
191         return shared_from_this();
192     }
193 
194     virtual std::shared_ptr<RSPropertyBase> Multiply(const float scale)
195     {
196         return shared_from_this();
197     }
198 
199     virtual bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const
200     {
201         return true;
202     }
203 
204     friend std::shared_ptr<RSPropertyBase> operator+=(
205         const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
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*=(const std::shared_ptr<RSPropertyBase>& value, const float scale);
209     friend std::shared_ptr<RSPropertyBase> operator+(
210         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
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>& value, const float scale);
215     friend bool operator==(
216         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
217     friend bool operator!=(
218         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
219     friend class RSTransition;
220     friend class RSSpringAnimation;
221     friend class RSPropertyAnimation;
222     friend class RSPathAnimation;
223     friend class RSModifier;
224     friend class RSKeyframeAnimation;
225     friend class RSInterpolatingSpringAnimation;
226     friend class RSImplicitTransitionParam;
227     friend class RSImplicitSpringAnimationParam;
228     friend class RSImplicitKeyframeAnimationParam;
229     friend class RSImplicitInterpolatingSpringAnimationParam;
230     friend class RSImplicitCancelAnimationParam;
231     friend class RSImplicitCurveAnimationParam;
232     friend class RSImplicitAnimator;
233     friend class RSGeometryTransModifier;
234     friend class RSExtendedModifier;
235     friend class RSCustomTransitionEffect;
236     friend class RSCurveAnimation;
237     template<typename T1>
238     friend class RSAnimatableProperty;
239     template<uint16_t commandType, uint16_t commandSubType>
240     friend class RSGetShowingValueAndCancelAnimationTask;
241 };
242 
243 template<typename T>
244 class RSProperty : public RSPropertyBase {
245     static_assert(std::is_base_of_v<RSArithmetic<T>, T> || supports_arithmetic<T>::value);
246 
247 public:
248     RSProperty() : RSPropertyBase() {}
249     explicit RSProperty(const T& value) : RSPropertyBase()
250     {
251         stagingValue_ = value;
252     }
253     virtual ~RSProperty() = default;
254 
255     virtual void Set(const T& value)
256     {
257         if (ROSEN_EQ(value, stagingValue_) || !IsValid(value)) {
258             return;
259         }
260 
261         stagingValue_ = value;
262         auto node = target_.lock();
263         if (node == nullptr) {
264             return;
265         }
266 
267         UpdateExtendModifierForGeometry(node);
268         if (isCustom_) {
269             MarkModifierDirty();
270         } else {
271             UpdateToRender(stagingValue_, UPDATE_TYPE_OVERWRITE);
272         }
273     }
274 
275     virtual T Get() const
276     {
277         return stagingValue_;
278     }
279 
280 protected:
281     void UpdateToRender(const T& value, PropertyUpdateType type) const
282     {}
283 
284     void SetValue(const std::shared_ptr<RSPropertyBase>& value) override
285     {
286         auto property = std::static_pointer_cast<RSProperty<T>>(value);
287         if (property != nullptr) {
288             stagingValue_ = property->stagingValue_;
289         }
290     }
291 
292     std::shared_ptr<RSPropertyBase> Clone() const override
293     {
294         return std::make_shared<RSProperty<T>>(stagingValue_);
295     }
296 
297     bool IsValid(const T& value)
298     {
299         return true;
300     }
301 
302     void SetIsCustom(bool isCustom) override
303     {
304         isCustom_ = isCustom;
305     }
306 
307     bool GetIsCustom() const override
308     {
309         return isCustom_;
310     }
311 
312     std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override
313     {
314         return std::make_shared<RSRenderProperty<T>>(stagingValue_, id_);
315     }
316 
317     T stagingValue_ {};
318     bool isCustom_ { false };
319 
320     friend class RSPathAnimation;
321     friend class RSImplicitAnimator;
322     friend class RSExtendedModifier;
323     friend class RSModifier;
324 };
325 
326 template<typename T>
327 class RSAnimatableProperty : public RSProperty<T> {
328     static_assert(std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<Color, T> ||
329                   std::is_same_v<Matrix3f, T> || std::is_same_v<Vector2f, T> || std::is_same_v<Vector4f, T> ||
330                   std::is_same_v<Quaternion, T> || std::is_same_v<std::shared_ptr<RSFilter>, T> ||
331                   std::is_same_v<Vector4<Color>, T> || std::is_base_of_v<RSAnimatableArithmetic<T>, T> ||
332                   supports_animatable_arithmetic<T>::value || std::is_same_v<RRect, T>);
333 
334 public:
335     RSAnimatableProperty() : RSProperty<T>() {}
336     explicit RSAnimatableProperty(const T& value) : RSProperty<T>(value)
337     {
338         showingValue_ = value;
339     }
340 
341     virtual ~RSAnimatableProperty() = default;
342 
343     void Set(const T& value) override
344     {
345         if (ROSEN_EQ(value, RSProperty<T>::stagingValue_) || !RSProperty<T>::IsValid(value)) {
346             return;
347         }
348 
349         auto node = RSProperty<T>::target_.lock();
350         if (node == nullptr) {
351             RSProperty<T>::stagingValue_ = value;
352             return;
353         }
354 
355         RSProperty<T>::UpdateExtendModifierForGeometry(node);
356         auto implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
357         if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) {
358             auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
359             auto endValue = std::make_shared<RSAnimatableProperty<T>>(value);
360             if (motionPathOption_ != nullptr) {
361                 implicitAnimator->BeginImplicitPathAnimation(motionPathOption_);
362                 implicitAnimator->CreateImplicitAnimation(
363                     node, RSProperty<T>::shared_from_this(), startValue, endValue);
364                 implicitAnimator->EndImplicitPathAnimation();
365             } else {
366                 implicitAnimator->CreateImplicitAnimation(
367                     node, RSProperty<T>::shared_from_this(), startValue, endValue);
368             }
369             return;
370         }
371 
372         if (runningPathNum_ > 0) {
373             return;
374         }
375 
376         bool hasPropertyAnimation = node->HasPropertyAnimation(RSProperty<T>::id_);
377         T sendValue = value;
378         if (hasPropertyAnimation) {
379             sendValue = value - RSProperty<T>::stagingValue_;
380         }
381         RSProperty<T>::stagingValue_ = value;
382         if (RSProperty<T>::isCustom_) {
383             UpdateExtendedAnimatableProperty(sendValue, hasPropertyAnimation);
384         } else {
385             RSProperty<T>::UpdateToRender(
386                 sendValue, hasPropertyAnimation ? UPDATE_TYPE_INCREMENTAL : UPDATE_TYPE_OVERWRITE);
387         }
388     }
389 
390     void RequestCancelAnimation()
391     {
392         auto node = RSProperty<T>::target_.lock();
393         if (node == nullptr) {
394             return;
395         }
396         auto implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
397         if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) {
398             implicitAnimator->CancelImplicitAnimation(node, RSProperty<T>::shared_from_this());
399         }
400     }
401 
402     T Get() const override
403     {
404         if (RSProperty<T>::isCustom_) {
405             return showingValue_;
406         }
407         return RSProperty<T>::stagingValue_;
408     }
409 
410     T GetStagingValue() const
411     {
412         return RSProperty<T>::stagingValue_;
413     }
414 
415     bool GetShowingValueAndCancelAnimation() override
416     {
417         auto node = RSProperty<T>::target_.lock();
418         if (node == nullptr) {
419             return false;
420         }
421         if (!node->HasPropertyAnimation(this->id_) || this->GetIsCustom()) {
422             return true;
423         }
424         auto task = std::make_shared<RSNodeGetShowingPropertyAndCancelAnimation>(node->GetId(), GetRenderProperty());
425         RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(task, node->IsRenderServiceNode());
426         // when task is timeout, the caller need to decide whether to call this function again
427         if (!task || task->IsTimeout()) {
428             return false;
429         }
430 
431         // We also need to send a command to cancel animation, cause:
432         // case 1. some new animations have been added, but not flushed to render side,
433         // resulting these animations not canceled in task.
434         // case 2. the node or modifier has not yet been created on the render side, resulting in task failure.
435         node->CancelAnimationByProperty(this->id_, !RSProperty<T>::isCustom_);
436 
437         if (!task->IsSuccess()) {
438             // corresponding to case 2, as the new showing value is the same as staging value,
439             // need not to update the value
440             return true;
441         }
442 
443         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(task->GetProperty());
444         if (!renderProperty) {
445             return false;
446         }
447         RSProperty<T>::stagingValue_ = renderProperty->Get();
448         return true;
449     }
450 
451     void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) override
452     {
453         auto renderProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<T>>(rsRenderPropertyBase);
454         if (!renderProperty) {
455             return;
456         }
457         RSProperty<T>::stagingValue_ = renderProperty->Get();
458     }
459 
460     void SetUpdateCallback(const std::function<void(T)>& updateCallback)
461     {
462         propertyChangeListener_ = updateCallback;
463     }
464 
465     std::vector<std::shared_ptr<RSAnimation>> AnimateWithInitialVelocity(
466         const RSAnimationTimingProtocol& timingProtocol, const RSAnimationTimingCurve& timingCurve,
467         const std::shared_ptr<RSPropertyBase>& targetValue,
468         const std::shared_ptr<RSAnimatableProperty<T>>& velocity = nullptr,
469         const std::function<void()>& finishCallback = nullptr, const std::function<void()>& repeatCallback = nullptr)
470     {
471         auto endValue = std::static_pointer_cast<RSAnimatableProperty<T>>(targetValue);
472         if (!endValue) {
473             return {};
474         }
475 
476         auto node = RSProperty<T>::target_.lock();
477         if (!node) {
478             RSProperty<T>::stagingValue_ = endValue->Get();
479             return {};
480         }
481 
482         const auto& implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
483         if (!implicitAnimator) {
484             RSProperty<T>::stagingValue_ = endValue->Get();
485             return {};
486         }
487 
488         std::shared_ptr<AnimationFinishCallback> animationFinishCallback;
489         if (finishCallback) {
490             animationFinishCallback =
491                 std::make_shared<AnimationFinishCallback>(finishCallback, timingProtocol.GetFinishCallbackType());
492         }
493 
494         std::shared_ptr<AnimationRepeatCallback> animationRepeatCallback;
495         if (repeatCallback) {
496             animationRepeatCallback = std::make_shared<AnimationRepeatCallback>(repeatCallback);
497         }
498 
499         implicitAnimator->OpenImplicitAnimation(
500             timingProtocol, timingCurve, std::move(animationFinishCallback), std::move(animationRepeatCallback));
501         auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
502         if (velocity) {
503             implicitAnimator->CreateImplicitAnimationWithInitialVelocity(
504                 node, RSProperty<T>::shared_from_this(), startValue, endValue, velocity);
505         } else {
506             implicitAnimator->CreateImplicitAnimation(node, RSProperty<T>::shared_from_this(), startValue, endValue);
507         }
508 
509         return implicitAnimator->CloseImplicitAnimation();
510     }
511 
512     void SetPropertyUnit(RSPropertyUnit unit)
513     {
514         propertyUnit_ = unit;
515     }
516 
517 protected:
518     void UpdateOnAllAnimationFinish() override
519     {
520         RSProperty<T>::UpdateToRender(RSProperty<T>::stagingValue_, UPDATE_TYPE_FORCE_OVERWRITE);
521     }
522 
523     void UpdateCustomAnimation() override
524     {
525         if (RSProperty<T>::isCustom_) {
526             UpdateExtendedAnimatableProperty(RSProperty<T>::stagingValue_, false);
527         }
528     }
529 
530     void UpdateExtendedAnimatableProperty(const T& value, bool isDelta)
531     {
532         if (isDelta) {
533             if (renderProperty_ != nullptr) {
534                 renderProperty_->Set(renderProperty_->Get() + value);
535             }
536         } else {
537             showingValue_ = value;
538             RSProperty<T>::MarkModifierDirty();
539             if (renderProperty_ != nullptr) {
540                 renderProperty_->Set(value);
541             } else {
542                 NotifyPropertyChange();
543             }
544         }
545     }
546 
547     void AddPathAnimation() override
548     {
549         runningPathNum_ += 1;
550     }
551 
552     void RemovePathAnimation() override
553     {
554         runningPathNum_ -= 1;
555     }
556 
557     void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) override
558     {
559         auto renderProperty = std::static_pointer_cast<const RSRenderProperty<T>>(property);
560         if (renderProperty != nullptr) {
561             showingValue_ = renderProperty->Get();
562             NotifyPropertyChange();
563             RSProperty<T>::MarkModifierDirty();
564         }
565     }
566 
567     void SetValue(const std::shared_ptr<RSPropertyBase>& value) override
568     {
569         auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(value);
570         if (property != nullptr && property->GetPropertyType() == GetPropertyType()) {
571             RSProperty<T>::stagingValue_ = property->stagingValue_;
572         }
573     }
574 
575     std::shared_ptr<RSPropertyBase> Clone() const override
576     {
577         return std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
578     }
579 
580     void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) override
581     {
582         motionPathOption_ = motionPathOption;
583     }
584 
585     std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override
586     {
587         if (!RSProperty<T>::isCustom_) {
588             return std::make_shared<RSRenderAnimatableProperty<T>>(
589                 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType(), propertyUnit_);
590         }
591 
592         if (renderProperty_ == nullptr) {
593             renderProperty_ = std::make_shared<RSRenderAnimatableProperty<T>>(
594                 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType(), propertyUnit_);
595             auto weak = RSProperty<T>::weak_from_this();
596             renderProperty_->SetUpdateUIPropertyFunc(
597                 [weak](const std::shared_ptr<RSRenderPropertyBase>& renderProperty) {
598                     auto property = weak.lock();
599                     if (property == nullptr) {
600                         return;
601                     }
602                     property->UpdateShowingValue(renderProperty);
603                 });
604         }
605         return renderProperty_;
606     }
607 
608     void NotifyPropertyChange()
609     {
610         if (propertyChangeListener_) {
611             propertyChangeListener_(showingValue_);
612         }
613     }
614 
615     void SetThresholdType(ThresholdType thresholdType) override
616     {
617         thresholdType_ = thresholdType;
618     }
619 
620     float GetThreshold() const override
621     {
622         return RSProperty<T>::GetThresholdByThresholdType(thresholdType_);
623     }
624 
625     T showingValue_ {};
626     std::shared_ptr<RSRenderAnimatableProperty<T>> renderProperty_;
627     int runningPathNum_ { 0 };
628     std::shared_ptr<RSMotionPathOption> motionPathOption_ {};
629     std::function<void(T)> propertyChangeListener_;
630     ThresholdType thresholdType_ { ThresholdType::DEFAULT };
631     RSPropertyUnit propertyUnit_ { RSPropertyUnit::UNKNOWN };
632 
633 private:
634     RSRenderPropertyType GetPropertyType() const override
635     {
636         return RSRenderPropertyType::INVALID;
637     }
638 
639     std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) override
640     {
641         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
642         if (animatableProperty != nullptr) {
643             RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ + animatableProperty->stagingValue_;
644         }
645         return RSProperty<T>::shared_from_this();
646     }
647 
648     std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) override
649     {
650         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
651         if (animatableProperty != nullptr) {
652             RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ - animatableProperty->stagingValue_;
653         }
654         return RSProperty<T>::shared_from_this();
655     }
656 
657     std::shared_ptr<RSPropertyBase> Multiply(const float scale) override
658     {
659         RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ * scale;
660         return RSProperty<T>::shared_from_this();
661     }
662 
663     bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const override
664     {
665         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
666         if (animatableProperty != nullptr) {
667             return RSProperty<T>::stagingValue_ == animatableProperty->stagingValue_;
668         }
669         return true;
670     }
671 
672     friend class RSPropertyAnimation;
673     friend class RSPathAnimation;
674     friend class RSExtendedModifier;
675     friend class RSModifier;
676 };
677 
678 template<>
679 RSC_EXPORT void RSProperty<bool>::UpdateToRender(const bool& value, PropertyUpdateType type) const;
680 template<>
681 RSC_EXPORT void RSProperty<float>::UpdateToRender(const float& value, PropertyUpdateType type) const;
682 template<>
683 RSC_EXPORT void RSProperty<int>::UpdateToRender(const int& value, PropertyUpdateType type) const;
684 template<>
685 RSC_EXPORT void RSProperty<Color>::UpdateToRender(const Color& value, PropertyUpdateType type) const;
686 template<>
687 RSC_EXPORT void RSProperty<Gravity>::UpdateToRender(const Gravity& value, PropertyUpdateType type) const;
688 template<>
689 RSC_EXPORT void RSProperty<Matrix3f>::UpdateToRender(const Matrix3f& value, PropertyUpdateType type) const;
690 template<>
691 RSC_EXPORT void RSProperty<Quaternion>::UpdateToRender(const Quaternion& value, PropertyUpdateType type) const;
692 template<>
693 RSC_EXPORT void RSProperty<std::shared_ptr<RSFilter>>::UpdateToRender(
694     const std::shared_ptr<RSFilter>& value, PropertyUpdateType type) const;
695 template<>
696 RSC_EXPORT void RSProperty<std::shared_ptr<RSImage>>::UpdateToRender(
697     const std::shared_ptr<RSImage>& value, PropertyUpdateType type) const;
698 template<>
699 RSC_EXPORT void RSProperty<std::shared_ptr<RSMask>>::UpdateToRender(
700     const std::shared_ptr<RSMask>& value, PropertyUpdateType type) const;
701 template<>
702 RSC_EXPORT void RSProperty<std::shared_ptr<RSPath>>::UpdateToRender(
703     const std::shared_ptr<RSPath>& value, PropertyUpdateType type) const;
704 template<>
705 RSC_EXPORT void RSProperty<std::shared_ptr<RSLinearGradientBlurPara>>::UpdateToRender(
706     const std::shared_ptr<RSLinearGradientBlurPara>& value, PropertyUpdateType type) const;
707 template<>
708 RSC_EXPORT void RSProperty<std::shared_ptr<RSShader>>::UpdateToRender(
709     const std::shared_ptr<RSShader>& value, PropertyUpdateType type) const;
710 template<>
711 RSC_EXPORT void RSProperty<Vector2f>::UpdateToRender(const Vector2f& value, PropertyUpdateType type) const;
712 template<>
713 RSC_EXPORT void RSProperty<Vector4<uint32_t>>::UpdateToRender(
714     const Vector4<uint32_t>& value, PropertyUpdateType type) const;
715 template<>
716 RSC_EXPORT void RSProperty<Vector4<Color>>::UpdateToRender(
717     const Vector4<Color>& value, PropertyUpdateType type) const;
718 template<>
719 RSC_EXPORT void RSProperty<Vector4f>::UpdateToRender(const Vector4f& value, PropertyUpdateType type) const;
720 template<>
721 RSC_EXPORT void RSProperty<RRect>::UpdateToRender(const RRect& value, PropertyUpdateType type) const;
722 
723 template<>
724 RSC_EXPORT bool RSProperty<float>::IsValid(const float& value);
725 template<>
726 RSC_EXPORT bool RSProperty<Vector2f>::IsValid(const Vector2f& value);
727 template<>
728 RSC_EXPORT bool RSProperty<Vector4f>::IsValid(const Vector4f& value);
729 
730 template<>
731 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<float>::GetPropertyType() const;
732 template<>
733 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Color>::GetPropertyType() const;
734 template<>
735 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Matrix3f>::GetPropertyType() const;
736 template<>
737 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector2f>::GetPropertyType() const;
738 template<>
739 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4f>::GetPropertyType() const;
740 template<>
741 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Quaternion>::GetPropertyType() const;
742 template<>
743 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<std::shared_ptr<RSFilter>>::GetPropertyType() const;
744 template<>
745 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4<Color>>::GetPropertyType() const;
746 template<>
747 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<RRect>::GetPropertyType() const;
748 } // namespace Rosen
749 } // namespace OHOS
750 
751 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H
752