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