• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_modifier_ng.h"
17 
18 #include "sandbox_utils.h"
19 
20 #include "command/rs_node_command.h"
21 #include "modifier/rs_property.h"
22 #include "modifier_ng/rs_render_modifier_ng.h"
23 #include "platform/common/rs_log.h"
24 #include "ui/rs_node.h"
25 
26 namespace OHOS::Rosen::ModifierNG {
27 constexpr int PID_SHIFT = 32;
28 
29 static const std::unordered_map<RSPropertyType, ThresholdType> g_propertyTypeToThresholdTypeMap = {
30     { RSPropertyType::INVALID, ThresholdType::DEFAULT },
31     { RSPropertyType::BOUNDS, ThresholdType::LAYOUT },
32     { RSPropertyType::FRAME, ThresholdType::LAYOUT },
33     { RSPropertyType::POSITION_Z, ThresholdType::LAYOUT },
34     { RSPropertyType::POSITION_Z_APPLICABLE_CAMERA3D, ThresholdType::ZERO },
35     { RSPropertyType::PIVOT, ThresholdType::FINE },
36     { RSPropertyType::PIVOT_Z, ThresholdType::FINE },
37     { RSPropertyType::QUATERNION, ThresholdType::FINE },
38     { RSPropertyType::ROTATION, ThresholdType::FINE },
39     { RSPropertyType::ROTATION_X, ThresholdType::FINE },
40     { RSPropertyType::ROTATION_Y, ThresholdType::FINE },
41     { RSPropertyType::CAMERA_DISTANCE, ThresholdType::COARSE },
42     { RSPropertyType::SCALE, ThresholdType::FINE },
43     { RSPropertyType::SCALE_Z, ThresholdType::FINE },
44     { RSPropertyType::SKEW, ThresholdType::FINE },
45     { RSPropertyType::PERSP, ThresholdType::FINE },
46     { RSPropertyType::TRANSLATE, ThresholdType::LAYOUT },
47     { RSPropertyType::TRANSLATE_Z, ThresholdType::LAYOUT },
48     { RSPropertyType::SUBLAYER_TRANSFORM, ThresholdType::DEFAULT },
49     { RSPropertyType::CORNER_RADIUS, ThresholdType::MEDIUM },
50     { RSPropertyType::ALPHA, ThresholdType::COARSE },
51     { RSPropertyType::ALPHA_OFFSCREEN, ThresholdType::ZERO },
52     { RSPropertyType::FOREGROUND_COLOR, ThresholdType::COLOR },
53     { RSPropertyType::BACKGROUND_COLOR, ThresholdType::COLOR },
54     { RSPropertyType::BACKGROUND_SHADER, ThresholdType::ZERO },
55     { RSPropertyType::BACKGROUND_SHADER_PROGRESS, ThresholdType::FINE },
56     { RSPropertyType::BG_IMAGE, ThresholdType::ZERO },
57     { RSPropertyType::BG_IMAGE_INNER_RECT, ThresholdType::LAYOUT },
58     { RSPropertyType::BG_IMAGE_WIDTH, ThresholdType::LAYOUT },
59     { RSPropertyType::BG_IMAGE_HEIGHT, ThresholdType::LAYOUT },
60     { RSPropertyType::BG_IMAGE_POSITION_X, ThresholdType::LAYOUT },
61     { RSPropertyType::BG_IMAGE_POSITION_Y, ThresholdType::LAYOUT },
62     { RSPropertyType::BG_IMAGE_RECT, ThresholdType::DEFAULT },
63     { RSPropertyType::BORDER_COLOR, ThresholdType::COLOR },
64     { RSPropertyType::BORDER_WIDTH, ThresholdType::LAYOUT },
65     { RSPropertyType::BORDER_STYLE, ThresholdType::ZERO },
66     { RSPropertyType::BORDER_DASH_WIDTH, ThresholdType::ZERO },
67     { RSPropertyType::BORDER_DASH_GAP, ThresholdType::ZERO },
68     { RSPropertyType::BACKGROUND_FILTER, ThresholdType::DEFAULT },
69     { RSPropertyType::LINEAR_GRADIENT_BLUR_PARA, ThresholdType::ZERO },
70     { RSPropertyType::DYNAMIC_LIGHT_UP_RATE, ThresholdType::COARSE },
71     { RSPropertyType::DYNAMIC_LIGHT_UP_DEGREE, ThresholdType::COARSE },
72     { RSPropertyType::FG_BRIGHTNESS_RATES, ThresholdType::COARSE },
73     { RSPropertyType::FG_BRIGHTNESS_SATURATION, ThresholdType::COARSE },
74     { RSPropertyType::FG_BRIGHTNESS_POSCOEFF, ThresholdType::COARSE },
75     { RSPropertyType::FG_BRIGHTNESS_NEGCOEFF, ThresholdType::COARSE },
76     { RSPropertyType::FG_BRIGHTNESS_FRACTION, ThresholdType::COARSE },
77     { RSPropertyType::FG_BRIGHTNESS_HDR, ThresholdType::ZERO },
78     { RSPropertyType::BG_BRIGHTNESS_RATES, ThresholdType::COARSE },
79     { RSPropertyType::BG_BRIGHTNESS_SATURATION, ThresholdType::COARSE },
80     { RSPropertyType::BG_BRIGHTNESS_POSCOEFF, ThresholdType::COARSE },
81     { RSPropertyType::BG_BRIGHTNESS_NEGCOEFF, ThresholdType::COARSE },
82     { RSPropertyType::BG_BRIGHTNESS_FRACTION, ThresholdType::COARSE },
83     { RSPropertyType::FRAME_GRAVITY, ThresholdType::ZERO },
84     { RSPropertyType::CLIP_RRECT, ThresholdType::MEDIUM },
85     { RSPropertyType::CLIP_BOUNDS, ThresholdType::ZERO },
86     { RSPropertyType::CLIP_TO_BOUNDS, ThresholdType::ZERO },
87     { RSPropertyType::CLIP_TO_FRAME, ThresholdType::ZERO },
88     { RSPropertyType::VISIBLE, ThresholdType::ZERO },
89     { RSPropertyType::SHADOW_COLOR, ThresholdType::COLOR },
90     { RSPropertyType::SHADOW_OFFSET_X, ThresholdType::LAYOUT },
91     { RSPropertyType::SHADOW_OFFSET_Y, ThresholdType::LAYOUT },
92     { RSPropertyType::SHADOW_ALPHA, ThresholdType::COARSE },
93     { RSPropertyType::SHADOW_ELEVATION, ThresholdType::COARSE },
94     { RSPropertyType::SHADOW_RADIUS, ThresholdType::LAYOUT },
95     { RSPropertyType::SHADOW_PATH, ThresholdType::ZERO },
96     { RSPropertyType::SHADOW_MASK, ThresholdType::ZERO },
97     { RSPropertyType::SHADOW_COLOR_STRATEGY, ThresholdType::ZERO },
98     { RSPropertyType::MASK, ThresholdType::ZERO },
99     { RSPropertyType::SPHERIZE, ThresholdType::MEDIUM },
100     { RSPropertyType::LIGHT_UP_EFFECT_DEGREE, ThresholdType::COARSE },
101     { RSPropertyType::PIXEL_STRETCH_SIZE, ThresholdType::COARSE },
102     { RSPropertyType::PIXEL_STRETCH_PERCENT, ThresholdType::FINE },
103     { RSPropertyType::PIXEL_STRETCH_TILE_MODE, ThresholdType::ZERO },
104     { RSPropertyType::USE_EFFECT, ThresholdType::ZERO },
105     { RSPropertyType::USE_EFFECT_TYPE, ThresholdType::ZERO },
106     { RSPropertyType::COLOR_BLEND_MODE, ThresholdType::ZERO },
107     { RSPropertyType::COLOR_BLEND_APPLY_TYPE, ThresholdType::ZERO },
108     { RSPropertyType::SANDBOX, ThresholdType::LAYOUT },
109     { RSPropertyType::GRAY_SCALE, ThresholdType::COARSE },
110     { RSPropertyType::BRIGHTNESS, ThresholdType::COARSE },
111     { RSPropertyType::CONTRAST, ThresholdType::COARSE },
112     { RSPropertyType::SATURATE, ThresholdType::COARSE },
113     { RSPropertyType::SEPIA, ThresholdType::COARSE },
114     { RSPropertyType::INVERT, ThresholdType::COARSE },
115     { RSPropertyType::AIINVERT, ThresholdType::COARSE },
116     { RSPropertyType::SYSTEMBAREFFECT, ThresholdType::ZERO },
117     { RSPropertyType::WATER_RIPPLE_PROGRESS, ThresholdType::COARSE },
118     { RSPropertyType::WATER_RIPPLE_PARAMS, ThresholdType::ZERO },
119     { RSPropertyType::HUE_ROTATE, ThresholdType::COARSE },
120     { RSPropertyType::COLOR_BLEND, ThresholdType::COLOR },
121     { RSPropertyType::PARTICLE, ThresholdType::ZERO },
122     { RSPropertyType::SHADOW_IS_FILLED, ThresholdType::ZERO },
123     { RSPropertyType::OUTLINE_COLOR, ThresholdType::COLOR },
124     { RSPropertyType::OUTLINE_WIDTH, ThresholdType::LAYOUT },
125     { RSPropertyType::OUTLINE_STYLE, ThresholdType::ZERO },
126     { RSPropertyType::OUTLINE_DASH_WIDTH, ThresholdType::ZERO },
127     { RSPropertyType::OUTLINE_DASH_GAP, ThresholdType::ZERO },
128     { RSPropertyType::OUTLINE_RADIUS, ThresholdType::MEDIUM },
129     { RSPropertyType::GREY_COEF, ThresholdType::COARSE },
130     { RSPropertyType::LIGHT_INTENSITY, ThresholdType::COARSE },
131     { RSPropertyType::LIGHT_COLOR, ThresholdType::COARSE },
132     { RSPropertyType::LIGHT_POSITION, ThresholdType::LAYOUT },
133     { RSPropertyType::ILLUMINATED_BORDER_WIDTH, ThresholdType::COARSE },
134     { RSPropertyType::ILLUMINATED_TYPE, ThresholdType::ZERO },
135     { RSPropertyType::BLOOM, ThresholdType::COARSE },
136     { RSPropertyType::FOREGROUND_EFFECT_RADIUS, ThresholdType::COARSE },
137     { RSPropertyType::USE_SHADOW_BATCHING, ThresholdType::ZERO },
138     { RSPropertyType::MOTION_BLUR_PARA, ThresholdType::ZERO },
139     { RSPropertyType::PARTICLE_EMITTER_UPDATER, ThresholdType::ZERO },
140     { RSPropertyType::PARTICLE_NOISE_FIELD, ThresholdType::ZERO },
141     { RSPropertyType::FLY_OUT_DEGREE, ThresholdType::COARSE },
142     { RSPropertyType::FLY_OUT_PARAMS, ThresholdType::ZERO },
143     { RSPropertyType::DISTORTION_K, ThresholdType::COARSE },
144     { RSPropertyType::DYNAMIC_DIM_DEGREE, ThresholdType::COARSE },
145     { RSPropertyType::MAGNIFIER_PARA, ThresholdType::ZERO },
146     { RSPropertyType::BACKGROUND_BLUR_RADIUS, ThresholdType::COARSE },
147     { RSPropertyType::BACKGROUND_BLUR_SATURATION, ThresholdType::COARSE },
148     { RSPropertyType::BACKGROUND_BLUR_BRIGHTNESS, ThresholdType::COARSE },
149     { RSPropertyType::BACKGROUND_BLUR_MASK_COLOR, ThresholdType::COLOR },
150     { RSPropertyType::BACKGROUND_BLUR_COLOR_MODE, ThresholdType::ZERO },
151     { RSPropertyType::BACKGROUND_BLUR_RADIUS_X, ThresholdType::COARSE },
152     { RSPropertyType::BACKGROUND_BLUR_RADIUS_Y, ThresholdType::COARSE },
153     { RSPropertyType::BG_BLUR_DISABLE_SYSTEM_ADAPTATION, ThresholdType::ZERO },
154     { RSPropertyType::ALWAYS_SNAPSHOT, ThresholdType::ZERO },
155     { RSPropertyType::FOREGROUND_BLUR_RADIUS, ThresholdType::COARSE },
156     { RSPropertyType::FOREGROUND_BLUR_SATURATION, ThresholdType::COARSE },
157     { RSPropertyType::FOREGROUND_BLUR_BRIGHTNESS, ThresholdType::COARSE },
158     { RSPropertyType::FOREGROUND_BLUR_MASK_COLOR, ThresholdType::COLOR },
159     { RSPropertyType::FOREGROUND_BLUR_COLOR_MODE, ThresholdType::ZERO },
160     { RSPropertyType::FOREGROUND_BLUR_RADIUS_X, ThresholdType::COARSE },
161     { RSPropertyType::FOREGROUND_BLUR_RADIUS_Y, ThresholdType::COARSE },
162     { RSPropertyType::FG_BLUR_DISABLE_SYSTEM_ADAPTATION, ThresholdType::ZERO },
163     { RSPropertyType::ATTRACTION_FRACTION, ThresholdType::MEDIUM },
164     { RSPropertyType::ATTRACTION_DSTPOINT, ThresholdType::MEDIUM },
165     { RSPropertyType::CUSTOM, ThresholdType::DEFAULT },
166     { RSPropertyType::TRANSITION_STYLE, ThresholdType::DEFAULT },
167     { RSPropertyType::BACKGROUND_STYLE, ThresholdType::DEFAULT },
168     { RSPropertyType::CONTENT_STYLE, ThresholdType::DEFAULT },
169     { RSPropertyType::FOREGROUND_STYLE, ThresholdType::DEFAULT },
170     { RSPropertyType::OVERLAY_STYLE, ThresholdType::DEFAULT },
171     { RSPropertyType::NODE_MODIFIER, ThresholdType::DEFAULT },
172     { RSPropertyType::ENV_FOREGROUND_COLOR, ThresholdType::DEFAULT },
173     { RSPropertyType::ENV_FOREGROUND_COLOR_STRATEGY, ThresholdType::DEFAULT },
174     { RSPropertyType::CUSTOM_CLIP_TO_FRAME, ThresholdType::DEFAULT },
175     { RSPropertyType::HDR_BRIGHTNESS, ThresholdType::DEFAULT },
176     { RSPropertyType::HDR_UI_BRIGHTNESS, ThresholdType::COARSE },
177     { RSPropertyType::HDR_BRIGHTNESS_FACTOR, ThresholdType::COARSE },
178     { RSPropertyType::BEHIND_WINDOW_FILTER_RADIUS, ThresholdType::COARSE },
179     { RSPropertyType::BEHIND_WINDOW_FILTER_SATURATION, ThresholdType::COARSE },
180     { RSPropertyType::BEHIND_WINDOW_FILTER_BRIGHTNESS, ThresholdType::COARSE },
181     { RSPropertyType::BEHIND_WINDOW_FILTER_MASK_COLOR, ThresholdType::COARSE },
182     { RSPropertyType::SHADOW_BLENDER_PARAMS, ThresholdType::ZERO },
183     { RSPropertyType::CHILDREN, ThresholdType::DEFAULT }
184 };
185 
GenerateModifierId()186 ModifierId RSModifier::GenerateModifierId()
187 {
188     static pid_t pid_ = GetRealPid();
189     static std::atomic<uint32_t> currentId_ = 1;
190 
191     auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
192     if (currentId == UINT32_MAX) {
193         RS_LOGE("Modifier Id overflow");
194     }
195 
196     return ((ModifierId)pid_ << PID_SHIFT) | currentId;
197 }
198 
AttachProperty(const std::shared_ptr<RSPropertyBase> & property)199 void RSModifier::AttachProperty(const std::shared_ptr<RSPropertyBase>& property)
200 {
201     if (property == nullptr) {
202         RS_LOGE("Failed to attach property, property is null.");
203         return;
204     }
205     property->SetIsCustom(IsCustom());
206     property->AttachModifier(shared_from_this());
207     if (node_.expired()) {
208         return;
209     }
210     property->target_ = node_;
211     if (IsCustom()) {
212         property->MarkCustomModifierDirty();
213     }
214 }
215 
AttachProperty(RSPropertyType type,std::shared_ptr<RSPropertyBase> property)216 void RSModifier::AttachProperty(RSPropertyType type, std::shared_ptr<RSPropertyBase> property)
217 {
218     if (property == nullptr) {
219         RS_LOGE("Failed to attach property with type %{public}d, property is null!", static_cast<int32_t>(type));
220         return;
221     }
222 
223     property->SetPropertyTypeNG(type);
224     // replace existing property if any
225     properties_[type] = property;
226     SetPropertyThresholdType(type, property);
227 
228     auto node = node_.lock();
229     if (!node) {
230         // not attached yet
231         return;
232     }
233     auto shouldSetOption = node->motionPathOption_ != nullptr && property->IsPathAnimatable();
234     if (shouldSetOption) {
235         property->SetMotionPathOption(node->motionPathOption_);
236     }
237     property->Attach(*node, weak_from_this());
238     MarkNodeDirty();
239     std::shared_ptr<RSRenderPropertyBase> renderProperty = property->GetRenderProperty();
240     std::unique_ptr<RSCommand> command =
241         std::make_unique<RSModifierNGAttachProperty>(node->GetId(), id_, GetType(), type, renderProperty);
242     node->AddCommand(command, node->IsRenderServiceNode(), node->GetFollowType(), node->GetId());
243     if (node->NeedForcedSendToRemote()) {
244         std::unique_ptr<RSCommand> cmdForRemote =
245             std::make_unique<RSModifierNGAttachProperty>(node->GetId(), id_, GetType(), type, renderProperty);
246         node->AddCommand(cmdForRemote, true, node->GetFollowType(), node->GetId());
247     }
248 }
249 
DetachProperty(RSPropertyType type)250 void RSModifier::DetachProperty(RSPropertyType type)
251 {
252     auto it = properties_.find(type);
253     if (it == properties_.end()) {
254         return;
255     }
256     auto property = it->second;
257     properties_.erase(it);
258     // actually do the detach
259     property->Detach();
260     auto node = node_.lock();
261     if (!node) {
262         // not attached yet
263         return;
264     }
265     std::unique_ptr<RSCommand> command =
266         std::make_unique<RSModifierNGDetachProperty>(node->GetId(), id_, GetType(), type);
267     node->AddCommand(command, node->IsRenderServiceNode());
268 }
269 
SetPropertyThresholdType(RSPropertyType type,std::shared_ptr<RSPropertyBase> property)270 void RSModifier::SetPropertyThresholdType(RSPropertyType type, std::shared_ptr<RSPropertyBase> property)
271 {
272     auto it = g_propertyTypeToThresholdTypeMap.find(type);
273     if (it == g_propertyTypeToThresholdTypeMap.end()) {
274         RS_LOGE("RSPropertyType is not exist! type: %{public}d", static_cast<int32_t>(type));
275         return;
276     }
277     if (it->second != ThresholdType::DEFAULT) {
278         property->SetThresholdType(it->second);
279     }
280 }
281 
OnAttach(RSNode & node)282 void RSModifier::OnAttach(RSNode& node)
283 {
284     node_ = node.weak_from_this();
285     if (properties_.empty()) {
286         return;
287     }
288     auto weakPtr = weak_from_this();
289     for (auto& [_, property] : properties_) {
290         auto shouldSetOption = node.motionPathOption_ != nullptr && property->IsPathAnimatable();
291         if (shouldSetOption) {
292             property->SetMotionPathOption(node.motionPathOption_);
293         }
294         property->Attach(node, weakPtr);
295     }
296     MarkNodeDirty();
297 }
298 
OnDetach()299 void RSModifier::OnDetach()
300 {
301     node_.reset();
302     for (auto& [_, property] : properties_) {
303         property->Detach();
304     }
305     MarkNodeDirty();
306 }
307 
SetDirty(bool isDirty,const std::shared_ptr<RSModifierManager> & modifierManager)308 void RSModifier::SetDirty(bool isDirty, const std::shared_ptr<RSModifierManager>& modifierManager)
309 {
310     if (isDirty_ == isDirty) {
311         // not changed
312         return;
313     }
314     isDirty_ = isDirty;
315 
316     if (!isDirty_) {
317         // not dirty
318         return;
319     }
320 
321     if (modifierManager == nullptr) {
322         RS_LOGE("multi-instance, Modifier manager is null while mark modifier dirty Id: %{public}" PRIu64 "!", GetId());
323         return;
324     }
325     modifierManager->AddModifier(shared_from_this());
326 }
327 
CreateRenderModifier()328 std::shared_ptr<RSRenderModifier> RSModifier::CreateRenderModifier()
329 {
330     const auto& constructor = RSRenderModifier::ConstructorLUT_[static_cast<uint16_t>(GetType())];
331     if (constructor == nullptr) {
332         return nullptr;
333     }
334     auto renderModifier = constructor();
335     renderModifier->id_ = id_;
336     for (auto& [type, property] : properties_) {
337         if (property == nullptr) {
338             RS_LOGE("RSModifier::CreateRenderModifier property is null! type: %{public}d", static_cast<int32_t>(type));
339             continue;
340         }
341         renderModifier->properties_.emplace(type, property->GetRenderProperty());
342     }
343     // this function is only called before marshalling, no need to actually attach properties
344     return renderModifier;
345 }
346 } // namespace OHOS::Rosen::ModifierNG
347