1 /*
2 * Copyright (c) 2025 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_ng/rs_render_modifier_ng.h"
17
18 #include "recording/draw_cmd_list.h"
19 #include "rs_trace.h"
20
21 #include "modifier/rs_render_property.h"
22 #include "modifier_ng/appearance/rs_alpha_render_modifier.h"
23 #include "modifier_ng/appearance/rs_background_filter_render_modifier.h"
24 #include "modifier_ng/appearance/rs_behind_window_filter_render_modifier.h"
25 #include "modifier_ng/appearance/rs_blend_render_modifier.h"
26 #include "modifier_ng/appearance/rs_border_render_modifier.h"
27 #include "modifier_ng/appearance/rs_compositing_filter_render_modifier.h"
28 #include "modifier_ng/appearance/rs_dynamic_light_up_render_modifier.h"
29 #include "modifier_ng/appearance/rs_foreground_filter_render_modifier.h"
30 #include "modifier_ng/appearance/rs_hdr_brightness_render_modifier.h"
31 #include "modifier_ng/appearance/rs_mask_render_modifier.h"
32 #include "modifier_ng/appearance/rs_outline_render_modifier.h"
33 #include "modifier_ng/appearance/rs_particle_effect_render_modifier.h"
34 #include "modifier_ng/appearance/rs_pixel_stretch_render_modifier.h"
35 #include "modifier_ng/appearance/rs_point_light_render_modifier.h"
36 #include "modifier_ng/appearance/rs_shadow_render_modifier.h"
37 #include "modifier_ng/appearance/rs_use_effect_render_modifier.h"
38 #include "modifier_ng/appearance/rs_visibility_render_modifier.h"
39 #include "modifier_ng/background/rs_background_color_render_modifier.h"
40 #include "modifier_ng/background/rs_background_image_render_modifier.h"
41 #include "modifier_ng/background/rs_background_ng_shader_render_modifier.h"
42 #include "modifier_ng/background/rs_background_shader_render_modifier.h"
43 #include "modifier_ng/foreground/rs_env_foreground_color_render_modifier.h"
44 #include "modifier_ng/foreground/rs_foreground_color_render_modifier.h"
45 #include "modifier_ng/foreground/rs_foreground_shader_render_modifier.h"
46 #include "modifier_ng/geometry/rs_bounds_clip_render_modifier.h"
47 #include "modifier_ng/geometry/rs_bounds_render_modifier.h"
48 #include "modifier_ng/geometry/rs_frame_clip_render_modifier.h"
49 #include "modifier_ng/geometry/rs_frame_render_modifier.h"
50 #include "modifier_ng/geometry/rs_transform_render_modifier.h"
51 #include "pipeline/rs_render_node.h"
52 #include "platform/common/rs_log.h"
53 #include "property/rs_properties_painter.h"
54
55 namespace OHOS::Rosen::ModifierNG {
56 // RSRenderModifier ==========================================================================
57 const RSRenderModifier::LegacyPropertyApplierMap RSRenderModifier::emptyLegacyPropertyApplierMap_;
58
59 static const std::unordered_map<RSModifierType, RSRenderModifier::ResetFunc> g_resetFuncLUT_ = {
60 { RSModifierType::TRANSFORM, RSTransformRenderModifier::ResetProperties },
61 { RSModifierType::ALPHA, RSAlphaRenderModifier::ResetProperties },
62 { RSModifierType::FOREGROUND_COLOR, RSForegroundColorRenderModifier::ResetProperties },
63 { RSModifierType::BACKGROUND_COLOR, RSBackgroundColorRenderModifier::ResetProperties },
64 { RSModifierType::BACKGROUND_SHADER, RSBackgroundShaderRenderModifier::ResetProperties },
65 { RSModifierType::BACKGROUND_IMAGE, RSBackgroundImageRenderModifier::ResetProperties },
66 { RSModifierType::BORDER, RSBorderRenderModifier::ResetProperties },
67 { RSModifierType::OUTLINE, RSOutlineRenderModifier::ResetProperties },
68 { RSModifierType::CLIP_TO_BOUNDS, RSBoundsClipRenderModifier::ResetProperties },
69 { RSModifierType::CLIP_TO_FRAME, RSFrameClipRenderModifier::ResetProperties },
70 { RSModifierType::VISIBILITY, RSVisibilityRenderModifier::ResetProperties },
71 { RSModifierType::DYNAMIC_LIGHT_UP, RSDynamicLightUpRenderModifier::ResetProperties },
72 { RSModifierType::SHADOW, RSShadowRenderModifier::ResetProperties },
73 { RSModifierType::MASK, RSMaskRenderModifier::ResetProperties },
74 { RSModifierType::PIXEL_STRETCH, RSPixelStretchRenderModifier::ResetProperties },
75 { RSModifierType::USE_EFFECT, RSUseEffectRenderModifier::ResetProperties },
76 { RSModifierType::BLENDER, RSBlendRenderModifier::ResetProperties },
77 { RSModifierType::POINT_LIGHT, RSPointLightRenderModifier::ResetProperties },
78 { RSModifierType::PARTICLE_EFFECT, RSParticleEffectRenderModifier::ResetProperties },
79 { RSModifierType::COMPOSITING_FILTER, RSCompositingFilterRenderModifier::ResetProperties },
80 { RSModifierType::BACKGROUND_FILTER, RSBackgroundFilterRenderModifier::ResetProperties },
81 { RSModifierType::FOREGROUND_FILTER, RSForegroundFilterRenderModifier::ResetProperties },
82 { RSModifierType::BACKGROUND_NG_SHADER, RSBackgroundNGShaderRenderModifier::ResetProperties },
83 { RSModifierType::FOREGROUND_SHADER, RSForegroundShaderRenderModifier::ResetProperties },
84 };
85
86 std::array<RSRenderModifier::Constructor, MODIFIER_TYPE_COUNT> RSRenderModifier::ConstructorLUT_ = {
87 nullptr, // INVALID
__anonc72f8f170102null88 [] { return std::make_shared<RSBoundsRenderModifier>(); }, // BOUNDS
__anonc72f8f170202null89 [] { return std::make_shared<RSFrameRenderModifier>(); }, // FRAME
__anonc72f8f170302null90 [] { return std::make_shared<RSTransformRenderModifier>(); }, // TRANSFORM
__anonc72f8f170402null91 [] { return std::make_shared<RSAlphaRenderModifier>(); }, // ALPHA
__anonc72f8f170502null92 [] { return std::make_shared<RSForegroundColorRenderModifier>(); }, // FOREGROUND_COLOR
__anonc72f8f170602null93 [] { return std::make_shared<RSBackgroundColorRenderModifier>(); }, // BACKGROUND_COLOR
__anonc72f8f170702null94 [] { return std::make_shared<RSBackgroundShaderRenderModifier>(); }, // BACKGROUND_SHADER
__anonc72f8f170802null95 [] { return std::make_shared<RSBackgroundImageRenderModifier>(); }, // BACKGROUND_IMAGE
__anonc72f8f170902null96 [] { return std::make_shared<RSBorderRenderModifier>(); }, // BORDER
__anonc72f8f170a02null97 [] { return std::make_shared<RSOutlineRenderModifier>(); }, // OUTLINE
__anonc72f8f170b02null98 [] { return std::make_shared<RSBoundsClipRenderModifier>(); }, // CLIP_TO_BOUNDS
__anonc72f8f170c02null99 [] { return std::make_shared<RSFrameClipRenderModifier>(); }, // CLIP_TO_FRAME
__anonc72f8f170d02null100 [] { return std::make_shared<RSVisibilityRenderModifier>(); }, // VISIBILITY
__anonc72f8f170e02null101 [] { return std::make_shared<RSDynamicLightUpRenderModifier>(); }, // DYNAMIC_LIGHT_UP
__anonc72f8f170f02null102 [] { return std::make_shared<RSShadowRenderModifier>(); }, // SHADOW
__anonc72f8f171002null103 [] { return std::make_shared<RSMaskRenderModifier>(); }, // MASK
__anonc72f8f171102null104 [] { return std::make_shared<RSPixelStretchRenderModifier>(); }, // PIXEL_STRETCH
__anonc72f8f171202null105 [] { return std::make_shared<RSUseEffectRenderModifier>(); }, // USE_EFFECT
__anonc72f8f171302null106 [] { return std::make_shared<RSBlendRenderModifier>(); }, // BLENDER
__anonc72f8f171402null107 [] { return std::make_shared<RSPointLightRenderModifier>(); }, // POINT_LIGHT
__anonc72f8f171502null108 [] { return std::make_shared<RSParticleEffectRenderModifier>(); }, // PARTICLE_EFFECT
__anonc72f8f171602null109 [] { return std::make_shared<RSCompositingFilterRenderModifier>(); }, // COMPOSITING_FILTER
__anonc72f8f171702null110 [] { return std::make_shared<RSBackgroundFilterRenderModifier>(); }, // BACKGROUND_FILTER
__anonc72f8f171802null111 [] { return std::make_shared<RSForegroundFilterRenderModifier>(); }, // FOREGROUND_FILTER
__anonc72f8f171902null112 [] { return std::make_shared<RSCustomRenderModifier<RSModifierType::TRANSITION_STYLE>>(); }, // TRANSITION_STYLE
__anonc72f8f171a02null113 [] { return std::make_shared<RSCustomRenderModifier<RSModifierType::BACKGROUND_STYLE>>(); }, // BACKGROUND_STYLE
__anonc72f8f171b02null114 [] { return std::make_shared<RSCustomRenderModifier<RSModifierType::CONTENT_STYLE>>(); }, // CONTENT_STYLE
__anonc72f8f171c02null115 [] { return std::make_shared<RSCustomRenderModifier<RSModifierType::FOREGROUND_STYLE>>(); }, // FOREGROUND_STYLE
__anonc72f8f171d02null116 [] { return std::make_shared<RSCustomRenderModifier<RSModifierType::OVERLAY_STYLE>>(); }, // OVERLAY_STYLE
117 nullptr, // NODE_MODIFIER
__anonc72f8f171e02null118 [] { return std::make_shared<RSEnvForegroundColorRenderModifier>(); }, // ENV_FOREGROUND_COLOR
__anonc72f8f171f02null119 [] { return std::make_shared<RSHDRBrightnessRenderModifier>(); }, // HDR_BRIGHTNESS
__anonc72f8f172002null120 [] { return std::make_shared<RSBehindWindowFilterRenderModifier>(); }, // BEHIND_WINDOW_FILTER
__anonc72f8f172102null121 [] { return std::make_shared<RSBackgroundNGShaderRenderModifier>(); }, // BACKGROUND_NG_SHADER
__anonc72f8f172202null122 [] { return std::make_shared<RSForegroundShaderRenderModifier>(); }, // FOREGROUND_SHADER
123 nullptr, // CHILDREN
124 };
125
GetResetFuncMap()126 const std::unordered_map<RSModifierType, RSRenderModifier::ResetFunc>& RSRenderModifier::GetResetFuncMap()
127 {
128 return g_resetFuncLUT_;
129 }
130
AttachProperty(RSPropertyType type,const std::shared_ptr<RSRenderPropertyBase> & property)131 void RSRenderModifier::AttachProperty(RSPropertyType type, const std::shared_ptr<RSRenderPropertyBase>& property)
132 {
133 auto [it, isInserted] = properties_.try_emplace(type, property);
134 if (!isInserted) {
135 return;
136 }
137 if (auto node = target_.lock()) {
138 property->Attach(*node, weak_from_this());
139 property->UpdatePropertyUnitNG(type);
140 node->SetDirty();
141 node->AddDirtyType(GetType());
142 }
143 dirty_ = true;
144 }
145
DetachProperty(RSPropertyType type)146 void RSRenderModifier::DetachProperty(RSPropertyType type)
147 {
148 auto it = properties_.find(type);
149 if (it == properties_.end()) {
150 return;
151 }
152 if (auto node = target_.lock()) {
153 if (it->second) {
154 it->second->Detach();
155 }
156 node->SetDirty();
157 node->AddDirtyType(GetType());
158 }
159 properties_.erase(it);
160 dirty_ = true;
161 }
162
ApplyLegacyProperty(RSProperties & properties)163 void RSRenderModifier::ApplyLegacyProperty(RSProperties& properties)
164 {
165 const auto& map = GetLegacyPropertyApplierMap();
166 for (auto& [type, property] : properties_) {
167 auto it = map.find(type);
168 if (it == map.end()) {
169 RS_LOGD("apply legacy property failed, type: %{public}d", static_cast<int>(type));
170 continue;
171 }
172 if (it->second != nullptr) {
173 it->second(properties, *property);
174 }
175 }
176 dirty_ = false;
177 }
178
IsAttached() const179 bool RSRenderModifier::IsAttached() const
180 {
181 return !target_.expired();
182 }
183
OnAttachModifier(RSRenderNode & node)184 void RSRenderModifier::OnAttachModifier(RSRenderNode& node)
185 {
186 node.SetDirty();
187 node.AddDirtyType(GetType());
188 target_ = node.weak_from_this();
189 for (auto& [type, property] : properties_) {
190 property->Attach(node, weak_from_this());
191 property->UpdatePropertyUnitNG(type);
192 }
193 dirty_ = true;
194 }
195
OnDetachModifier()196 void RSRenderModifier::OnDetachModifier()
197 {
198 auto node = target_.lock();
199 target_.reset();
200 if (node == nullptr) {
201 return;
202 }
203 for (auto& [type, property] : properties_) {
204 property->Detach();
205 }
206 node->SetDirty();
207 node->AddDirtyType(GetType());
208 dirty_ = true;
209 }
210
SetDirty()211 void RSRenderModifier::SetDirty()
212 {
213 dirty_ = true;
214 if (auto node = target_.lock()) {
215 node->SetDirty();
216 node->AddDirtyType(GetType());
217 OnSetDirty();
218 }
219 }
220
OnSetDirty()221 void RSRenderModifier::OnSetDirty()
222 {
223 if (auto node = target_.lock()) {
224 node->MarkNonGeometryChanged();
225 }
226 }
227
Marshalling(Parcel & parcel) const228 bool RSRenderModifier::Marshalling(Parcel& parcel) const
229 {
230 auto ret = RSMarshallingHelper::Marshalling(parcel, GetType());
231 if (ret) {
232 ret = RSMarshallingHelper::Marshalling(parcel, id_);
233 }
234 if (ret) {
235 ret = RSMarshallingHelper::Marshalling(parcel, properties_);
236 }
237 return ret;
238 }
239
Unmarshalling(Parcel & parcel)240 std::shared_ptr<RSRenderModifier> RSRenderModifier::Unmarshalling(Parcel& parcel)
241 {
242 RSModifierType type = RSModifierType::MAX;
243 if (!RSMarshallingHelper::Unmarshalling(parcel, type)) {
244 return nullptr;
245 }
246 if (type >= RSModifierType::MAX) {
247 RS_LOGE("%{public}s: type[%{public}u] out of limit.", __func__, static_cast<uint16_t>(type));
248 return nullptr;
249 }
250 auto constructor = ConstructorLUT_[static_cast<uint16_t>(type)];
251 if (constructor == nullptr) {
252 return nullptr;
253 }
254 auto ret = constructor();
255 if (!RSMarshallingHelper::UnmarshallingPidPlusId(parcel, ret->id_) ||
256 !RSMarshallingHelper::Unmarshalling(parcel, ret->properties_)) {
257 return nullptr;
258 }
259 for (auto& [type, property] : ret->properties_) {
260 // Attach property to RSRenderModifier
261 ret->AttachProperty(type, property);
262 }
263 return ret;
264 }
265
266 // only use in dump without consideration of time performance
FindPropertyType(const std::shared_ptr<RSRenderPropertyBase> target) const267 RSPropertyType RSRenderModifier::FindPropertyType(const std::shared_ptr<RSRenderPropertyBase> target) const
268 {
269 for (auto& [type, property] : properties_) {
270 if (property == target) {
271 return type;
272 }
273 }
274 return RSPropertyType::INVALID;
275 }
276
277 // RSCustomRenderModifier ===========================================================================
278 template<RSModifierType T>
Apply(RSPaintFilterCanvas * canvas,RSProperties & properties)279 void RSCustomRenderModifier<T>::Apply(RSPaintFilterCanvas* canvas, RSProperties& properties)
280 {
281 auto propertyType = ModifierTypeConvertor::GetPropertyType(GetType());
282 if (HasProperty(propertyType) && canvas) {
283 auto cmds = Getter<Drawing::DrawCmdListPtr>(propertyType, nullptr);
284 RSPropertiesPainter::DrawFrame(properties, *canvas, cmds);
285 }
286 }
287
288 template<RSModifierType T>
OnSetDirty()289 void RSCustomRenderModifier<T>::OnSetDirty()
290 {
291 if (auto node = target_.lock()) {
292 node->MarkNonGeometryChanged();
293 node->SetContentDirty();
294 }
295 }
296
297 template class RSCustomRenderModifier<RSModifierType::TRANSITION_STYLE>;
298 template class RSCustomRenderModifier<RSModifierType::BACKGROUND_STYLE>;
299 template class RSCustomRenderModifier<RSModifierType::CONTENT_STYLE>;
300 template class RSCustomRenderModifier<RSModifierType::FOREGROUND_STYLE>;
301 template class RSCustomRenderModifier<RSModifierType::OVERLAY_STYLE>;
302 } // namespace OHOS::Rosen::ModifierNG
303