• 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 "include/effects/SkColorMatrix.h"
26 #include "pixel_map.h"
27 
28 #include "common/rs_obj_abs_geometry.h"
29 #include "modifier/rs_modifier_type.h"
30 #include "pipeline/rs_draw_cmd_list.h"
31 #include "pipeline/rs_paint_filter_canvas.h"
32 #include "property/rs_properties.h"
33 #include "property/rs_properties_def.h"
34 #include "property/rs_properties_painter.h"
35 
36 namespace OHOS {
37 namespace Rosen {
38 namespace {
39 using ModifierUnmarshallingFunc = RSRenderModifier* (*)(Parcel& parcel);
40 
41 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP, MODIFIER_TIER)        \
42     { RSModifierType::MODIFIER_TYPE, [](Parcel& parcel) -> RSRenderModifier* {                          \
43             std::shared_ptr<RSRenderAnimatableProperty<TYPE>> prop;                                     \
44             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {                                    \
45                 return nullptr;                                                                         \
46             }                                                                                           \
47             auto modifier = new RS##MODIFIER_NAME##RenderModifier(prop);                                \
48             return ((!modifier) ? nullptr : modifier);                                                  \
49         },                                                                                              \
50     },
51 
52 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, MODIFIER_TIER)                \
53     { RSModifierType::MODIFIER_TYPE, [](Parcel& parcel) -> RSRenderModifier* {                          \
54             std::shared_ptr<RSRenderProperty<TYPE>> prop;                                               \
55             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {                                    \
56                 return nullptr;                                                                         \
57             }                                                                                           \
58             auto modifier = new RS##MODIFIER_NAME##RenderModifier(prop);                                \
59             return ((!modifier) ? nullptr : modifier);                                                  \
60         },                                                                                              \
61     },
62 
63 static std::unordered_map<RSModifierType, ModifierUnmarshallingFunc> funcLUT = {
64 #include "modifier/rs_modifiers_def.in"
__anon71b58cac0202() 65     { RSModifierType::EXTENDED, [](Parcel& parcel) -> RSRenderModifier* {
66 #ifndef USE_ROSEN_DRAWING
67             std::shared_ptr<RSRenderProperty<std::shared_ptr<DrawCmdList>>> prop;
68 #else
69             std::shared_ptr<RSRenderProperty<std::shared_ptr<Drawing::DrawCmdList>>> prop;
70 #endif
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     },
__anon71b58cac0302() 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             if (!modifier) {
87                 return nullptr;
88             }
89             return modifier;
90         },
91     },
__anon71b58cac0402() 92     { RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY, [](Parcel& parcel) -> RSRenderModifier* {
93             std::shared_ptr<RSRenderProperty<ForegroundColorStrategyType>> prop;
94             if (!RSMarshallingHelper::Unmarshalling(parcel, prop)) {
95                 return nullptr;
96             }
97             auto modifier = new RSEnvForegroundColorStrategyRenderModifier(prop);
98             if (!modifier) {
99                 return nullptr;
100             }
101             return modifier;
102         },
103     },
104 
__anon71b58cac0502() 105     { RSModifierType::GEOMETRYTRANS, [](Parcel& parcel) -> RSRenderModifier* {
106 #ifndef USE_ROSEN_DRAWING
107             std::shared_ptr<RSRenderProperty<SkMatrix>> prop;
108 #else
109             std::shared_ptr<RSRenderProperty<Drawing::Matrix>> prop;
110 #endif
111             int16_t type;
112             if (!RSMarshallingHelper::Unmarshalling(parcel, prop) || !parcel.ReadInt16(type)) {
113                 return nullptr;
114             }
115             auto modifier = new RSGeometryTransRenderModifier(prop);
116             modifier->SetType(static_cast<RSModifierType>(type));
117             return modifier;
118         },
119     },
120 };
121 
122 #undef DECLARE_ANIMATABLE_MODIFIER
123 #undef DECLARE_NOANIMATABLE_MODIFIER
124 }
125 
Apply(RSModifierContext & context) const126 void RSDrawCmdListRenderModifier::Apply(RSModifierContext& context) const
127 {
128     if (context.canvas_) {
129         auto cmds = property_->Get();
130         RSPropertiesPainter::DrawFrame(context.property_, *context.canvas_, cmds);
131     }
132 }
133 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)134 void RSDrawCmdListRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
135 {
136 #ifndef USE_ROSEN_DRAWING
137     if (auto property = std::static_pointer_cast<RSRenderProperty<DrawCmdListPtr>>(prop)) {
138         property_->Set(property->Get());
139     }
140 #else
141     if (auto property = std::static_pointer_cast<RSRenderProperty<Drawing::DrawCmdListPtr>>(prop)) {
142         property_->Set(property->Get());
143     }
144 #endif
145 }
146 
Marshalling(Parcel & parcel)147 bool RSDrawCmdListRenderModifier::Marshalling(Parcel& parcel)
148 {
149     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::EXTENDED)) &&
150         RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType()));
151 }
152 
GetCmdsClipRect() const153 RectF RSDrawCmdListRenderModifier::GetCmdsClipRect() const
154 {
155 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
156     auto cmds = property_->Get();
157     return RSPropertiesPainter::GetCmdsClipRect(cmds);
158 #else
159     return RectF { 0.0f, 0.0f, 0.0f, 0.0f };
160 #endif
161 }
162 
ApplyForDrivenContent(RSModifierContext & context) const163 void RSDrawCmdListRenderModifier::ApplyForDrivenContent(RSModifierContext& context) const
164 {
165 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
166     if (context.canvas_) {
167         auto cmds = property_->Get();
168         RSPropertiesPainter::DrawFrameForDriven(context.property_, *context.canvas_, cmds);
169     }
170 #endif
171 }
172 
Apply(RSModifierContext & context) const173 void RSParticleRenderModifier::Apply(RSModifierContext& context) const
174 {
175     auto renderProperty = std::static_pointer_cast<RSRenderProperty<RSRenderParticleVector>>(property_);
176     context.property_.SetParticles(renderProperty->Get());
177 }
178 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)179 void RSParticleRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
180 {
181     if (auto property = std::static_pointer_cast<RSRenderProperty<RSRenderParticleVector>>(prop)) {
182         property_->Set(property->Get());
183     }
184 }
185 
Marshalling(Parcel & parcel)186 bool RSParticleRenderModifier::Marshalling(Parcel& parcel)
187 {
188     return true;
189 }
190 
Marshalling(Parcel & parcel)191 bool RSEnvForegroundColorRenderModifier::Marshalling(Parcel& parcel)
192 {
193     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
194     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::ENV_FOREGROUND_COLOR)) &&
195             RSMarshallingHelper::Marshalling(parcel, renderProperty);
196 }
197 
Apply(RSModifierContext & context) const198 void RSEnvForegroundColorRenderModifier::Apply(RSModifierContext& context) const
199 {
200     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
201     context.canvas_->SetEnvForegroundColor(renderProperty->Get());
202 }
203 
Update(const std::shared_ptr<RSRenderPropertyBase> & prop,bool isDelta)204 void RSEnvForegroundColorRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
205 {
206     if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(prop)) {
207         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(property_);
208         renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());
209     }
210 }
211 
Marshalling(Parcel & parcel)212 bool RSEnvForegroundColorStrategyRenderModifier::Marshalling(Parcel& parcel)
213 {
214     auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(property_);
215     return parcel.WriteInt16(static_cast<short>(RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY)) &&
216             RSMarshallingHelper::Marshalling(parcel, renderProperty);
217 }
218 
219 
Apply(RSModifierContext & context) const220 void RSEnvForegroundColorStrategyRenderModifier::Apply(RSModifierContext& context) const
221 {
222     auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(property_);
223     switch (renderProperty->Get()) {
224         case ForegroundColorStrategyType::INVERT_BACKGROUNDCOLOR: {
225             // calculate the color by screebshot
226             Color color = GetInvertBackgroundColor(context);
227             context.canvas_->SetEnvForegroundColor(color);
228             break;
229         }
230         default: {
231             break;
232         }
233     }
234 }
235 
CalculateInvertColor(Color backgroundColor) const236 Color RSEnvForegroundColorStrategyRenderModifier::CalculateInvertColor(Color backgroundColor) const
237 {
238     uint32_t a = backgroundColor.GetAlpha();
239     uint32_t r = 255 - backgroundColor.GetRed();
240     uint32_t g = 255 - backgroundColor.GetGreen();
241     uint32_t b = 255 - backgroundColor.GetBlue();
242     return Color(r, g, b, a);
243 }
244 
GetInvertBackgroundColor(RSModifierContext & context) const245 Color RSEnvForegroundColorStrategyRenderModifier::GetInvertBackgroundColor(RSModifierContext& context) const
246 {
247 #ifdef ROSEN_OHOS
248 #ifndef USE_ROSEN_DRAWING
249     SkAutoCanvasRestore acr(context.canvas_, true);
250 #else
251     Drawing::AutoCanvasRestore acr(*context.canvas_, true);
252 #endif
253     if (!context.property_.GetClipToBounds()) {
254         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor not GetClipToBounds");
255         Vector4f clipRegion = context.property_.GetBounds();
256 #ifndef USE_ROSEN_DRAWING
257         SkRect rect = SkRect::MakeXYWH(0, 0, clipRegion.z_, clipRegion.w_);
258         context.canvas_->clipRect(rect);
259 #else
260         Drawing::Rect rect = Drawing::Rect(0, 0, clipRegion.z_, clipRegion.w_);
261         context.canvas_->ClipRect(rect, Drawing::ClipOp::INTERSECT, false);
262 #endif
263     }
264     Color backgroundColor = context.property_.GetBackgroundColor();
265     if (backgroundColor.GetAlpha() == 0xff) {
266         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor not alpha");
267         return CalculateInvertColor(backgroundColor);
268     }
269 #ifndef USE_ROSEN_DRAWING
270     auto imageSnapshot = context.canvas_->GetSurface()->makeImageSnapshot(context.canvas_->getDeviceClipBounds());
271 #else
272     auto imageSnapshot = context.canvas_->GetSurface()->GetImageSnapshot(context.canvas_->GetDeviceClipBounds());
273 #endif
274     if (imageSnapshot == nullptr) {
275         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor imageSnapshot null");
276         return Color(0);
277     }
278     Media::InitializationOptions opts;
279     opts.size.width = context.property_.GetBoundsWidth();
280     opts.size.height = context.property_.GetBoundsHeight();
281     if (opts.size.width == 0 || opts.size.height == 0) {
282         RS_LOGI("RSRenderModifier::GetInvertBackgroundColor opts.size.width/height == 0");
283         return Color(0);
284     }
285     std::unique_ptr<Media::PixelMap> pixelmap = Media::PixelMap::Create(opts);
286     uint8_t* data = static_cast<uint8_t*>(malloc(pixelmap->GetRowBytes() * pixelmap->GetHeight()));
287     if (data == nullptr) {
288         RS_LOGE("RSRenderModifier::GetInvertBackgroundColor: data is nullptr");
289         return Color(0);
290     }
291 #ifndef USE_ROSEN_DRAWING
292     SkImageInfo info = SkImageInfo::Make(pixelmap->GetWidth(), pixelmap->GetHeight(),
293         kRGBA_8888_SkColorType, kPremul_SkAlphaType);
294     if (!imageSnapshot->readPixels(info, data, pixelmap->GetRowBytes(), 0, 0)) {
295 #else
296     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
297     Drawing::Bitmap bitmap;
298     bitmap.Build(pixelmap->GetWidth(), pixelmap->GetHeight(), format);
299     bitmap.SetPixels(data);
300     if (!imageSnapshot->ReadPixels(bitmap, 0, 0)) {
301 #endif
302         RS_LOGE("RSRenderModifier::Run: readPixels failed");
303         free(data);
304         data = nullptr;
305         return Color(0);
306     }
307     pixelmap->SetPixelsAddr(data, nullptr, pixelmap->GetRowBytes() * pixelmap->GetHeight(),
308         Media::AllocatorType::HEAP_ALLOC, nullptr);
309     OHOS::Media::InitializationOptions options;
310     options.alphaType = pixelmap->GetAlphaType();
311     options.pixelFormat = pixelmap->GetPixelFormat();
312     options.scaleMode = OHOS::Media::ScaleMode::FIT_TARGET_SIZE;
313     options.size.width = 1;
314     options.size.height = 1;
315     options.editable = true;
316     std::unique_ptr<Media::PixelMap> newPixelMap = Media::PixelMap::Create(*pixelmap.get(), options);
317     uint32_t colorVal = 0;
318     newPixelMap->GetARGB32Color(0, 0, colorVal);
319     return CalculateInvertColor(Color(colorVal));
320 #else
321     return Color(0);
322 #endif
323 }
324 
325 void RSEnvForegroundColorStrategyRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
326 {
327     if (auto property = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType >>(prop)) {
328         auto renderProperty = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType >>(property_);
329         renderProperty->Set(property->Get());
330     }
331 }
332 
333 void RSGeometryTransRenderModifier::Apply(RSModifierContext& context) const
334 {
335     auto geoPtr = (context.property_.GetBoundsGeometry());
336     auto property = property_->Get();
337     geoPtr->ConcatMatrix(property);
338 }
339 
340 void RSGeometryTransRenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)
341 {
342 #ifndef USE_ROSEN_DRAWING
343     if (auto property = std::static_pointer_cast<RSRenderProperty<SkMatrix>>(prop)) {
344 #else
345     if (auto property = std::static_pointer_cast<RSRenderProperty<Drawing::Matrix>>(prop)) {
346 #endif
347         property_->Set(property->Get());
348     }
349 }
350 
351 bool RSGeometryTransRenderModifier::Marshalling(Parcel& parcel)
352 {
353     return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::GEOMETRYTRANS)) &&
354            RSMarshallingHelper::Marshalling(parcel, property_) && parcel.WriteInt16(static_cast<int16_t>(GetType()));
355 }
356 
357 RSRenderModifier* RSRenderModifier::Unmarshalling(Parcel& parcel)
358 {
359     int16_t type = 0;
360     if (!parcel.ReadInt16(type)) {
361         return nullptr;
362     }
363     auto it = funcLUT.find(static_cast<RSModifierType>(type));
364     if (it == funcLUT.end()) {
365         ROSEN_LOGE("RSRenderModifier Unmarshalling cannot find func in lut %d", type);
366         return nullptr;
367     }
368     return it->second(parcel);
369 }
370 
371 namespace {
372 template<typename T>
373 T Add(T a, T b)
374 {
375     return a + b;
376 }
377 template<typename T>
378 T Add(const std::optional<T>& a, T b)
379 {
380     return a.has_value() ? *a + b : b;
381 }
382 
383 template<typename T>
384 T Multiply(T a, T b)
385 {
386     return a * b;
387 }
388 template<typename T>
389 T Multiply(const std::optional<T>& a, T b)
390 {
391     return a.has_value() ? *a * b : b;
392 }
393 
394 template<typename T>
395 T Replace(T a, T b)
396 {
397     return b;
398 }
399 template<typename T>
400 T Replace(const std::optional<T>& a, T b)
401 {
402     return b;
403 }
404 } // namespace
405 
406 #define DECLARE_ANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, DELTA_OP, MODIFIER_TIER)                       \
407     bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel)                                                \
408     {                                                                                                                  \
409         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);                   \
410         return parcel.WriteInt16(static_cast<int16_t>(RSModifierType::MODIFIER_TYPE)) &&                               \
411                RSMarshallingHelper::Marshalling(parcel, renderProperty);                                               \
412     }                                                                                                                  \
413     void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) const                                    \
414     {                                                                                                                  \
415         auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);                   \
416         context.property_.Set##MODIFIER_NAME(DELTA_OP(context.property_.Get##MODIFIER_NAME(), renderProperty->Get())); \
417     }                                                                                                                  \
418     void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta)    \
419     {                                                                                                                  \
420         if (auto property = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(prop)) {                        \
421             auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<TYPE>>(property_);               \
422             renderProperty->Set(isDelta ? (renderProperty->Get() + property->Get()) : property->Get());                \
423         }                                                                                                              \
424     }
425 
426 #define DECLARE_NOANIMATABLE_MODIFIER(MODIFIER_NAME, TYPE, MODIFIER_TYPE, MODIFIER_TIER)                            \
427     bool RS##MODIFIER_NAME##RenderModifier::Marshalling(Parcel& parcel)                                             \
428     {                                                                                                               \
429         auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                          \
430         return parcel.WriteInt16(static_cast<short>(RSModifierType::MODIFIER_TYPE)) &&                              \
431                RSMarshallingHelper::Marshalling(parcel, renderProperty);                                            \
432     }                                                                                                               \
433     void RS##MODIFIER_NAME##RenderModifier::Apply(RSModifierContext& context) const                                 \
434     {                                                                                                               \
435         auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                          \
436         context.property_.Set##MODIFIER_NAME(renderProperty->Get());                                                \
437     }                                                                                                               \
438     void RS##MODIFIER_NAME##RenderModifier::Update(const std::shared_ptr<RSRenderPropertyBase>& prop, bool isDelta) \
439     {                                                                                                               \
440         if (auto property = std::static_pointer_cast<RSRenderProperty<TYPE>>(prop)) {                               \
441             auto renderProperty = std::static_pointer_cast<RSRenderProperty<TYPE>>(property_);                      \
442             renderProperty->Set(property->Get());                                                                   \
443         }                                                                                                           \
444     }
445 
446 #include "modifier/rs_modifiers_def.in"
447 
448 #undef DECLARE_ANIMATABLE_MODIFIER
449 #undef DECLARE_NOANIMATABLE_MODIFIER
450 } // namespace Rosen
451 } // namespace OHOS
452