• 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 #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"
__anon5f7ebaad0202() 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     },
__anon5f7ebaad0302() 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     },
__anon5f7ebaad0402() 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     },
__anon5f7ebaad0502() 98     { RSModifierType::GEOMETRYTRANS, [](Parcel& parcel) -> RSRenderModifier* {
99             std::shared_ptr<RSRenderProperty<Drawing::Matrix>> prop;
100             int16_t type;
101             if (!RSMarshallingHelper::Unmarshalling(parcel, prop) || !parcel.ReadInt16(type)) {
102                 return nullptr;
103             }
104             auto modifier = new RSGeometryTransRenderModifier(prop);
105             modifier->SetType(static_cast<RSModifierType>(type));
106             return modifier;
107         },
108     },
109 };
110 
111 #undef DECLARE_ANIMATABLE_MODIFIER
112 #undef DECLARE_NOANIMATABLE_MODIFIER
113 }
114 
Apply(RSModifierContext & context) const115 void RSDrawCmdListRenderModifier::Apply(RSModifierContext& context) const
116 {
117     if (context.canvas_) {
118         auto& cmds = property_->GetRef();
119         RSPropertiesPainter::DrawFrame(context.properties_, *context.canvas_, cmds);
120     }
121 }
122 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)123 void RSDrawCmdListRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
124 {
125     if (auto property = std::static_pointer_cast<RSRenderProperty<Drawing::DrawCmdListPtr>>(prop)) {
126         property_->Set(property->Get());
127     }
128 }
129 
Marshalling(Parcel & parcel)130 bool RSDrawCmdListRenderModifier::Marshalling(Parcel& parcel)
131 {
132     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::EXTENDED)) &&
133         RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType()));
134 }
135 
Marshalling(Parcel & parcel)136 bool RSEnvForegroundColorRenderModifier::Marshalling(Parcel& parcel)
137 {
138     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
139     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::ENV_FOREGROUND_COLOR)) &&
140             RSMarshallingHelper::Marshalling(parcel, renderProperty);
141 }
142 
Apply(RSModifierContext & context) const143 void RSEnvForegroundColorRenderModifier::Apply(RSModifierContext& context) const
144 {
145     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
146     context.canvas_->SetEnvForegroundColor(renderProperty->Get());
147 }
148 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)149 void RSEnvForegroundColorRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
150 {
151     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(prop)) {
152         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
153         renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());
154     }
155 }
156 
Marshalling(Parcel & parcel)157 bool RSEnvForegroundColorStrategyRenderModifier::Marshalling(Parcel& parcel)
158 {
159     auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(property_);
160     return parcel.WriteInt16(static_cast<short>(RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY)) &&
161             RSMarshallingHelper::Marshalling(parcel, renderProperty);
162 }
163 
164 
Apply(RSModifierContext & context) const165 void RSEnvForegroundColorStrategyRenderModifier::Apply(RSModifierContext& context) const
166 {
167     auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(property_);
168     switch (renderProperty->Get()) {
169         case ForegroundColorStrategyType::INVERT_BACKGROUNDCOLOR: {
170             // calculate the color by screebshot
171             Color color = GetInvertBackgroundColor(context);
172             context.canvas_->SetEnvForegroundColor(color);
173             break;
174         }
175         default: {
176             break;
177         }
178     }
179 }
180 
CalculateInvertColor(Color backgroundColor) const181 Color RSEnvForegroundColorStrategyRenderModifier::CalculateInvertColor(Color backgroundColor) const
182 {
183     int16_t a = std::clamp<int16_t>(backgroundColor.GetAlpha(), 0, UINT8_MAX);
184     int16_t r = 255 - std::clamp<int16_t>(backgroundColor.GetRed(), 0, UINT8_MAX);
185     int16_t g = 255 - std::clamp<int16_t>(backgroundColor.GetGreen(), 0, UINT8_MAX);
186     int16_t b = 255 - std::clamp<int16_t>(backgroundColor.GetBlue(), 0, UINT8_MAX);
187     return Color(r, g, b, a);
188 }
189 
GetInvertBackgroundColor(RSModifierContext & context) const190 Color RSEnvForegroundColorStrategyRenderModifier::GetInvertBackgroundColor(RSModifierContext& context) const
191 {
192     Drawing::AutoCanvasRestore acr(*context.canvas_, true);
193     if (!context.properties_.GetClipToBounds()) {
194         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor not GetClipToBounds");
195         Vector4f clipRegion = context.properties_.GetBounds();
196         Drawing::Rect rect = Drawing::Rect(0, 0, clipRegion.z_, clipRegion.w_);
197         context.canvas_->ClipRect(rect, Drawing::ClipOp::INTERSECT, false);
198     }
199     Color backgroundColor = context.properties_.GetBackgroundColor();
200     if (backgroundColor.GetAlpha() == 0xff) {
201         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor not alpha");
202         return CalculateInvertColor(backgroundColor);
203     }
204     auto imageSnapshot = context.canvas_->GetSurface()->GetImageSnapshot(context.canvas_->GetDeviceClipBounds());
205     if (imageSnapshot == nullptr) {
206         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor imageSnapshot null");
207         return Color(0);
208     }
209     auto colorPicker = RSPropertiesPainter::CalcAverageColor(imageSnapshot);
210     return CalculateInvertColor(Color(
211         Drawing::Color::ColorQuadGetR(colorPicker), Drawing::Color::ColorQuadGetG(colorPicker),
212         Drawing::Color::ColorQuadGetB(colorPicker), Drawing::Color::ColorQuadGetA(colorPicker)));
213 }
214 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)215 void RSEnvForegroundColorStrategyRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
216 {
217     if (auto property = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType >>(prop)) {
218         auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType >>(property_);
219         renderProperty->Set(property->Get());
220     }
221 }
222 
Apply(RSModifierContext & context) const223 void RSGeometryTransRenderModifier::Apply(RSModifierContext& context) const
224 {
225     auto& geoPtr = (context.properties_.GetBoundsGeometry());
226     geoPtr->ConcatMatrix(property_->Get());
227 }
228 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)229 void RSGeometryTransRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
230 {
231     if (auto property = std::static_pointer_cast<RSRenderProperty<Drawing::Matrix>>(prop)) {
232         property_->Set(property->Get());
233     }
234 }
235 
Marshalling(Parcel & parcel)236 bool RSGeometryTransRenderModifier::Marshalling(Parcel& parcel)
237 {
238     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::GEOMETRYTRANS)) &&
239            RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType()));
240 }
241 
Unmarshalling(Parcel & parcel)242 RSRenderModifier* RSRenderModifier::Unmarshalling(Parcel& parcel)
243 {
244     int16_t type = 0;
245     if (!parcel.ReadInt16(type)) {
246         return nullptr;
247     }
248     auto it = funcLUT.find(static_cast<RSModifierType>(type));
249     if (it == funcLUT.end()) {
250         ROSEN_LOGE("RSRenderModifier Unmarshalling cannot find func in lut %{public}d", type);
251         return nullptr;
252     }
253     return it->second(parcel);
254 }
255 
256 namespace {
257 template<typename T>
Add(const T & a,const T && b)258 T Add(const T& a, const T&& b)
259 {
260     return a + b;
261 }
262 template<typename T>
Add(const std::optional<T> & a,const T && b)263 T Add(const std::optional<T>& a, const T&& b)
264 {
265     return a.has_value() ? *a + b : b;
266 }
267 
268 template<typename T>
Multiply(const T & a,const T && b)269 T Multiply(const T& a, const T&& b)
270 {
271     return a * b;
272 }
273 template<typename T>
Multiply(const std::optional<T> & a,const T && b)274 T Multiply(const std::optional<T>& a, const T&& b)
275 {
276     return a.has_value() ? *a * b : b;
277 }
278 
279 template<typename T>
Replace(const T & a,const T && b)280 const T& Replace(const T& a, const T&& b)
281 {
282     return b;
283 }
284 template<typename T>
Replace(const std::optional<T> & a,T && b)285 const T& Replace(const std::optional<T>& a, T&& b)
286 {
287     return b;
288 }
289 } // namespace
290 
291 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP, MODIFIER_TIER, THRESHOLD_TYPE)    \
292     bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel)                                             \
293     {                                                                                                               \
294         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);                \
295         return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::MODIFIER_TYPE)) &&                            \
296                RSMarshallingHelper::Marshalling(parcel, renderProperty);                                            \
297     }                                                                                                               \
298     void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) const                                 \
299     {                                                                                                               \
300         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);                \
301         context.properties_.Set##MODIFIER_NAME(                                                                     \
302             DELTA_OP(context.properties_.Get##MODIFIER_NAME(), renderProperty->Get()));                             \
303     }                                                                                                               \
304     void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
305     {                                                                                                               \
306         if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(prop)) {                     \
307             auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);            \
308             renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());             \
309         }                                                                                                           \
310     }
311 
312 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, MODIFIER_TIER)                            \
313     bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel)                                             \
314     {                                                                                                               \
315         auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                          \
316         return parcel.WriteInt16(static_cast<short>(RSModifierType::MODIFIER_TYPE)) &&                              \
317                RSMarshallingHelper::Marshalling(parcel, renderProperty);                                            \
318     }                                                                                                               \
319     void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) const                                 \
320     {                                                                                                               \
321         auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                          \
322         context.properties_.Set##MODIFIER_NAME(renderProperty->GetRef());                                              \
323     }                                                                                                               \
324     void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
325     {                                                                                                               \
326         if (auto property = std::static_pointer_cast<RSRenderProperty<TYPE>>(prop)) {                               \
327             auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                      \
328             renderProperty->Set(property->GetRef());                                                                   \
329         }                                                                                                           \
330     }
331 
332 #include "modifier/rs_modifiers_def.in"
333 DECLARE_NOANIMATABLE_MODIFIER(Particles, RSRenderParticleVector, PARTICLE, Foreground)
334 
335 #undef DECLARE_ANIMATABLE_MODIFIER
336 #undef DECLARE_NOANIMATABLE_MODIFIER
337 } // namespace Rosen
338 } // namespace OHOS
339