• 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_implicit_animator.h"
23 #include "animation/rs_implicit_animator_map.h"
24 #include "animation/rs_motion_path_option.h"
25 #include "command/rs_node_showing_command.h"
26 #include "common/rs_color.h"
27 #include "common/rs_common_def.h"
28 #include "common/rs_macros.h"
29 #include "common/rs_vector2.h"
30 #include "common/rs_vector4.h"
31 #include "modifier/rs_animatable_arithmetic.h"
32 #include "modifier/rs_modifier_type.h"
33 #include "modifier/rs_render_property.h"
34 #include "pipeline/rs_node_map.h"
35 #include "property/rs_properties_def.h"
36 #include "render/rs_border.h"
37 #include "render/rs_filter.h"
38 #include "render/rs_image.h"
39 #include "render/rs_mask.h"
40 #include "render/rs_path.h"
41 #include "render/rs_shader.h"
42 #include "transaction/rs_transaction_proxy.h"
43 #include "ui/rs_node.h"
44 
45 #ifdef _WIN32
46 #include <windows.h>
47 #define gettid GetCurrentThreadId
48 #endif
49 
50 #ifdef __APPLE__
51 #define gettid getpid
52 #endif
53 
54 #ifdef __gnu_linux__
55 #include <sys/types.h>
56 #include <sys/syscall.h>
57 #define gettid []() -> int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); }
58 #endif
59 
60 namespace OHOS {
61 namespace Rosen {
62 template<class...>
63 struct make_void { using type = void; };
64 template<class... T>
65 using void_t = typename make_void<T...>::type;
66 
67 template<class T, class = void>
68 struct supports_arithmetic : std::false_type {};
69 template<class T>
70 struct supports_arithmetic<T,
71     void_t<decltype(std::declval<T>() == std::declval<T>())>>
72         : std::true_type {};
73 
74 template<class T, class = void>
75 struct supports_animatable_arithmetic : std::false_type {};
76 template<class T>
77 struct supports_animatable_arithmetic<T,
78     void_t<decltype(std::declval<T>() + std::declval<T>()),
79         decltype(std::declval<T>() - std::declval<T>()),
80         decltype(std::declval<T>() * std::declval<float>()),
81         decltype(std::declval<T>() == std::declval<T>())>>
82         : std::true_type {};
83 
84 class RSC_EXPORT RSPropertyBase : public std::enable_shared_from_this<RSPropertyBase> {
85 public:
86     RSPropertyBase();
87     virtual ~RSPropertyBase() = default;
88 
89     PropertyId GetId() const
90     {
91         return id_;
92     }
93 
94 protected:
95     virtual void SetIsCustom(bool isCustom) {}
96 
97     virtual bool GetIsCustom() const
98     {
99         return false;
100     }
101 
102     virtual void SetValue(const std::shared_ptr<RSPropertyBase>& value) {}
103 
104     virtual std::shared_ptr<RSPropertyBase> Clone() const
105     {
106         return std::make_shared<RSPropertyBase>();
107     }
108 
109     virtual void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) {}
110 
111     virtual RSRenderPropertyType GetPropertyType() const
112     {
113         return RSRenderPropertyType::INVALID;
114     }
115 
116     virtual void UpdateOnAllAnimationFinish() {}
117 
118     virtual void AddPathAnimation() {}
119 
120     virtual void RemovePathAnimation() {}
121 
122     virtual void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) {}
123 
124     void AttachModifier(const std::shared_ptr<RSModifier>& modifier)
125     {
126         modifier_ = modifier;
127     }
128 
129     void MarkModifierDirty();
130 
131     void UpdateExtendModifierForGeometry(const std::shared_ptr<RSNode>& node);
132 
133     virtual std::shared_ptr<RSRenderPropertyBase> GetRenderProperty()
134     {
135         return std::make_shared<RSRenderPropertyBase>(id_);
136     }
137 
138     virtual bool GetShowingValueAndCancelAnimation()
139     {
140         return false;
141     }
142 
143     PropertyId id_;
144     RSModifierType type_ { RSModifierType::INVALID };
145     std::weak_ptr<RSNode> target_;
146     std::weak_ptr<RSModifier> modifier_;
147 
148 private:
149     virtual std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value)
150     {
151         return shared_from_this();
152     }
153 
154     virtual std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value)
155     {
156         return shared_from_this();
157     }
158 
159     virtual std::shared_ptr<RSPropertyBase> Multiply(const float scale)
160     {
161         return shared_from_this();
162     }
163 
164     virtual bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const
165     {
166         return true;
167     }
168 
169     friend std::shared_ptr<RSPropertyBase> operator+=(
170         const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
171     friend std::shared_ptr<RSPropertyBase> operator-=(
172         const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
173     friend std::shared_ptr<RSPropertyBase> operator*=(const std::shared_ptr<RSPropertyBase>& value, const float scale);
174     friend std::shared_ptr<RSPropertyBase> operator+(
175         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
176     friend std::shared_ptr<RSPropertyBase> operator-(
177         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
178     friend std::shared_ptr<RSPropertyBase> operator*(
179         const std::shared_ptr<const RSPropertyBase>& value, const float scale);
180     friend bool operator==(
181         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
182     friend bool operator!=(
183         const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b);
184     friend class RSCurveAnimation;
185     friend class RSCustomTransitionEffect;
186     friend class RSExtendedModifier;
187     friend class RSGeometryTransModifier;
188     friend class RSImplicitAnimator;
189     friend class RSImplicitCurveAnimationParam;
190     friend class RSImplicitInterpolatingSpringAnimationParam;
191     friend class RSImplicitKeyframeAnimationParam;
192     friend class RSImplicitSpringAnimationParam;
193     friend class RSImplicitTransitionParam;
194     friend class RSModifier;
195     friend class RSPropertyAnimation;
196     friend class RSPathAnimation;
197     friend class RSKeyframeAnimation;
198     friend class RSSpringAnimation;
199     friend class RSInterpolatingSpringAnimation;
200     friend class RSTransition;
201     template<typename T1>
202     friend class RSAnimatableProperty;
203     template<uint16_t commandType, uint16_t commandSubType>
204     friend class RSGetShowingValueAndCancelAnimationTask;
205 };
206 
207 template<typename T>
208 class RSProperty : public RSPropertyBase {
209     static_assert(std::is_base_of_v<RSArithmetic<T>, T> || supports_arithmetic<T>::value);
210 
211 public:
212     RSProperty() : RSPropertyBase() {}
213     explicit RSProperty(const T& value) : RSPropertyBase()
214     {
215         stagingValue_ = value;
216     }
217     virtual ~RSProperty() = default;
218 
219     virtual void Set(const T& value)
220     {
221         if (ROSEN_EQ(value, stagingValue_) || !IsValid(value)) {
222             return;
223         }
224 
225         stagingValue_ = value;
226         auto node = target_.lock();
227         if (node == nullptr) {
228             return;
229         }
230 
231         UpdateExtendModifierForGeometry(node);
232         if (isCustom_) {
233             MarkModifierDirty();
234         } else {
235             UpdateToRender(stagingValue_, false);
236         }
237     }
238 
239     virtual T Get() const
240     {
241         return stagingValue_;
242     }
243 
244 protected:
245     void UpdateToRender(const T& value, bool isDelta, bool forceUpdate = false) const
246     {}
247 
248     void SetValue(const std::shared_ptr<RSPropertyBase>& value) override
249     {
250         auto property = std::static_pointer_cast<RSProperty<T>>(value);
251         if (property != nullptr) {
252             stagingValue_ = property->stagingValue_;
253         }
254     }
255 
256     std::shared_ptr<RSPropertyBase> Clone() const override
257     {
258         return std::make_shared<RSProperty<T>>(stagingValue_);
259     }
260 
261     bool IsValid(const T& value)
262     {
263         return true;
264     }
265 
266     void SetIsCustom(bool isCustom) override
267     {
268         isCustom_ = isCustom;
269     }
270 
271     bool GetIsCustom() const override
272     {
273         return isCustom_;
274     }
275 
276     std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override
277     {
278         return std::make_shared<RSRenderProperty<T>>(stagingValue_, id_);
279     }
280 
281     T stagingValue_ {};
282     bool isCustom_ { false };
283 
284     friend class RSPathAnimation;
285     friend class RSImplicitAnimator;
286     friend class RSExtendedModifier;
287     friend class RSModifier;
288 };
289 
290 template<typename T>
291 class RSAnimatableProperty : public RSProperty<T> {
292     static_assert(std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<Color, T> ||
293                   std::is_same_v<Matrix3f, T> || std::is_same_v<Vector2f, T> || std::is_same_v<Vector4f, T> ||
294                   std::is_same_v<Quaternion, T> || std::is_same_v<std::shared_ptr<RSFilter>, T> ||
295                   std::is_same_v<Vector4<Color>, T> || std::is_base_of_v<RSAnimatableArithmetic<T>, T> ||
296                   supports_animatable_arithmetic<T>::value || std::is_same_v<RRect, T>);
297 
298 public:
299     RSAnimatableProperty() : RSProperty<T>() {}
300     explicit RSAnimatableProperty(const T& value) : RSProperty<T>(value)
301     {
302         showingValue_ = value;
303     }
304 
305     virtual ~RSAnimatableProperty() = default;
306 
307     void Set(const T& value) override
308     {
309         if (ROSEN_EQ(value, RSProperty<T>::stagingValue_) || !RSProperty<T>::IsValid(value)) {
310             return;
311         }
312 
313         auto node = RSProperty<T>::target_.lock();
314         if (node == nullptr) {
315             RSProperty<T>::stagingValue_ = value;
316             return;
317         }
318 
319         RSProperty<T>::UpdateExtendModifierForGeometry(node);
320         auto implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid());
321         if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) {
322             auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
323             auto endValue = std::make_shared<RSAnimatableProperty<T>>(value);
324             if (motionPathOption_ != nullptr) {
325                 implicitAnimator->BeginImplicitPathAnimation(motionPathOption_);
326                 implicitAnimator->CreateImplicitAnimation(
327                     node, RSProperty<T>::shared_from_this(), startValue, endValue);
328                 implicitAnimator->EndImplicitPathAnimation();
329             } else {
330                 implicitAnimator->CreateImplicitAnimation(
331                     node, RSProperty<T>::shared_from_this(), startValue, endValue);
332             }
333             return;
334         }
335 
336         if (runningPathNum_ > 0) {
337             return;
338         }
339 
340         bool hasPropertyAnimation = node->HasPropertyAnimation(RSProperty<T>::id_);
341         T sendValue = value;
342         if (hasPropertyAnimation) {
343             sendValue = value - RSProperty<T>::stagingValue_;
344         }
345         RSProperty<T>::stagingValue_ = value;
346         if (RSProperty<T>::isCustom_) {
347             UpdateExtendedAnimatableProperty(sendValue, hasPropertyAnimation);
348         } else {
349             RSProperty<T>::UpdateToRender(sendValue, hasPropertyAnimation);
350         }
351     }
352 
353     T Get() const override
354     {
355         if (RSProperty<T>::isCustom_) {
356             return showingValue_;
357         }
358         return RSProperty<T>::stagingValue_;
359     }
360 
361     T GetStagingValue() const
362     {
363         return RSProperty<T>::stagingValue_;
364     }
365 
366     bool GetShowingValueAndCancelAnimation() override
367     {
368         auto node = RSProperty<T>::target_.lock();
369         if (node == nullptr) {
370             return false;
371         }
372         if (!node->HasPropertyAnimation(this->id_) || this->GetIsCustom()) {
373             return true;
374         }
375         auto task = std::make_shared<RSNodeGetShowingPropertyAndCancelAnimation>(node->GetId(), GetRenderProperty());
376         RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(task, node->IsRenderServiceNode());
377         if (!task || !task->GetResult()) {
378             return false;
379         }
380         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(task->GetProperty());
381         if (!renderProperty) {
382             return false;
383         }
384         node->CancelAnimationByProperty(this->id_);
385         RSProperty<T>::stagingValue_ = renderProperty->Get();
386         return true;
387     }
388 
389     void SetUpdateCallback(const std::function<void(T)>& updateCallback)
390     {
391         propertyChangeListener_ = updateCallback;
392     }
393 
394 protected:
395     void UpdateOnAllAnimationFinish() override
396     {
397         RSProperty<T>::UpdateToRender(RSProperty<T>::stagingValue_, false, true);
398     }
399 
400     void UpdateExtendedAnimatableProperty(const T& value, bool isDelta)
401     {
402         if (isDelta) {
403             if (renderProperty_ != nullptr) {
404                 renderProperty_->Set(renderProperty_->Get() + value);
405             }
406         } else {
407             showingValue_ = value;
408             RSProperty<T>::MarkModifierDirty();
409             if (renderProperty_ != nullptr) {
410                 renderProperty_->Set(value);
411             } else {
412                 NotifyPropertyChange();
413             }
414         }
415     }
416 
417     void AddPathAnimation() override
418     {
419         runningPathNum_ += 1;
420     }
421 
422     void RemovePathAnimation() override
423     {
424         runningPathNum_ -= 1;
425     }
426 
427     void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) override
428     {
429         auto renderProperty = std::static_pointer_cast<const RSRenderProperty<T>>(property);
430         if (renderProperty != nullptr) {
431             showingValue_ = renderProperty->Get();
432             NotifyPropertyChange();
433             RSProperty<T>::MarkModifierDirty();
434         }
435     }
436 
437     void SetValue(const std::shared_ptr<RSPropertyBase>& value) override
438     {
439         auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(value);
440         if (property != nullptr && property->GetPropertyType() == GetPropertyType()) {
441             RSProperty<T>::stagingValue_ = property->stagingValue_;
442         }
443     }
444 
445     std::shared_ptr<RSPropertyBase> Clone() const override
446     {
447         return std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_);
448     }
449 
450     void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) override
451     {
452         motionPathOption_ = motionPathOption;
453     }
454 
455     std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override
456     {
457         if (!RSProperty<T>::isCustom_) {
458             return std::make_shared<RSRenderAnimatableProperty<T>>(
459                 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType());
460         }
461 
462         if (renderProperty_ == nullptr) {
463             renderProperty_ = std::make_shared<RSRenderAnimatableProperty<T>>(
464                 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType());
465             auto weak = RSProperty<T>::weak_from_this();
466             renderProperty_->SetUpdateUIPropertyFunc(
467                 [weak](const std::shared_ptr<RSRenderPropertyBase>& renderProperty) {
468                     auto property = weak.lock();
469                     if (property == nullptr) {
470                         return;
471                     }
472                     property->UpdateShowingValue(renderProperty);
473                 });
474         }
475         return renderProperty_;
476     }
477 
478     void NotifyPropertyChange()
479     {
480         if (propertyChangeListener_) {
481             propertyChangeListener_(showingValue_);
482         }
483     }
484 
485     T showingValue_ {};
486     std::shared_ptr<RSRenderAnimatableProperty<T>> renderProperty_;
487     int runningPathNum_ { 0 };
488     std::shared_ptr<RSMotionPathOption> motionPathOption_ {};
489     std::function<void(T)> propertyChangeListener_;
490 
491 private:
492     RSRenderPropertyType GetPropertyType() const override
493     {
494         return RSRenderPropertyType::INVALID;
495     }
496 
497     std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) override
498     {
499         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
500         if (animatableProperty != nullptr) {
501             RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ + animatableProperty->stagingValue_;
502         }
503         return RSProperty<T>::shared_from_this();
504     }
505 
506     std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) override
507     {
508         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
509         if (animatableProperty != nullptr) {
510             RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ - animatableProperty->stagingValue_;
511         }
512         return RSProperty<T>::shared_from_this();
513     }
514 
515     std::shared_ptr<RSPropertyBase> Multiply(const float scale) override
516     {
517         RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ * scale;
518         return RSProperty<T>::shared_from_this();
519     }
520 
521     bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const override
522     {
523         auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value);
524         if (animatableProperty != nullptr) {
525             return RSProperty<T>::stagingValue_ == animatableProperty->stagingValue_;
526         }
527         return true;
528     }
529 
530     friend class RSPropertyAnimation;
531     friend class RSPathAnimation;
532     friend class RSExtendedModifier;
533     friend class RSModifier;
534 };
535 
536 template<>
537 RSC_EXPORT void RSProperty<bool>::UpdateToRender(const bool& value, bool isDelta, bool forceUpdate) const;
538 template<>
539 RSC_EXPORT void RSProperty<float>::UpdateToRender(const float& value, bool isDelta, bool forceUpdate) const;
540 template<>
541 RSC_EXPORT void RSProperty<int>::UpdateToRender(const int& value, bool isDelta, bool forceUpdate) const;
542 template<>
543 RSC_EXPORT void RSProperty<Color>::UpdateToRender(const Color& value, bool isDelta, bool forceUpdate) const;
544 template<>
545 RSC_EXPORT void RSProperty<Gravity>::UpdateToRender(const Gravity& value, bool isDelta, bool forceUpdate) const;
546 template<>
547 RSC_EXPORT void RSProperty<Matrix3f>::UpdateToRender(const Matrix3f& value, bool isDelta, bool forceUpdate) const;
548 template<>
549 RSC_EXPORT void RSProperty<Quaternion>::UpdateToRender(const Quaternion& value, bool isDelta, bool forceUpdate) const;
550 template<>
551 RSC_EXPORT void RSProperty<std::shared_ptr<RSFilter>>::UpdateToRender(
552     const std::shared_ptr<RSFilter>& value, bool isDelta, bool forceUpdate) const;
553 template<>
554 RSC_EXPORT void RSProperty<std::shared_ptr<RSImage>>::UpdateToRender(
555     const std::shared_ptr<RSImage>& value, bool isDelta, bool forceUpdate) const;
556 template<>
557 RSC_EXPORT void RSProperty<std::shared_ptr<RSMask>>::UpdateToRender(
558     const std::shared_ptr<RSMask>& value, bool isDelta, bool forceUpdate) const;
559 template<>
560 RSC_EXPORT void RSProperty<std::shared_ptr<RSPath>>::UpdateToRender(
561     const std::shared_ptr<RSPath>& value, bool isDelta, bool forceUpdate) const;
562 template<>
563 RSC_EXPORT void RSProperty<std::shared_ptr<RSLinearGradientBlurPara>>::UpdateToRender(
564     const std::shared_ptr<RSLinearGradientBlurPara>& value, bool isDelta, bool forceUpdate) const;
565 template<>
566 RSC_EXPORT void RSProperty<std::shared_ptr<RSShader>>::UpdateToRender(
567     const std::shared_ptr<RSShader>& value, bool isDelta, bool forceUpdate) const;
568 template<>
569 RSC_EXPORT void RSProperty<Vector2f>::UpdateToRender(const Vector2f& value, bool isDelta, bool forceUpdate) const;
570 template<>
571 RSC_EXPORT void RSProperty<Vector4<uint32_t>>::UpdateToRender(
572     const Vector4<uint32_t>& value, bool isDelta, bool forceUpdate) const;
573 template<>
574 RSC_EXPORT void RSProperty<Vector4<Color>>::UpdateToRender(
575     const Vector4<Color>& value, bool isDelta, bool forceUpdate) const;
576 template<>
577 RSC_EXPORT void RSProperty<Vector4f>::UpdateToRender(const Vector4f& value, bool isDelta, bool forceUpdate) const;
578 template<>
579 RSC_EXPORT void RSProperty<RRect>::UpdateToRender(const RRect& value, bool isDelta, bool forceUpdate) const;
580 
581 template<>
582 RSC_EXPORT bool RSProperty<float>::IsValid(const float& value);
583 template<>
584 RSC_EXPORT bool RSProperty<Vector2f>::IsValid(const Vector2f& value);
585 template<>
586 RSC_EXPORT bool RSProperty<Vector4f>::IsValid(const Vector4f& value);
587 
588 template<>
589 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<float>::GetPropertyType() const;
590 template<>
591 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Color>::GetPropertyType() const;
592 template<>
593 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Matrix3f>::GetPropertyType() const;
594 template<>
595 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector2f>::GetPropertyType() const;
596 template<>
597 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4f>::GetPropertyType() const;
598 template<>
599 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Quaternion>::GetPropertyType() const;
600 template<>
601 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<std::shared_ptr<RSFilter>>::GetPropertyType() const;
602 template<>
603 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4<Color>>::GetPropertyType() const;
604 template<>
605 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<RRect>::GetPropertyType() const;
606 } // namespace Rosen
607 } // namespace OHOS
608 
609 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H
610