1 /*
2  * Copyright (c) 2022 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_modifier.h"
17 #include "draw/color.h"
18 #include "image/bitmap.h"
19 #include <memory>
20 #include <unordered_map>
21 
22 #include "pixel_map.h"
23 
24 #include "common/rs_obj_abs_geometry.h"
25 #include "common/rs_vector2.h"
26 #include "common/rs_vector4.h"
27 #include "modifier/rs_modifier_type.h"
28 #include "pipeline/rs_draw_cmd_list.h"
29 #include "pipeline/rs_paint_filter_canvas.h"
30 #include "platform/common/rs_log.h"
31 #include "property/rs_properties.h"
32 #include "property/rs_properties_def.h"
33 #include "property/rs_properties_painter.h"
34 #include "render/rs_filter.h"
35 #include "render/rs_image.h"
36 #include "render/rs_mask.h"
37 #include "render/rs_path.h"
38 #include "render/rs_shader.h"
39 
40 namespace OHOS {
41 namespace Rosen {
42 namespace {
43 using ModifierUnmarshallingFunc = RSRenderModifier* (*)(Parcel& parcel);
44 
45 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP, MODIFIER_TIER, THRESHOLD_TYPE) \
46     { RSModifierType::MODIFIER_TYPE, [](Parcel& parcel) -> RSRenderModifier* {                                   \
47             std::shared_ptr<RSRenderAnimatableProperty<TYPE>> prop;                                              \
48             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {                                             \
49                 return nullptr;                                                                                  \
50             }                                                                                                    \
51             auto modifier = new RS##MODIFIER_NAME##RenderModifier(prop);                                         \
52             return ((!modifier) ? nullptr : modifier);                                                           \
53         },                                                                                                       \
54     },
55 
56 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, MODIFIER_TIER)                \
57     { RSModifierType::MODIFIER_TYPE, [](Parcel& parcel) -> RSRenderModifier* {                          \
58             std::shared_ptr<RSRenderProperty<TYPE>> prop;                                               \
59             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {                                    \
60                 return nullptr;                                                                         \
61             }                                                                                           \
62             auto modifier = new RS##MODIFIER_NAME##RenderModifier(prop);                                \
63             return ((!modifier) ? nullptr : modifier);                                                  \
64         },                                                                                              \
65     },
66 
67 static std::unordered_map<RSModifierType, ModifierUnmarshallingFunc> funcLUT = {
68 #include "modifier/rs_modifiers_def.in"
__anon35d38fe50202() 69     { RSModifierType::EXTENDED, [](Parcel& parcel) -> RSRenderModifier* {
70             std::shared_ptr<RSRenderProperty<std::shared_ptr<Drawing::DrawCmdList>>> prop;
71             int16_t type;
72             if (!RSMarshallingHelper::Unmarshalling(parcel, prop) || !parcel.ReadInt16(type)) {
73                 return nullptr;
74             }
75             RSDrawCmdListRenderModifier* modifier = new RSDrawCmdListRenderModifier(prop);
76             modifier->SetType(static_cast<RSModifierType>(type));
77             return modifier;
78         },
79     },
__anon35d38fe50302() 80     { RSModifierType::ENV_FOREGROUND_COLOR, [](Parcel& parcel) -> RSRenderModifier* {
81             std::shared_ptr<RSRenderAnimatableProperty<Color>> prop;
82             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
83                 return nullptr;
84             }
85             auto modifier = new RSEnvForegroundColorRenderModifier(prop);
86             return modifier;
87         },
88     },
__anon35d38fe50402() 89     { RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY, [](Parcel& parcel) -> RSRenderModifier* {
90             std::shared_ptr<RSRenderProperty<ForegroundColorStrategyType>> prop;
91             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
92                 return nullptr;
93             }
94             auto modifier = new RSEnvForegroundColorStrategyRenderModifier(prop);
95             return modifier;
96         },
97     },
__anon35d38fe50502() 98     { RSModifierType::CUSTOM_CLIP_TO_FRAME, [](Parcel& parcel) -> RSRenderModifier* {
99             std::shared_ptr<RSRenderAnimatableProperty<Vector4f>> prop;
100             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
101                 return nullptr;
102             }
103             auto modifier = new RSCustomClipToFrameRenderModifier(prop);
104             return modifier;
105         },
106     },
__anon35d38fe50602() 107     { RSModifierType::GEOMETRYTRANS, [](Parcel& parcel) -> RSRenderModifier* {
108             std::shared_ptr<RSRenderProperty<Drawing::Matrix>> prop;
109             int16_t type;
110             if (!RSMarshallingHelper::Unmarshalling(parcel, prop) || !parcel.ReadInt16(type)) {
111                 return nullptr;
112             }
113             auto modifier = new RSGeometryTransRenderModifier(prop);
114             modifier->SetType(static_cast<RSModifierType>(type));
115             return modifier;
116         },
117     },
__anon35d38fe50702() 118     { RSModifierType::BEHIND_WINDOW_FILTER_RADIUS, [](Parcel& parcel) -> RSRenderModifier* {
119             std::shared_ptr<RSRenderAnimatableProperty<float>> prop;
120             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
121                 return nullptr;
122             }
123             auto modifier = new RSBehindWindowFilterRadiusRenderModifier(prop);
124             return modifier;
125         },
126     },
__anon35d38fe50802() 127     { RSModifierType::BEHIND_WINDOW_FILTER_SATURATION, [](Parcel& parcel) -> RSRenderModifier* {
128             std::shared_ptr<RSRenderAnimatableProperty<float>> prop;
129             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
130                 return nullptr;
131             }
132             auto modifier = new RSBehindWindowFilterSaturationRenderModifier(prop);
133             return modifier;
134         },
135     },
__anon35d38fe50902() 136     { RSModifierType::BEHIND_WINDOW_FILTER_BRIGHTNESS, [](Parcel& parcel) -> RSRenderModifier* {
137             std::shared_ptr<RSRenderAnimatableProperty<float>> prop;
138             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
139                 return nullptr;
140             }
141             auto modifier = new RSBehindWindowFilterBrightnessRenderModifier(prop);
142             return modifier;
143         },
144     },
__anon35d38fe50a02() 145     { RSModifierType::BEHIND_WINDOW_FILTER_MASK_COLOR, [](Parcel& parcel) -> RSRenderModifier* {
146             std::shared_ptr<RSRenderAnimatableProperty<Color>> prop;
147             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
148                 return nullptr;
149             }
150             auto modifier = new RSBehindWindowFilterMaskColorRenderModifier(prop);
151             return modifier;
152         },
153     },
154 };
155 
156 #undef DECLARE_ANIMATABLE_MODIFIER
157 #undef DECLARE_NOANIMATABLE_MODIFIER
158 }
159 
Apply(RSModifierContext & context) const160 void RSDrawCmdListRenderModifier::Apply(RSModifierContext& context) const
161 {
162     if (context.canvas_) {
163         auto& cmds = property_->GetRef();
164         RSPropertiesPainter::DrawFrame(context.properties_, *context.canvas_, cmds);
165     }
166 }
167 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)168 void RSDrawCmdListRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
169 {
170     if (auto property = std::static_pointer_cast<RSRenderProperty<Drawing::DrawCmdListPtr>>(prop)) {
171         property_->Set(property->Get());
172     }
173 }
174 
Marshalling(Parcel & parcel)175 bool RSDrawCmdListRenderModifier::Marshalling(Parcel& parcel)
176 {
177     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::EXTENDED)) &&
178         RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType()));
179 }
180 
Marshalling(Parcel & parcel)181 bool RSEnvForegroundColorRenderModifier::Marshalling(Parcel& parcel)
182 {
183     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
184     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::ENV_FOREGROUND_COLOR)) &&
185             RSMarshallingHelper::Marshalling(parcel, renderProperty);
186 }
187 
Apply(RSModifierContext & context) const188 void RSEnvForegroundColorRenderModifier::Apply(RSModifierContext& context) const
189 {
190     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
191     context.canvas_->SetEnvForegroundColor(renderProperty->Get());
192 }
193 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)194 void RSEnvForegroundColorRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
195 {
196     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(prop)) {
197         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
198         renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());
199     }
200 }
201 
Marshalling(Parcel & parcel)202 bool RSEnvForegroundColorStrategyRenderModifier::Marshalling(Parcel& parcel)
203 {
204     auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(property_);
205     return parcel.WriteInt16(static_cast<short>(RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY)) &&
206             RSMarshallingHelper::Marshalling(parcel, renderProperty);
207 }
208 
209 
Apply(RSModifierContext & context) const210 void RSEnvForegroundColorStrategyRenderModifier::Apply(RSModifierContext& context) const
211 {
212     auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(property_);
213     switch (renderProperty->Get()) {
214         case ForegroundColorStrategyType::INVERT_BACKGROUNDCOLOR: {
215             // calculate the color by screebshot
216             Color color = GetInvertBackgroundColor(context);
217             context.canvas_->SetEnvForegroundColor(color);
218             break;
219         }
220         default: {
221             break;
222         }
223     }
224 }
225 
CalculateInvertColor(Color backgroundColor) const226 Color RSEnvForegroundColorStrategyRenderModifier::CalculateInvertColor(Color backgroundColor) const
227 {
228     int16_t a = std::clamp<int16_t>(backgroundColor.GetAlpha(), 0, UINT8_MAX);
229     int16_t r = 255 - std::clamp<int16_t>(backgroundColor.GetRed(), 0, UINT8_MAX);
230     int16_t g = 255 - std::clamp<int16_t>(backgroundColor.GetGreen(), 0, UINT8_MAX);
231     int16_t b = 255 - std::clamp<int16_t>(backgroundColor.GetBlue(), 0, UINT8_MAX);
232     return Color(r, g, b, a);
233 }
234 
GetInvertBackgroundColor(RSModifierContext & context) const235 Color RSEnvForegroundColorStrategyRenderModifier::GetInvertBackgroundColor(RSModifierContext& context) const
236 {
237     Drawing::AutoCanvasRestore acr(*context.canvas_, true);
238     if (!context.properties_.GetClipToBounds()) {
239         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor not GetClipToBounds");
240         Vector4f clipRegion = context.properties_.GetBounds();
241         Drawing::Rect rect = Drawing::Rect(0, 0, clipRegion.z_, clipRegion.w_);
242         context.canvas_->ClipRect(rect, Drawing::ClipOp::INTERSECT, false);
243     }
244     Color backgroundColor = context.properties_.GetBackgroundColor();
245     if (backgroundColor.GetAlpha() == 0xff) {
246         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor not alpha");
247         return CalculateInvertColor(backgroundColor);
248     }
249     auto imageSnapshot = context.canvas_->GetSurface()->GetImageSnapshot(context.canvas_->GetDeviceClipBounds());
250     if (imageSnapshot == nullptr) {
251         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor imageSnapshot null");
252         return Color(0);
253     }
254     auto colorPicker = RSPropertiesPainter::CalcAverageColor(imageSnapshot);
255     return CalculateInvertColor(Color(
256         Drawing::Color::ColorQuadGetR(colorPicker), Drawing::Color::ColorQuadGetG(colorPicker),
257         Drawing::Color::ColorQuadGetB(colorPicker), Drawing::Color::ColorQuadGetA(colorPicker)));
258 }
259 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)260 void RSEnvForegroundColorStrategyRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
261 {
262     if (auto property = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType >>(prop)) {
263         auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType >>(property_);
264         renderProperty->Set(property->Get());
265     }
266 }
267 
Marshalling(Parcel & parcel)268 bool RSCustomClipToFrameRenderModifier::Marshalling(Parcel& parcel)
269 {
270     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(property_);
271     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::CUSTOM_CLIP_TO_FRAME)) &&
272         RSMarshallingHelper::Marshalling(parcel, renderProperty);
273 }
274 
Apply(RSModifierContext & context) const275 void RSCustomClipToFrameRenderModifier::Apply(RSModifierContext& context) const
276 {
277     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(property_);
278     const auto& rect4f = renderProperty->Get();
279     Drawing::Rect customClipRect(rect4f.x_, rect4f.y_, rect4f.z_, rect4f.w_);
280     context.canvas_->ClipRect(customClipRect);
281 }
282 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)283 void RSCustomClipToFrameRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
284 {
285     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(prop)) {
286         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(property_);
287         renderProperty->Set(property->Get());
288     }
289 }
290 
Apply(RSModifierContext & context) const291 void RSGeometryTransRenderModifier::Apply(RSModifierContext& context) const
292 {
293     auto& geoPtr = (context.properties_.GetBoundsGeometry());
294     geoPtr->ConcatMatrix(property_->Get());
295 }
296 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)297 void RSGeometryTransRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
298 {
299     if (auto property = std::static_pointer_cast<RSRenderProperty<Drawing::Matrix>>(prop)) {
300         property_->Set(property->Get());
301     }
302 }
303 
Marshalling(Parcel & parcel)304 bool RSGeometryTransRenderModifier::Marshalling(Parcel& parcel)
305 {
306     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::GEOMETRYTRANS)) &&
307            RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType()));
308 }
309 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)310 void RSBehindWindowFilterRadiusRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
311 {
312     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(prop)) {
313         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(property_);
314         renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());
315     }
316 }
317 
Marshalling(Parcel & parcel)318 bool RSBehindWindowFilterRadiusRenderModifier::Marshalling(Parcel& parcel)
319 {
320     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(property_);
321     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::BEHIND_WINDOW_FILTER_RADIUS)) &&
322         RSMarshallingHelper::Marshalling(parcel, renderProperty);
323 }
324 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)325 void RSBehindWindowFilterSaturationRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop,
326     bool isDelta)
327 {
328     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(prop)) {
329         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(property_);
330         renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());
331     }
332 }
333 
Marshalling(Parcel & parcel)334 bool RSBehindWindowFilterSaturationRenderModifier::Marshalling(Parcel& parcel)
335 {
336     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(property_);
337     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::BEHIND_WINDOW_FILTER_SATURATION)) &&
338         RSMarshallingHelper::Marshalling(parcel, renderProperty);
339 }
340 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)341 void RSBehindWindowFilterBrightnessRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop,
342     bool isDelta)
343 {
344     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(prop)) {
345         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(property_);
346         renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());
347     }
348 }
349 
Marshalling(Parcel & parcel)350 bool RSBehindWindowFilterBrightnessRenderModifier::Marshalling(Parcel& parcel)
351 {
352     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(property_);
353     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::BEHIND_WINDOW_FILTER_BRIGHTNESS)) &&
354         RSMarshallingHelper::Marshalling(parcel, renderProperty);
355 }
356 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)357 void RSBehindWindowFilterMaskColorRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop,
358     bool isDelta)
359 {
360     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(prop)) {
361         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
362         renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());
363     }
364 }
365 
Marshalling(Parcel & parcel)366 bool RSBehindWindowFilterMaskColorRenderModifier::Marshalling(Parcel& parcel)
367 {
368     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
369     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::BEHIND_WINDOW_FILTER_MASK_COLOR)) &&
370         RSMarshallingHelper::Marshalling(parcel, renderProperty);
371 }
372 
Unmarshalling(Parcel & parcel)373 RSRenderModifier* RSRenderModifier::Unmarshalling(Parcel& parcel)
374 {
375     int16_t type = 0;
376     if (!parcel.ReadInt16(type)) {
377         return nullptr;
378     }
379     auto it = funcLUT.find(static_cast<RSModifierType>(type));
380     if (it == funcLUT.end()) {
381         ROSEN_LOGE("RSRenderModifier Unmarshalling cannot find func in lut %{public}d", type);
382         return nullptr;
383     }
384     return it->second(parcel);
385 }
386 
387 namespace {
388 template<typename T>
Add(const T & a,const T && b)389 T Add(const T& a, const T&& b)
390 {
391     return a + b;
392 }
393 template<typename T>
Add(const std::optional<T> & a,const T && b)394 T Add(const std::optional<T>& a, const T&& b)
395 {
396     return a.has_value() ? *a + b : b;
397 }
398 
399 template<typename T>
Multiply(const T & a,const T && b)400 T Multiply(const T& a, const T&& b)
401 {
402     return a * b;
403 }
404 template<typename T>
Multiply(const std::optional<T> & a,const T && b)405 T Multiply(const std::optional<T>& a, const T&& b)
406 {
407     return a.has_value() ? *a * b : b;
408 }
409 
410 template<typename T>
Replace(const T & a,const T && b)411 const T& Replace(const T& a, const T&& b)
412 {
413     return b;
414 }
415 template<typename T>
Replace(const std::optional<T> & a,T && b)416 const T& Replace(const std::optional<T>& a, T&& b)
417 {
418     return b;
419 }
420 } // namespace
421 
422 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP, MODIFIER_TIER, THRESHOLD_TYPE)    \
423     bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel)                                             \
424     {                                                                                                               \
425         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);                \
426         return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::MODIFIER_TYPE)) &&                            \
427                RSMarshallingHelper::Marshalling(parcel, renderProperty);                                            \
428     }                                                                                                               \
429     void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) const                                 \
430     {                                                                                                               \
431         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);                \
432         context.properties_.Set##MODIFIER_NAME(                                                                     \
433             DELTA_OP(context.properties_.Get##MODIFIER_NAME(), renderProperty->Get()));                             \
434     }                                                                                                               \
435     void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
436     {                                                                                                               \
437         if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(prop)) {                     \
438             auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);            \
439             renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());             \
440         }                                                                                                           \
441     }
442 
443 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, MODIFIER_TIER)                            \
444     bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel)                                             \
445     {                                                                                                               \
446         auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                          \
447         return parcel.WriteInt16(static_cast<short>(RSModifierType::MODIFIER_TYPE)) &&                              \
448                RSMarshallingHelper::Marshalling(parcel, renderProperty);                                            \
449     }                                                                                                               \
450     void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) const                                 \
451     {                                                                                                               \
452         auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                          \
453         context.properties_.Set##MODIFIER_NAME(renderProperty->GetRef());                                              \
454     }                                                                                                               \
455     void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
456     {                                                                                                               \
457         if (auto property = std::static_pointer_cast<RSRenderProperty<TYPE>>(prop)) {                               \
458             auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                      \
459             renderProperty->Set(property->GetRef());                                                                   \
460         }                                                                                                           \
461     }
462 
463 #include "modifier/rs_modifiers_def.in"
464 DECLARE_NOANIMATABLE_MODIFIER(Particles, RSRenderParticleVector, PARTICLE, Foreground)
465 
466 #undef DECLARE_ANIMATABLE_MODIFIER
467 #undef DECLARE_NOANIMATABLE_MODIFIER
468 } // namespace Rosen
469 } // namespace OHOS
470