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