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 #include "modifier/rs_render_property.h"
17 
18 #include <iomanip>
19 
20 #include "pipeline/rs_render_node.h"
21 #include "platform/common/rs_log.h"
22 #include "rs_profiler.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 
OnChange() const27 void RSRenderPropertyBase::OnChange() const
28 {
29     if (auto node = node_.lock()) {
30         node->SetDirty();
31         node->AddDirtyType(modifierType_);
32         if (modifierType_ < RSModifierType::BOUNDS || modifierType_ > RSModifierType::TRANSLATE_Z ||
33             modifierType_ == RSModifierType::POSITION_Z) {
34             node->MarkNonGeometryChanged();
35         }
36         if (modifierType_ > RSModifierType::EXTENDED) {
37             node->SetContentDirty();
38         }
39         if (modifierType_ == RSModifierType::POSITION_Z) {
40             node->MarkParentNeedRegenerateChildren();
41         }
42     }
43 }
44 
UpdatePropertyUnit(RSModifierType type)45 void RSRenderPropertyBase::UpdatePropertyUnit(RSModifierType type)
46 {
47     switch (type) {
48         case RSModifierType::FRAME:
49         case RSModifierType::TRANSLATE:
50             SetPropertyUnit(RSPropertyUnit::PIXEL_POSITION);
51             break;
52         case RSModifierType::SCALE:
53             SetPropertyUnit(RSPropertyUnit::RATIO_SCALE);
54             break;
55         case RSModifierType::ROTATION_X:
56         case RSModifierType::ROTATION_Y:
57         case RSModifierType::ROTATION:
58             SetPropertyUnit(RSPropertyUnit::ANGLE_ROTATION);
59             break;
60         default:
61             SetPropertyUnit(RSPropertyUnit::UNKNOWN);
62             break;
63     }
64 }
65 
Marshalling(Parcel & parcel,const std::shared_ptr<RSRenderPropertyBase> & val)66 bool RSRenderPropertyBase::Marshalling(Parcel& parcel, const std::shared_ptr<RSRenderPropertyBase>& val)
67 {
68     if (val == nullptr) {
69         parcel.WriteUint16(static_cast<int16_t>(RSModifierType::INVALID));
70         return true;
71     }
72     RSRenderPropertyType type = val->GetPropertyType();
73     if (!(parcel.WriteInt16(static_cast<int16_t>(type)))) {
74         return false;
75     }
76     RSPropertyUnit unit = val->GetPropertyUnit();
77     if (!(parcel.WriteInt16(static_cast<int16_t>(unit)))) {
78         return false;
79     }
80     switch (type) {
81         case RSRenderPropertyType::PROPERTY_FLOAT: {
82             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(val);
83             if (property == nullptr) {
84                 return false;
85             }
86             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
87         }
88         case RSRenderPropertyType::PROPERTY_COLOR: {
89             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(val);
90             if (property == nullptr) {
91                 return false;
92             }
93             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
94         }
95         case RSRenderPropertyType::PROPERTY_MATRIX3F: {
96             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Matrix3f>>(val);
97             if (property == nullptr) {
98                 return false;
99             }
100             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
101         }
102         case RSRenderPropertyType::PROPERTY_QUATERNION: {
103             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Quaternion>>(val);
104             if (property == nullptr) {
105                 return false;
106             }
107             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
108         }
109         case RSRenderPropertyType::PROPERTY_FILTER: {
110             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>>(val);
111             if (property == nullptr) {
112                 return false;
113             }
114             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
115         }
116         case RSRenderPropertyType::PROPERTY_VECTOR2F: {
117             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(val);
118             if (property == nullptr) {
119                 return false;
120             }
121             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
122         }
123         case RSRenderPropertyType::PROPERTY_VECTOR4F: {
124             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(val);
125             if (property == nullptr) {
126                 return false;
127             }
128             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
129         }
130         case RSRenderPropertyType::PROPERTY_VECTOR4_COLOR: {
131             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4<Color>>>(val);
132             if (property == nullptr) {
133                 return false;
134             }
135             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
136         }
137         case RSRenderPropertyType::PROPERTY_RRECT: {
138             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<RRect>>(val);
139             if (property == nullptr) {
140                 return false;
141             }
142             return parcel.WriteUint64(property->GetId()) && RSMarshallingHelper::Marshalling(parcel, property->Get());
143         }
144         default: {
145             return false;
146         }
147     }
148     return true;
149 }
150 
Unmarshalling(Parcel & parcel,std::shared_ptr<RSRenderPropertyBase> & val)151 bool RSRenderPropertyBase::Unmarshalling(Parcel& parcel, std::shared_ptr<RSRenderPropertyBase>& val)
152 {
153     int16_t typeId = 0;
154     if (!parcel.ReadInt16(typeId)) {
155         return false;
156     }
157     RSRenderPropertyType type = static_cast<RSRenderPropertyType>(typeId);
158     if (type == RSRenderPropertyType::INVALID) {
159         val.reset();
160         return true;
161     }
162     int16_t unitId = 0;
163     if (!parcel.ReadInt16(unitId)) {
164         return false;
165     }
166     RSPropertyUnit unit = static_cast<RSPropertyUnit>(unitId);
167     PropertyId id = 0;
168     if (!parcel.ReadUint64(id)) {
169         return false;
170     }
171     RS_PROFILER_PATCH_NODE_ID(parcel, id);
172     switch (type) {
173         case RSRenderPropertyType::PROPERTY_FLOAT: {
174             float value;
175             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
176                 return false;
177             }
178             val.reset(new RSRenderAnimatableProperty<float>(value, id, type, unit));
179             break;
180         }
181         case RSRenderPropertyType::PROPERTY_COLOR: {
182             Color value;
183             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
184                 return false;
185             }
186             val.reset(new RSRenderAnimatableProperty<Color>(value, id, type, unit));
187             break;
188         }
189         case RSRenderPropertyType::PROPERTY_MATRIX3F: {
190             Matrix3f value;
191             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
192                 return false;
193             }
194             val.reset(new RSRenderAnimatableProperty<Matrix3f>(value, id, type, unit));
195             break;
196         }
197         case RSRenderPropertyType::PROPERTY_QUATERNION: {
198             Quaternion value;
199             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
200                 return false;
201             }
202             val.reset(new RSRenderAnimatableProperty<Quaternion>(value, id, type, unit));
203             break;
204         }
205         case RSRenderPropertyType::PROPERTY_FILTER: {
206             std::shared_ptr<RSFilter> value;
207             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
208                 return false;
209             }
210             val.reset(new RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>(value, id, type, unit));
211             break;
212         }
213         case RSRenderPropertyType::PROPERTY_VECTOR2F: {
214             Vector2f value;
215             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
216                 return false;
217             }
218             val.reset(new RSRenderAnimatableProperty<Vector2f>(value, id, type, unit));
219             break;
220         }
221         case RSRenderPropertyType::PROPERTY_VECTOR4F: {
222             Vector4f value;
223             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
224                 return false;
225             }
226             val.reset(new RSRenderAnimatableProperty<Vector4f>(value, id, type, unit));
227             break;
228         }
229         case RSRenderPropertyType::PROPERTY_VECTOR4_COLOR: {
230             Vector4<Color> value;
231             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
232                 return false;
233             }
234             val.reset(new RSRenderAnimatableProperty<Vector4<Color>>(value, id, type, unit));
235             break;
236         }
237         case RSRenderPropertyType::PROPERTY_RRECT: {
238             RRect value;
239             if (!RSMarshallingHelper::Unmarshalling(parcel, value)) {
240                 return false;
241             }
242             val.reset(new RSRenderAnimatableProperty<RRect>(value, id, type, unit));
243             break;
244         }
245         default: {
246             return false;
247         }
248     }
249     return val != nullptr;
250 }
251 
252 template<>
ToFloat() const253 float RSRenderAnimatableProperty<float>::ToFloat() const
254 {
255     return std::fabs(RSRenderProperty<float>::stagingValue_);
256 }
257 
258 template<>
ToFloat() const259 float RSRenderAnimatableProperty<Vector4f>::ToFloat() const
260 {
261     return RSRenderProperty<Vector4f>::stagingValue_.GetLength();
262 }
263 
264 template<>
ToFloat() const265 float RSRenderAnimatableProperty<Quaternion>::ToFloat() const
266 {
267     return RSRenderProperty<Quaternion>::stagingValue_.GetLength();
268 }
269 
270 template<>
ToFloat() const271 float RSRenderAnimatableProperty<Vector2f>::ToFloat() const
272 {
273     return RSRenderProperty<Vector2f>::stagingValue_.GetLength();
274 }
275 
operator +=(const std::shared_ptr<RSRenderPropertyBase> & a,const std::shared_ptr<const RSRenderPropertyBase> & b)276 std::shared_ptr<RSRenderPropertyBase> operator+=(
277     const std::shared_ptr<RSRenderPropertyBase>& a, const std::shared_ptr<const RSRenderPropertyBase>& b)
278 {
279     if (a == nullptr) {
280         return {};
281     }
282 
283     return a->Add(b);
284 }
285 
operator -=(const std::shared_ptr<RSRenderPropertyBase> & a,const std::shared_ptr<const RSRenderPropertyBase> & b)286 std::shared_ptr<RSRenderPropertyBase> operator-=(
287     const std::shared_ptr<RSRenderPropertyBase>& a, const std::shared_ptr<const RSRenderPropertyBase>& b)
288 {
289     if (a == nullptr) {
290         return {};
291     }
292 
293     return a->Minus(b);
294 }
295 
operator *=(const std::shared_ptr<RSRenderPropertyBase> & value,const float scale)296 std::shared_ptr<RSRenderPropertyBase> operator*=(const std::shared_ptr<RSRenderPropertyBase>& value, const float scale)
297 {
298     if (value == nullptr) {
299         return {};
300     }
301 
302     return value->Multiply(scale);
303 }
304 
operator +(const std::shared_ptr<const RSRenderPropertyBase> & a,const std::shared_ptr<const RSRenderPropertyBase> & b)305 std::shared_ptr<RSRenderPropertyBase> operator+(
306     const std::shared_ptr<const RSRenderPropertyBase>& a, const std::shared_ptr<const RSRenderPropertyBase>& b)
307 {
308     if (a == nullptr) {
309         return {};
310     }
311 
312     return a->Clone()->Add(b);
313 }
314 
operator -(const std::shared_ptr<const RSRenderPropertyBase> & a,const std::shared_ptr<const RSRenderPropertyBase> & b)315 std::shared_ptr<RSRenderPropertyBase> operator-(
316     const std::shared_ptr<const RSRenderPropertyBase>& a, const std::shared_ptr<const RSRenderPropertyBase>& b)
317 {
318     if (a == nullptr) {
319         return {};
320     }
321 
322     return a->Clone()->Minus(b);
323 }
324 
operator *(const std::shared_ptr<const RSRenderPropertyBase> & value,const float scale)325 std::shared_ptr<RSRenderPropertyBase> operator*(
326     const std::shared_ptr<const RSRenderPropertyBase>& value, const float scale)
327 {
328     if (value == nullptr) {
329         return {};
330     }
331 
332     return value->Clone()->Multiply(scale);
333 }
334 
operator ==(const std::shared_ptr<const RSRenderPropertyBase> & a,const std::shared_ptr<const RSRenderPropertyBase> & b)335 bool operator==(
336     const std::shared_ptr<const RSRenderPropertyBase>& a, const std::shared_ptr<const RSRenderPropertyBase>& b)
337 {
338     if (a == nullptr) {
339         return {};
340     }
341 
342     return a->IsEqual(b);
343 }
344 
operator !=(const std::shared_ptr<const RSRenderPropertyBase> & a,const std::shared_ptr<const RSRenderPropertyBase> & b)345 bool operator!=(
346     const std::shared_ptr<const RSRenderPropertyBase>& a, const std::shared_ptr<const RSRenderPropertyBase>& b)
347 {
348     if (a == nullptr) {
349         return {};
350     }
351 
352     return !a->IsEqual(b);
353 }
354 
355 template<>
Dump(std::string & out) const356 void RSRenderProperty<int>::Dump(std::string& out) const
357 {
358     out += "[" + std::to_string(Get()) + "]";
359 }
360 
361 template<>
Dump(std::string & out) const362 void RSRenderProperty<float>::Dump(std::string& out) const
363 {
364     std::stringstream ss;
365     ss << "[" << std::fixed << std::setprecision(1) << Get() << "]";
366     out += ss.str();
367 }
368 
369 template<>
Dump(std::string & out) const370 void RSRenderProperty<Vector4<uint32_t>>::Dump(std::string& out) const
371 {
372     Vector4 v4 = Get();
373     switch (modifierType_) {
374         case RSModifierType::BORDER_STYLE:
375         case RSModifierType::OUTLINE_STYLE: {
376             out += "[left:" + std::to_string(v4.x_);
377             out += " top:" + std::to_string(v4.y_);
378             out += " right:" + std::to_string(v4.z_);
379             out += " bottom:" + std::to_string(v4.w_) + "]";
380             break;
381         }
382         default: {
383             out += "[x:" + std::to_string(v4.x_) + " y:";
384             out += std::to_string(v4.y_) + " z:";
385             out += std::to_string(v4.z_) + " w:";
386             out += std::to_string(v4.w_) + "]";
387             break;
388         }
389     }
390 }
391 
392 template<>
Dump(std::string & out) const393 void RSRenderProperty<Vector4f>::Dump(std::string& out) const
394 {
395     Vector4f v4f = Get();
396     std::stringstream ss;
397     ss << std::fixed << std::setprecision(1);
398     switch (modifierType_) {
399         case RSModifierType::BORDER_WIDTH:
400         case RSModifierType::BORDER_DASH_WIDTH:
401         case RSModifierType::BORDER_DASH_GAP:
402         case RSModifierType::OUTLINE_WIDTH:
403         case RSModifierType::OUTLINE_DASH_WIDTH:
404         case RSModifierType::OUTLINE_DASH_GAP: {
405             ss << "[left:" << v4f.x_ << " top:" << v4f.y_ << " right:" << v4f.z_ << " bottom:" << v4f.w_ << + "]";
406             break;
407         }
408         case RSModifierType::CORNER_RADIUS:
409         case RSModifierType::OUTLINE_RADIUS: {
410             ss << "[topLeft:" << v4f.x_ << " topRight:" << v4f.y_ \
411                << " bottomRight:" << v4f.z_ << " bottomLeft:" << v4f.w_ << + "]";
412             break;
413         }
414         case RSModifierType::BOUNDS: {
415             ss << "[x:" << v4f.x_ << " y:" << v4f.y_ << " width:" << v4f.z_ << " height:" << v4f.w_ << + "]";
416             break;
417         }
418         default: {
419             ss << "[x:" << v4f.x_ << " y:" << v4f.y_ << " z:" << v4f.z_ << " w:" << v4f.w_ << + "]";
420             break;
421         }
422     }
423     out += ss.str();
424 }
425 
426 template<>
Dump(std::string & out) const427 void RSRenderProperty<Quaternion>::Dump(std::string& out) const
428 {
429     Quaternion q = Get();
430     std::stringstream ss;
431     ss << std::fixed << std::setprecision(1);
432     ss << "[x:" << q.x_ << " y:" << q.y_ << " z:" << q.z_ << " w:" << q.w_ << + "]";
433     out += ss.str();
434 }
435 
436 template<>
Dump(std::string & out) const437 void RSRenderProperty<Vector2f>::Dump(std::string& out) const
438 {
439     Vector2f v2f = Get();
440     std::stringstream ss;
441     ss << std::fixed << std::setprecision(1) << "[x:" << v2f.x_ << " y:" << v2f.y_ << "]";
442     out += ss.str();
443 }
444 
445 template<>
Dump(std::string & out) const446 void RSRenderProperty<Matrix3f>::Dump(std::string& out) const
447 {
448 }
449 
450 template<>
Dump(std::string & out) const451 void RSRenderProperty<Color>::Dump(std::string& out) const
452 {
453     Get().Dump(out);
454 }
455 
456 template<>
Dump(std::string & out) const457 void RSRenderProperty<std::shared_ptr<RSFilter>>::Dump(std::string& out) const
458 {
459     auto filter = Get();
460     out += "[";
461     if (filter != nullptr && filter->IsValid()) {
462         out += filter->GetDescription();
463     }
464     out += "]";
465 }
466 
467 template<>
Dump(std::string & out) const468 void RSRenderProperty<Vector4<Color>>::Dump(std::string& out) const
469 {
470     Vector4<Color> v4Color = Get();
471     out += "[left";
472     v4Color.x_.Dump(out);
473     out += " top";
474     v4Color.y_.Dump(out);
475     out += " right";
476     v4Color.z_.Dump(out);
477     out += " bottom";
478     v4Color.w_.Dump(out);
479     out += ']';
480 }
481 
482 template<>
Dump(std::string & out) const483 void RSRenderProperty<RRect>::Dump(std::string& out) const
484 {
485 }
486 
487 template<>
Dump(std::string & out) const488 void RSRenderProperty<Drawing::DrawCmdListPtr>::Dump(std::string& out) const
489 {
490     auto propertyData = Get();
491     if (propertyData != nullptr) {
492         out += "drawCmdList[";
493         propertyData->Dump(out);
494         out += ']';
495     }
496 }
497 
498 template<>
Dump(std::string & out) const499 void RSRenderProperty<ForegroundColorStrategyType>::Dump(std::string& out) const
500 {
501     out += std::to_string(static_cast<int>(Get()));
502 }
503 
504 template<>
Dump(std::string & out) const505 void RSRenderProperty<SkMatrix>::Dump(std::string& out) const
506 {
507     Get().dump(out, 0);
508 }
509 
510 template<>
Dump(std::string & out) const511 void RSRenderProperty<std::shared_ptr<RSLinearGradientBlurPara>>::Dump(std::string& out) const
512 {
513     auto property = Get();
514     if (property != nullptr) {
515         property->Dump(out);
516     }
517 }
518 
519 template<>
Dump(std::string & out) const520 void RSRenderProperty<std::shared_ptr<MotionBlurParam>>::Dump(std::string& out) const
521 {
522     auto property = Get();
523     if (property != nullptr) {
524         property->Dump(out);
525     }
526 }
527 
528 template<>
Dump(std::string & out) const529 void RSRenderProperty<std::shared_ptr<RSMagnifierParams>>::Dump(std::string& out) const
530 {
531     auto property = Get();
532     if (property != nullptr) {
533         property->Dump(out);
534     }
535 }
536 
537 template<>
Dump(std::string & out) const538 void RSRenderProperty<std::vector<std::shared_ptr<EmitterUpdater>>>::Dump(std::string& out) const
539 {
540     auto property = Get();
541     out += '[';
542     bool found = false;
543     for (auto& eu : property) {
544         if (eu != nullptr) {
545             found = true;
546             out += "emitterUpdater";
547             eu->Dump(out);
548             out += ' ';
549         }
550     }
551     if (found) {
552         out.pop_back();
553     }
554     out += ']';
555 }
556 
557 template<>
Dump(std::string & out) const558 void RSRenderProperty<std::shared_ptr<ParticleNoiseFields>>::Dump(std::string& out) const
559 {
560     auto property = Get();
561     if (property != nullptr) {
562         property->Dump(out);
563     }
564 }
565 
566 template<>
Dump(std::string & out) const567 void RSRenderProperty<std::shared_ptr<RSMask>>::Dump(std::string& out) const
568 {
569     auto property = Get();
570     if (property != nullptr) {
571         property->Dump(out);
572     }
573 }
574 
575 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const576 bool RSRenderAnimatableProperty<float>::IsNearEqual(
577     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
578 {
579     auto animatableProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<float>>(value);
580     if (animatableProperty != nullptr) {
581         return fabs(RSRenderProperty<float>::stagingValue_ - animatableProperty->stagingValue_) <= zeroThreshold;
582     }
583     ROSEN_LOGE("RSRenderAnimatableProperty<float>::IsNearEqual: the value of the comparison is a null pointer!");
584     return true;
585 }
586 
587 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const588 bool RSRenderAnimatableProperty<Vector2f>::IsNearEqual(
589     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
590 {
591     auto animatableProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<Vector2f>>(value);
592     if (animatableProperty != nullptr) {
593         return RSRenderProperty<Vector2f>::stagingValue_.IsNearEqual(animatableProperty->Get(), zeroThreshold);
594     }
595     ROSEN_LOGE("RSRenderAnimatableProperty<Vector2f>::IsNearEqual: the value of the comparison is a null pointer!");
596     return true;
597 }
598 
599 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const600 bool RSRenderAnimatableProperty<Quaternion>::IsNearEqual(
601     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
602 {
603     auto animatableProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<Quaternion>>(value);
604     if (animatableProperty != nullptr) {
605         return RSRenderProperty<Quaternion>::stagingValue_.IsNearEqual(animatableProperty->Get(), zeroThreshold);
606     }
607     ROSEN_LOGE("RSRenderAnimatableProperty<Quaternion>::IsNearEqual: the value of the comparison is a null pointer!");
608     return true;
609 }
610 
611 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const612 bool RSRenderAnimatableProperty<Vector4f>::IsNearEqual(
613     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
614 {
615     auto animatableProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<Vector4f>>(value);
616     if (animatableProperty != nullptr) {
617         return RSRenderProperty<Vector4f>::stagingValue_.IsNearEqual(animatableProperty->Get(), zeroThreshold);
618     }
619     ROSEN_LOGE("RSRenderAnimatableProperty<Vector4f>::IsNearEqual: the value of the comparison is a null pointer!");
620     return true;
621 }
622 
623 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const624 bool RSRenderAnimatableProperty<Matrix3f>::IsNearEqual(
625     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
626 {
627     auto animatableProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<Matrix3f>>(value);
628     if (animatableProperty != nullptr) {
629         return RSRenderProperty<Matrix3f>::stagingValue_.IsNearEqual(animatableProperty->Get(), zeroThreshold);
630     }
631     ROSEN_LOGE("RSRenderAnimatableProperty<Matrix3f>::IsNearEqual: the value of the comparison is a null pointer!");
632     return true;
633 }
634 
635 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const636 bool RSRenderAnimatableProperty<Color>::IsNearEqual(
637     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
638 {
639     auto animatableProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<Color>>(value);
640     if (animatableProperty != nullptr) {
641         return RSRenderProperty<Color>::stagingValue_.IsNearEqual(
642             animatableProperty->Get(), static_cast<int16_t>(zeroThreshold));
643     }
644     ROSEN_LOGE("RSRenderAnimatableProperty<Color>::IsNearEqual: the value of the comparison is a null pointer!");
645     return true;
646 }
647 
648 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const649 bool RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>::IsNearEqual(
650     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
651 {
652     auto animatableProperty =
653         std::static_pointer_cast<const RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>>(value);
654     if (animatableProperty == nullptr) {
655         return true;
656     }
657 
658     auto filter = RSRenderProperty<std::shared_ptr<RSFilter>>::stagingValue_;
659     auto otherFilter = animatableProperty->Get();
660     if ((filter != nullptr) && (otherFilter != nullptr)) {
661         return filter->IsNearEqual(otherFilter, zeroThreshold);
662     } else if ((filter == nullptr) && (otherFilter == nullptr)) {
663         ROSEN_LOGE("RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>::IsNearEqual: "
664             "both values compared are null Pointers!");
665         return true;
666     } else if (filter == nullptr) {
667         ROSEN_LOGE(
668             "RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>::IsNearEqual: the staging value is a null pointer!");
669         return otherFilter->IsNearZero(zeroThreshold);
670     } else {
671         ROSEN_LOGE("RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>::IsNearEqual: "
672             "the value of the comparison is a null pointer!");
673         return filter->IsNearZero(zeroThreshold);
674     }
675 }
676 
677 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const678 bool RSRenderAnimatableProperty<Vector4<Color>>::IsNearEqual(
679     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
680 {
681     auto animatableProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<Vector4<Color>>>(value);
682     if (animatableProperty != nullptr) {
683         auto thisData = RSRenderProperty<Vector4<Color>>::stagingValue_.data_;
684         auto otherValue = animatableProperty->Get();
685         auto& otherData = otherValue.data_;
686         int16_t threshold = static_cast<int16_t>(zeroThreshold);
687         return thisData[0].IsNearEqual(otherData[0], threshold) && thisData[2].IsNearEqual(otherData[2], threshold) &&
688                thisData[2].IsNearEqual(otherData[2], threshold) && thisData[3].IsNearEqual(otherData[3], threshold);
689     }
690     ROSEN_LOGE(
691         "RSRenderAnimatableProperty<Vector4<Color>>::IsNearEqual: the value of the comparison is a null pointer!");
692     return true;
693 }
694 
695 template<>
IsNearEqual(const std::shared_ptr<RSRenderPropertyBase> & value,float zeroThreshold) const696 bool RSRenderAnimatableProperty<RRect>::IsNearEqual(
697     const std::shared_ptr<RSRenderPropertyBase>& value, float zeroThreshold) const
698 {
699     auto animatableProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<RRect>>(value);
700     if (animatableProperty != nullptr) {
701         return RSRenderProperty<RRect>::stagingValue_.IsNearEqual(animatableProperty->Get(), zeroThreshold);
702     }
703     ROSEN_LOGE("RSRenderAnimatableProperty<RRect>::IsNearEqual: the value of the comparison is a null pointer!");
704     return true;
705 }
706 
707 template<>
IsEqual(const std::shared_ptr<const RSRenderPropertyBase> & value) const708 bool RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>::IsEqual(
709     const std::shared_ptr<const RSRenderPropertyBase>& value) const
710 {
711     auto animatableProperty =
712         std::static_pointer_cast<const RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>>(value);
713     if (animatableProperty == nullptr) {
714         return true;
715     }
716 
717     auto filter = RSRenderProperty<std::shared_ptr<RSFilter>>::stagingValue_;
718     auto otherFilter = animatableProperty->Get();
719     if ((filter != nullptr) && (otherFilter != nullptr)) {
720         return filter->IsEqual(otherFilter);
721     } else if ((filter == nullptr) && (otherFilter == nullptr)) {
722         ROSEN_LOGE("RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>::IsEqual: "
723             "both values compared are null Pointers!");
724         return true;
725     } else if (filter == nullptr) {
726         ROSEN_LOGE(
727             "RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>::IsEqual: the staging value is a null pointer!");
728         return otherFilter->IsEqualZero();
729     } else {
730         ROSEN_LOGE("RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>::IsEqual: "
731             "the value of the comparison is a null pointer!");
732         return filter->IsEqualZero();
733     }
734 }
735 
736 template class RSRenderProperty<int>;
737 template class RSRenderProperty<float>;
738 template class RSRenderProperty<Vector4<uint32_t>>;
739 template class RSRenderProperty<Vector4f>;
740 template class RSRenderProperty<Quaternion>;
741 template class RSRenderProperty<Vector2f>;
742 template class RSRenderProperty<Matrix3f>;
743 template class RSRenderProperty<Color>;
744 template class RSRenderProperty<std::shared_ptr<RSFilter>>;
745 template class RSRenderProperty<Vector4<Color>>;
746 template class RSRenderProperty<RRect>;
747 template class RSRenderProperty<Drawing::DrawCmdListPtr>;
748 template class RSRenderProperty<ForegroundColorStrategyType>;
749 template class RSRenderProperty<SkMatrix>;
750 template class RSRenderProperty<std::shared_ptr<RSLinearGradientBlurPara>>;
751 template class RSRenderProperty<std::shared_ptr<MotionBlurParam>>;
752 template class RSRenderProperty<std::shared_ptr<RSMagnifierParams>>;
753 template class RSRenderProperty<std::vector<std::shared_ptr<EmitterUpdater>>>;
754 template class RSRenderProperty<std::shared_ptr<ParticleNoiseFields>>;
755 template class RSRenderProperty<std::shared_ptr<RSMask>>;
756 
757 template class RSRenderAnimatableProperty<float>;
758 template class RSRenderAnimatableProperty<Vector4f>;
759 template class RSRenderAnimatableProperty<Quaternion>;
760 template class RSRenderAnimatableProperty<Vector2f>;
761 template class RSRenderAnimatableProperty<Matrix3f>;
762 template class RSRenderAnimatableProperty<Color>;
763 template class RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>;
764 template class RSRenderAnimatableProperty<Vector4<Color>>;
765 template class RSRenderAnimatableProperty<RRect>;
766 } // namespace Rosen
767 } // namespace OHOS
768