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