• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef USE_ROSEN_DRAWING
18 #else
19 #include "draw/color.h"
20 #include "image/bitmap.h"
21 #endif
22 #include <memory>
23 #include <unordered_map>
24 
25 #include "pixel_map.h"
26 
27 #include "animation/rs_render_particle.h"
28 #include "common/rs_obj_abs_geometry.h"
29 #include "common/rs_vector2.h"
30 #include "common/rs_vector4.h"
31 #include "modifier/rs_modifier_type.h"
32 #include "pipeline/rs_draw_cmd_list.h"
33 #include "pipeline/rs_paint_filter_canvas.h"
34 #include "platform/common/rs_log.h"
35 #include "property/rs_properties.h"
36 #include "property/rs_properties_def.h"
37 #include "property/rs_properties_painter.h"
38 #include "render/rs_filter.h"
39 #include "render/rs_image.h"
40 #include "render/rs_mask.h"
41 #include "render/rs_path.h"
42 #include "render/rs_shader.h"
43 
44 namespace OHOS {
45 namespace Rosen {
46 namespace {
47 using ModifierUnmarshallingFunc = RSRenderModifier* (*)(Parcel& parcel);
48 
49 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP, MODIFIER_TIER, THRESHOLD_TYPE) \
50     { RSModifierType::MODIFIER_TYPE, [](Parcel& parcel) -> RSRenderModifier* {                                   \
51             std::shared_ptr<RSRenderAnimatableProperty<TYPE>> prop;                                              \
52             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {                                             \
53                 return nullptr;                                                                                  \
54             }                                                                                                    \
55             auto modifier = new RS##MODIFIER_NAME##RenderModifier(prop);                                         \
56             return ((!modifier) ? nullptr : modifier);                                                           \
57         },                                                                                                       \
58     },
59 
60 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, MODIFIER_TIER)                \
61     { RSModifierType::MODIFIER_TYPE, [](Parcel& parcel) -> RSRenderModifier* {                          \
62             std::shared_ptr<RSRenderProperty<TYPE>> prop;                                               \
63             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {                                    \
64                 return nullptr;                                                                         \
65             }                                                                                           \
66             auto modifier = new RS##MODIFIER_NAME##RenderModifier(prop);                                \
67             return ((!modifier) ? nullptr : modifier);                                                  \
68         },                                                                                              \
69     },
70 
71 static std::unordered_map<RSModifierType, ModifierUnmarshallingFunc> funcLUT = {
72 #include "modifier/rs_modifiers_def.in"
__anon216fe68e0202() 73     { RSModifierType::EXTENDED, [](Parcel& parcel) -> RSRenderModifier* {
74 #ifndef USE_ROSEN_DRAWING
75             std::shared_ptr<RSRenderProperty<std::shared_ptr<DrawCmdList>>> prop;
76 #else
77             std::shared_ptr<RSRenderProperty<std::shared_ptr<Drawing::DrawCmdList>>> prop;
78 #endif
79             int16_t type;
80             if (!RSMarshallingHelper::Unmarshalling(parcel, prop) || !parcel.ReadInt16(type)) {
81                 return nullptr;
82             }
83             RSDrawCmdListRenderModifier* modifier = new RSDrawCmdListRenderModifier(prop);
84             modifier->SetType(static_cast<RSModifierType>(type));
85             return modifier;
86         },
87     },
__anon216fe68e0302() 88     { RSModifierType::ENV_FOREGROUND_COLOR, [](Parcel& parcel) -> RSRenderModifier* {
89             std::shared_ptr<RSRenderAnimatableProperty<Color>> prop;
90             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
91                 return nullptr;
92             }
93             auto modifier = new RSEnvForegroundColorRenderModifier(prop);
94             if (!modifier) {
95                 return nullptr;
96             }
97             return modifier;
98         },
99     },
__anon216fe68e0402() 100     { RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY, [](Parcel& parcel) -> RSRenderModifier* {
101             std::shared_ptr<RSRenderProperty<ForegroundColorStrategyType>> prop;
102             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
103                 return nullptr;
104             }
105             auto modifier = new RSEnvForegroundColorStrategyRenderModifier(prop);
106             if (!modifier) {
107                 return nullptr;
108             }
109             return modifier;
110         },
111     },
__anon216fe68e0502() 112     { RSModifierType::GEOMETRYTRANS, [](Parcel& parcel) -> RSRenderModifier* {
113 #ifndef USE_ROSEN_DRAWING
114             std::shared_ptr<RSRenderProperty<SkMatrix>> prop;
115 #else
116             std::shared_ptr<RSRenderProperty<Drawing::Matrix>> prop;
117 #endif
118             int16_t type;
119             if (!RSMarshallingHelper::Unmarshalling(parcel, prop) || !parcel.ReadInt16(type)) {
120                 return nullptr;
121             }
122             auto modifier = new RSGeometryTransRenderModifier(prop);
123             modifier->SetType(static_cast<RSModifierType>(type));
124             return modifier;
125         },
126     },
127 };
128 
129 #undef DECLARE_ANIMATABLE_MODIFIER
130 #undef DECLARE_NOANIMATABLE_MODIFIER
131 }
132 
Apply(RSModifierContext & context) const133 void RSDrawCmdListRenderModifier::Apply(RSModifierContext& context) const
134 {
135     if (context.canvas_) {
136         auto& cmds = property_->GetRef();
137         RSPropertiesPainter::DrawFrame(context.properties_, *context.canvas_, cmds);
138     }
139 }
140 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)141 void RSDrawCmdListRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
142 {
143 #ifndef USE_ROSEN_DRAWING
144     if (auto property = std::static_pointer_cast<RSRenderProperty<DrawCmdListPtr>>(prop)) {
145         property_->Set(property->Get());
146     }
147 #else
148     if (auto property = std::static_pointer_cast<RSRenderProperty<Drawing::DrawCmdListPtr>>(prop)) {
149         property_->Set(property->Get());
150     }
151 #endif
152 }
153 
Marshalling(Parcel & parcel)154 bool RSDrawCmdListRenderModifier::Marshalling(Parcel& parcel)
155 {
156     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::EXTENDED)) &&
157         RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType()));
158 }
159 
GetCmdsClipRect() const160 RectF RSDrawCmdListRenderModifier::GetCmdsClipRect() const
161 {
162 #if defined(RS_ENABLE_DRIVEN_RENDER)
163     auto cmds = property_->Get();
164     return RSPropertiesPainter::GetCmdsClipRect(cmds);
165 #else
166     return RectF { 0.0f, 0.0f, 0.0f, 0.0f };
167 #endif
168 }
169 
ApplyForDrivenContent(RSModifierContext & context) const170 void RSDrawCmdListRenderModifier::ApplyForDrivenContent(RSModifierContext& context) const
171 {
172 #if defined(RS_ENABLE_DRIVEN_RENDER)
173     if (context.canvas_) {
174         auto cmds = property_->Get();
175         RSPropertiesPainter::DrawFrameForDriven(context.properties_, *context.canvas_, cmds);
176     }
177 #endif
178 }
179 
Marshalling(Parcel & parcel)180 bool RSEnvForegroundColorRenderModifier::Marshalling(Parcel& parcel)
181 {
182     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
183     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::ENV_FOREGROUND_COLOR)) &&
184             RSMarshallingHelper::Marshalling(parcel, renderProperty);
185 }
186 
Apply(RSModifierContext & context) const187 void RSEnvForegroundColorRenderModifier::Apply(RSModifierContext& context) const
188 {
189     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
190     context.canvas_->SetEnvForegroundColor(renderProperty->Get());
191 }
192 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)193 void RSEnvForegroundColorRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
194 {
195     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(prop)) {
196         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
197         renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());
198     }
199 }
200 
Marshalling(Parcel & parcel)201 bool RSEnvForegroundColorStrategyRenderModifier::Marshalling(Parcel& parcel)
202 {
203     auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(property_);
204     return parcel.WriteInt16(static_cast<short>(RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY)) &&
205             RSMarshallingHelper::Marshalling(parcel, renderProperty);
206 }
207 
208 
Apply(RSModifierContext & context) const209 void RSEnvForegroundColorStrategyRenderModifier::Apply(RSModifierContext& context) const
210 {
211     auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(property_);
212     switch (renderProperty->Get()) {
213         case ForegroundColorStrategyType::INVERT_BACKGROUNDCOLOR: {
214             // calculate the color by screebshot
215             Color color = GetInvertBackgroundColor(context);
216             context.canvas_->SetEnvForegroundColor(color);
217             break;
218         }
219         default: {
220             break;
221         }
222     }
223 }
224 
CalculateInvertColor(Color backgroundColor) const225 Color RSEnvForegroundColorStrategyRenderModifier::CalculateInvertColor(Color backgroundColor) const
226 {
227     uint32_t a = backgroundColor.GetAlpha();
228     uint32_t r = 255 - backgroundColor.GetRed();
229     uint32_t g = 255 - backgroundColor.GetGreen();
230     uint32_t b = 255 - backgroundColor.GetBlue();
231     return Color(r, g, b, a);
232 }
233 
GetInvertBackgroundColor(RSModifierContext & context) const234 Color RSEnvForegroundColorStrategyRenderModifier::GetInvertBackgroundColor(RSModifierContext& context) const
235 {
236 #ifndef USE_ROSEN_DRAWING
237     SkAutoCanvasRestore acr(context.canvas_, true);
238 #else
239     Drawing::AutoCanvasRestore acr(*context.canvas_, true);
240 #endif
241     if (!context.properties_.GetClipToBounds()) {
242         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor not GetClipToBounds");
243         Vector4f clipRegion = context.properties_.GetBounds();
244 #ifndef USE_ROSEN_DRAWING
245         SkRect rect = SkRect::MakeXYWH(0, 0, clipRegion.z_, clipRegion.w_);
246         context.canvas_->clipRect(rect);
247 #else
248         Drawing::Rect rect = Drawing::Rect(0, 0, clipRegion.z_, clipRegion.w_);
249         context.canvas_->ClipRect(rect, Drawing::ClipOp::INTERSECT, false);
250 #endif
251     }
252     Color backgroundColor = context.properties_.GetBackgroundColor();
253     if (backgroundColor.GetAlpha() == 0xff) {
254         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor not alpha");
255         return CalculateInvertColor(backgroundColor);
256     }
257 #ifndef USE_ROSEN_DRAWING
258     auto imageSnapshot = context.canvas_->GetSurface()->makeImageSnapshot(context.canvas_->getDeviceClipBounds());
259 #else
260     auto imageSnapshot = context.canvas_->GetSurface()->GetImageSnapshot(context.canvas_->GetDeviceClipBounds());
261 #endif
262     if (imageSnapshot == nullptr) {
263         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor imageSnapshot null");
264         return Color(0);
265     }
266     auto colorPicker = RSPropertiesPainter::CalcAverageColor(imageSnapshot);
267 #ifndef USE_ROSEN_DRAWING
268     return CalculateInvertColor(Color(SkColorGetR(colorPicker), SkColorGetG(colorPicker),
269         SkColorGetB(colorPicker), SkColorGetA(colorPicker)));
270 #else
271     return CalculateInvertColor(Color(
272         Drawing::Color::ColorQuadGetR(colorPicker), Drawing::Color::ColorQuadGetG(colorPicker),
273         Drawing::Color::ColorQuadGetB(colorPicker), Drawing::Color::ColorQuadGetA(colorPicker)));
274 #endif
275 }
276 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)277 void RSEnvForegroundColorStrategyRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
278 {
279     if (auto property = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType >>(prop)) {
280         auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType >>(property_);
281         renderProperty->Set(property->Get());
282     }
283 }
284 
Apply(RSModifierContext & context) const285 void RSGeometryTransRenderModifier::Apply(RSModifierContext& context) const
286 {
287     auto geoPtr = (context.properties_.GetBoundsGeometry());
288     auto property = property_->Get();
289     geoPtr->ConcatMatrix(property);
290 }
291 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)292 void RSGeometryTransRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
293 {
294 #ifndef USE_ROSEN_DRAWING
295     if (auto property = std::static_pointer_cast<RSRenderProperty<SkMatrix>>(prop)) {
296 #else
297     if (auto property = std::static_pointer_cast<RSRenderProperty<Drawing::Matrix>>(prop)) {
298 #endif
299         property_->Set(property->Get());
300     }
301 }
302 
303 bool RSGeometryTransRenderModifier::Marshalling(Parcel& parcel)
304 {
305     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::GEOMETRYTRANS)) &&
306            RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType()));
307 }
308 
309 RSRenderModifier* RSRenderModifier::Unmarshalling(Parcel& parcel)
310 {
311     int16_t type = 0;
312     if (!parcel.ReadInt16(type)) {
313         return nullptr;
314     }
315     auto it = funcLUT.find(static_cast<RSModifierType>(type));
316     if (it == funcLUT.end()) {
317         ROSEN_LOGE("RSRenderModifier Unmarshalling cannot find func in lut %{public}d", type);
318         return nullptr;
319     }
320     return it->second(parcel);
321 }
322 
323 namespace {
324 template<typename T>
325 T Add(const T& a, const T&& b)
326 {
327     return a + b;
328 }
329 template<typename T>
330 T Add(const std::optional<T>& a, const T&& b)
331 {
332     return a.has_value() ? *a + b : b;
333 }
334 
335 template<typename T>
336 T Multiply(const T& a, const T&& b)
337 {
338     return a * b;
339 }
340 template<typename T>
341 T Multiply(const std::optional<T>& a, const T&& b)
342 {
343     return a.has_value() ? *a * b : b;
344 }
345 
346 template<typename T>
347 const T& Replace(const T& a, const T&& b)
348 {
349     return b;
350 }
351 template<typename T>
352 const T& Replace(const std::optional<T>& a, T&& b)
353 {
354     return b;
355 }
356 } // namespace
357 
358 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP, MODIFIER_TIER, THRESHOLD_TYPE)    \
359     bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel)                                             \
360     {                                                                                                               \
361         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);                \
362         return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::MODIFIER_TYPE)) &&                            \
363                RSMarshallingHelper::Marshalling(parcel, renderProperty);                                            \
364     }                                                                                                               \
365     void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) const                                 \
366     {                                                                                                               \
367         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);                \
368         context.properties_.Set##MODIFIER_NAME(                                                                     \
369             DELTA_OP(context.properties_.Get##MODIFIER_NAME(), renderProperty->Get()));                             \
370     }                                                                                                               \
371     void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
372     {                                                                                                               \
373         if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(prop)) {                     \
374             auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);            \
375             renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());             \
376         }                                                                                                           \
377     }
378 
379 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, MODIFIER_TIER)                            \
380     bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel)                                             \
381     {                                                                                                               \
382         auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                          \
383         return parcel.WriteInt16(static_cast<short>(RSModifierType::MODIFIER_TYPE)) &&                              \
384                RSMarshallingHelper::Marshalling(parcel, renderProperty);                                            \
385     }                                                                                                               \
386     void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) const                                 \
387     {                                                                                                               \
388         auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                          \
389         context.properties_.Set##MODIFIER_NAME(renderProperty->Get());                                              \
390     }                                                                                                               \
391     void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
392     {                                                                                                               \
393         if (auto property = std::static_pointer_cast<RSRenderProperty<TYPE>>(prop)) {                               \
394             auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                      \
395             renderProperty->Set(property->Get());                                                                   \
396         }                                                                                                           \
397     }
398 
399 #include "modifier/rs_modifiers_def.in"
400 DECLARE_NOANIMATABLE_MODIFIER(Particles, RSRenderParticleVector, PARTICLE, Foreground)
401 
402 #undef DECLARE_ANIMATABLE_MODIFIER
403 #undef DECLARE_NOANIMATABLE_MODIFIER
404 } // namespace Rosen
405 } // namespace OHOS
406