1 /*
2 * Copyright (c) 2024 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 "foundation/graphic/graphic_2d/utils/log/rs_trace.h"
17 #include "rs_profiler.h"
18 #include "rs_profiler_json.h"
19 #include "rs_profiler_network.h"
20
21 #include "common/rs_obj_geometry.h"
22 #include "pipeline/rs_context.h"
23 #include "pipeline/rs_display_render_node.h"
24 #include "pipeline/rs_root_render_node.h"
25 #include "pipeline/rs_surface_handler.h"
26 #include "pipeline/rs_surface_render_node.h"
27
28 namespace OHOS::Rosen {
29
DumpNode(const RSRenderNode & node,JsonWriter & out)30 void RSProfiler::DumpNode(const RSRenderNode& node, JsonWriter& out)
31 {
32 out.PushObject();
33 DumpNodeBaseInfo(node, out);
34 DumpNodeProperties(node.GetRenderProperties(), out);
35 DumpNodeOptionalFlags(node, out);
36 DumpNodeDrawCmdModifiers(node, out);
37 DumpNodeAnimations(node.animationManager_, out);
38 DumpNodeChildrenListUpdate(node, out);
39
40 auto& children = out["children"];
41 children.PushArray();
42 if (node.GetSortedChildren()) {
43 for (auto& child : *node.GetSortedChildren()) {
44 if (child) {
45 DumpNode(*child, children);
46 }
47 }
48 }
49 children.PopArray();
50 out.PopObject();
51 }
52
DumpNodeBaseInfo(const RSRenderNode & node,JsonWriter & out)53 void RSProfiler::DumpNodeBaseInfo(const RSRenderNode& node, JsonWriter& out)
54 {
55 std::string type;
56 node.DumpNodeType(node.GetType(), type);
57 out["type"] = type;
58 out["id"] = node.GetId();
59 out["instanceRootNodeId"] = node.GetInstanceRootNodeId();
60 DumpNodeSubsurfaces(node, out);
61 auto sharedTrans = node.GetSharedTransitionParam();
62 if (sharedTrans) {
63 out["SharedTransitionParam"] =
64 std::to_string(sharedTrans->inNodeId_) + " -> " + std::to_string(sharedTrans->outNodeId_);
65 }
66 if (node.IsSuggestedDrawInGroup()) {
67 out["nodeGroup"] = static_cast<int>(node.nodeGroupType_);
68 }
69 if (node.GetUifirstRootNodeId() != INVALID_NODEID) {
70 out["uifirstRootNodeId"] = node.GetUifirstRootNodeId();
71 }
72 DumpNodeSubClassNode(node, out);
73 }
74
DumpNodeSubsurfaces(const RSRenderNode & node,JsonWriter & out)75 void RSProfiler::DumpNodeSubsurfaces(const RSRenderNode& node, JsonWriter& out)
76 {
77 if (auto surface = node.ReinterpretCastTo<RSSurfaceRenderNode>(); surface && surface->HasSubSurfaceNodes()) {
78 auto& subsurface = out["subsurface"];
79 subsurface.PushArray();
80 for (auto [id, _] : surface->GetChildSubSurfaceNodes()) {
81 subsurface.Append(id);
82 }
83 subsurface.PopArray();
84 }
85 }
86
DumpNodeSubClassNode(const RSRenderNode & node,JsonWriter & out)87 void RSProfiler::DumpNodeSubClassNode(const RSRenderNode& node, JsonWriter& out)
88 {
89 auto& subclass = out["subclass"];
90 subclass.PushObject();
91 if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
92 auto& surfaceNode = static_cast<const RSSurfaceRenderNode&>(node);
93 auto p = node.parent_.lock();
94 subclass["Parent"] = p ? p->GetId() : uint64_t(0);
95 subclass["Name"] = surfaceNode.GetName();
96 out["hasConsumer"] = surfaceNode.GetRSSurfaceHandler()->HasConsumer();
97 std::string contextAlpha = std::to_string(surfaceNode.contextAlpha_);
98 std::string propertyAlpha = std::to_string(surfaceNode.GetRenderProperties().GetAlpha());
99 subclass["Alpha"] = propertyAlpha + " (include ContextAlpha: " + contextAlpha + ")";
100 subclass["Visible"] = std::to_string(surfaceNode.GetRenderProperties().GetVisible()) + " " +
101 surfaceNode.GetVisibleRegion().GetRegionInfo();
102 subclass["Opaque"] = surfaceNode.GetOpaqueRegion().GetRegionInfo();
103 subclass["OcclusionBg"] = std::to_string((surfaceNode.GetAbilityBgAlpha()));
104 subclass["SecurityLayer"] = surfaceNode.GetSecurityLayer();
105 subclass["skipLayer"] = surfaceNode.GetSkipLayer();
106 subclass["snapshotSkipLayer"] = surfaceNode.GetSnapshotSkipLayer();
107 } else if (node.GetType() == RSRenderNodeType::ROOT_NODE) {
108 auto& rootNode = static_cast<const RSRootRenderNode&>(node);
109 subclass["Visible"] = rootNode.GetRenderProperties().GetVisible();
110 subclass["Size"] = { rootNode.GetRenderProperties().GetFrameWidth(),
111 rootNode.GetRenderProperties().GetFrameHeight() };
112 subclass["EnableRender"] = rootNode.GetEnableRender();
113 } else if (node.GetType() == RSRenderNodeType::DISPLAY_NODE) {
114 auto& displayNode = static_cast<const RSDisplayRenderNode&>(node);
115 subclass["skipLayer"] = displayNode.GetSecurityDisplay();
116 }
117 subclass.PopObject();
118 }
119
DumpNodeOptionalFlags(const RSRenderNode & node,JsonWriter & out)120 void RSProfiler::DumpNodeOptionalFlags(const RSRenderNode& node, JsonWriter& out)
121 {
122 if (node.GetBootAnimation()) {
123 out["GetBootAnimation"] = true;
124 }
125 if (node.isContainBootAnimation_) {
126 out["isContainBootAnimation_"] = true;
127 }
128 if (node.dirtyStatus_ != RSRenderNode::NodeDirty::CLEAN) {
129 out["isNodeDirty"] = static_cast<int>(node.dirtyStatus_);
130 }
131 if (node.GetRenderProperties().IsDirty()) {
132 out["isPropertyDirty"] = true;
133 }
134 if (node.isSubTreeDirty_) {
135 out["isSubTreeDirty"] = true;
136 }
137 if (node.IsPureContainer()) {
138 out["IsPureContainer"] = true;
139 }
140 }
141
DumpNodeDrawCmdModifiers(const RSRenderNode & node,JsonWriter & out)142 void RSProfiler::DumpNodeDrawCmdModifiers(const RSRenderNode& node, JsonWriter& out)
143 {
144 if (!node.renderContent_) {
145 return;
146 }
147
148 auto& modifiersJson = out["DrawCmdModifiers"];
149 modifiersJson.PushArray();
150 for (auto& [type, modifiers] : node.renderContent_->drawCmdModifiers_) {
151 modifiersJson.PushObject();
152 modifiersJson["type"] = static_cast<int>(type);
153 auto& modifierDesc = modifiersJson["modifiers"];
154 modifierDesc.PushArray();
155 for (const auto& modifier : modifiers) {
156 if (modifier) {
157 DumpNodeDrawCmdModifier(node, modifierDesc, static_cast<int>(type), *modifier);
158 }
159 }
160 modifiersJson.PopArray();
161 modifiersJson.PopObject();
162 }
163 modifiersJson.PopArray();
164 }
165
Hex(uint32_t value)166 static std::string Hex(uint32_t value)
167 {
168 std::stringstream sstream;
169 sstream << std::hex << value;
170 return sstream.str();
171 }
172
DumpNodeDrawCmdModifier(const RSRenderNode & node,JsonWriter & out,int type,RSRenderModifier & modifier)173 void RSProfiler::DumpNodeDrawCmdModifier(
174 const RSRenderNode& node, JsonWriter& out, int type, RSRenderModifier& modifier)
175 {
176 auto modType = static_cast<RSModifierType>(type);
177
178 if (modType < RSModifierType::ENV_FOREGROUND_COLOR) {
179 auto propertyPtr = std::static_pointer_cast<RSRenderProperty<Drawing::DrawCmdListPtr>>(modifier.GetProperty());
180 auto drawCmdListPtr = propertyPtr ? propertyPtr->Get() : nullptr;
181 auto propertyStr = drawCmdListPtr ? drawCmdListPtr->GetOpsWithDesc() : "";
182 size_t pos = 0;
183 size_t oldpos = 0;
184
185 out.PushObject();
186 auto& property = out["drawCmdList"];
187 property.PushArray();
188 while ((pos = propertyStr.find('\n', oldpos)) != std::string::npos) {
189 property.Append(propertyStr.substr(oldpos, pos - oldpos));
190 oldpos = pos + 1;
191 }
192 property.PopArray();
193 out.PopObject();
194 } else if (modType == RSModifierType::ENV_FOREGROUND_COLOR) {
195 auto propertyPtr = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(modifier.GetProperty());
196 if (propertyPtr) {
197 out.PushObject();
198 out["ENV_FOREGROUND_COLOR"] = "#" + Hex(propertyPtr->Get().AsRgbaInt()) + " (RGBA)";
199 out.PopObject();
200 }
201 } else if (modType == RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY) {
202 auto propertyPtr =
203 std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>(modifier.GetProperty());
204 if (propertyPtr) {
205 out.PushObject();
206 out["ENV_FOREGROUND_COLOR_STRATEGY"] = static_cast<int>(propertyPtr->Get());
207 out.PopObject();
208 }
209 } else if (modType == RSModifierType::GEOMETRYTRANS) {
210 auto propertyPtr = std::static_pointer_cast<RSRenderProperty<SkMatrix>>(modifier.GetProperty());
211 if (propertyPtr) {
212 std::string str;
213 propertyPtr->Get().dump(str, 0);
214 out.PushObject();
215 out["GEOMETRYTRANS"] = str;
216 out.PopObject();
217 }
218 } else if (modType == RSModifierType::CUSTOM_CLIP_TO_FRAME) {
219 auto propertyPtr = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(modifier.GetProperty());
220 if (propertyPtr) {
221 std::string str;
222 propertyPtr->Dump(str);
223 out.PushObject();
224 out["CUSTOM_CLIP_TO_FRAME"] = str;
225 out.PopObject();
226 }
227 }
228 }
229
DumpNodeProperties(const RSProperties & properties,JsonWriter & out)230 void RSProfiler::DumpNodeProperties(const RSProperties& properties, JsonWriter& out)
231 {
232 auto& json = out["Properties"];
233 json.PushObject();
234 json["Bounds"] = { properties.GetBoundsPositionX(), properties.GetBoundsPositionY(), properties.GetBoundsWidth(),
235 properties.GetBoundsHeight() };
236 json["Frame"] = { properties.GetFramePositionX(), properties.GetFramePositionY(), properties.GetFrameWidth(),
237 properties.GetFrameHeight() };
238
239 if (!properties.GetVisible()) {
240 json["IsVisible"] = false;
241 }
242 DumpNodePropertiesClip(properties, json);
243 DumpNodePropertiesTransform(properties, json);
244 DumpNodePropertiesDecoration(properties, json);
245 DumpNodePropertiesShadow(properties, json);
246 DumpNodePropertiesEffects(properties, json);
247 DumpNodePropertiesColor(properties, json);
248 json.PopObject();
249 }
250
DumpNodePropertiesClip(const RSProperties & properties,JsonWriter & out)251 void RSProfiler::DumpNodePropertiesClip(const RSProperties& properties, JsonWriter& out)
252 {
253 if (properties.clipToBounds_) {
254 out["ClipToBounds"] = true;
255 }
256 if (properties.clipToFrame_) {
257 out["ClipToFrame"] = true;
258 }
259 }
260
DumpNodePropertiesTransform(const RSProperties & properties,JsonWriter & out)261 void RSProfiler::DumpNodePropertiesTransform(const RSProperties& properties, JsonWriter& out)
262 {
263 if (!ROSEN_EQ(properties.GetPositionZ(), 0.f)) {
264 out["PositionZ"] = properties.GetPositionZ();
265 }
266 RSTransform defaultTransform;
267 Vector2f pivot = properties.GetPivot();
268 if ((!ROSEN_EQ(pivot[0], defaultTransform.pivotX_) || !ROSEN_EQ(pivot[1], defaultTransform.pivotY_))) {
269 out["Pivot"] = { pivot[0], pivot[1] };
270 }
271 if (!ROSEN_EQ(properties.GetRotation(), defaultTransform.rotation_)) {
272 out["Rotation"] = properties.GetRotation();
273 }
274 if (!ROSEN_EQ(properties.GetRotationX(), defaultTransform.rotationX_)) {
275 out["RotationX"] = properties.GetRotationX();
276 }
277 if (!ROSEN_EQ(properties.GetRotationY(), defaultTransform.rotationY_)) {
278 out["RotationY"] = properties.GetRotationY();
279 }
280 if (!ROSEN_EQ(properties.GetTranslateX(), defaultTransform.translateX_)) {
281 out["TranslateX"] = properties.GetTranslateX();
282 }
283 if (!ROSEN_EQ(properties.GetTranslateY(), defaultTransform.translateY_)) {
284 out["TranslateY"] = properties.GetTranslateY();
285 }
286 if (!ROSEN_EQ(properties.GetTranslateZ(), defaultTransform.translateZ_)) {
287 out["TranslateZ"] = properties.GetTranslateZ();
288 }
289 if (!ROSEN_EQ(properties.GetScaleX(), defaultTransform.scaleX_)) {
290 out["ScaleX"] = properties.GetScaleX();
291 }
292 if (!ROSEN_EQ(properties.GetScaleY(), defaultTransform.scaleY_)) {
293 out["ScaleY"] = properties.GetScaleY();
294 }
295 }
296
DumpNodePropertiesDecoration(const RSProperties & properties,JsonWriter & out)297 void RSProfiler::DumpNodePropertiesDecoration(const RSProperties& properties, JsonWriter& out)
298 {
299 if (!properties.GetCornerRadius().IsZero()) {
300 out["CornerRadius"] = { properties.GetCornerRadius().x_, properties.GetCornerRadius().y_,
301 properties.GetCornerRadius().z_, properties.GetCornerRadius().w_ };
302 }
303 if (properties.pixelStretch_.has_value()) {
304 auto& pixelStretch = out["PixelStretch"];
305 pixelStretch.PushObject();
306 pixelStretch["left"] = properties.pixelStretch_->z_;
307 pixelStretch["top"] = properties.pixelStretch_->y_;
308 pixelStretch["right"] = properties.pixelStretch_->z_;
309 pixelStretch["bottom"] = properties.pixelStretch_->w_;
310 pixelStretch.PopObject();
311 }
312 if (!ROSEN_EQ(properties.GetAlpha(), 1.f)) {
313 out["Alpha"] = properties.GetAlpha();
314 }
315 if (!ROSEN_EQ(properties.GetSpherize(), 0.f)) {
316 out["Spherize"] = properties.GetSpherize();
317 }
318
319 if (!ROSEN_EQ(properties.GetAttractionFraction(), 0.f)) {
320 out["AttractionEffect"] = properties.GetAttractionFraction();
321 }
322
323 if (!ROSEN_EQ(properties.GetForegroundColor(), RgbPalette::Transparent())) {
324 out["ForegroundColor"] = "#" + Hex(properties.GetForegroundColor().AsArgbInt()) + " (ARGB)";
325 }
326 if (!ROSEN_EQ(properties.GetBackgroundColor(), RgbPalette::Transparent())) {
327 out["BackgroundColor"] = "#" + Hex(properties.GetBackgroundColor().AsArgbInt()) + " (ARGB)";
328 }
329 Decoration defaultDecoration;
330 if ((!ROSEN_EQ(properties.GetBgImagePositionX(), defaultDecoration.bgImageRect_.left_) ||
331 !ROSEN_EQ(properties.GetBgImagePositionY(), defaultDecoration.bgImageRect_.top_) ||
332 !ROSEN_EQ(properties.GetBgImageWidth(), defaultDecoration.bgImageRect_.width_) ||
333 !ROSEN_EQ(properties.GetBgImageHeight(), defaultDecoration.bgImageRect_.height_))) {
334 out["BgImage"] = { properties.GetBgImagePositionX(), properties.GetBgImagePositionY(),
335 properties.GetBgImageWidth(), properties.GetBgImageHeight() };
336 }
337 }
338
DumpNodePropertiesShadow(const RSProperties & properties,JsonWriter & out)339 void RSProfiler::DumpNodePropertiesShadow(const RSProperties& properties, JsonWriter& out)
340 {
341 if (!ROSEN_EQ(properties.GetShadowColor(), Color(DEFAULT_SPOT_COLOR))) {
342 out["ShadowColor"] = "#" + Hex(properties.GetShadowColor().AsArgbInt()) + " (ARGB)";
343 }
344 if (!ROSEN_EQ(properties.GetShadowOffsetX(), DEFAULT_SHADOW_OFFSET_X)) {
345 out["ShadowOffsetX"] = properties.GetShadowOffsetX();
346 }
347 if (!ROSEN_EQ(properties.GetShadowOffsetY(), DEFAULT_SHADOW_OFFSET_Y)) {
348 out["ShadowOffsetY"] = properties.GetShadowOffsetY();
349 }
350 if (!ROSEN_EQ(properties.GetShadowAlpha(), 0.f)) {
351 out["ShadowAlpha"] = properties.GetShadowAlpha();
352 }
353 if (!ROSEN_EQ(properties.GetShadowElevation(), 0.f)) {
354 out["ShadowElevation"] = properties.GetShadowElevation();
355 }
356 if (!ROSEN_EQ(properties.GetShadowRadius(), 0.f)) {
357 out["ShadowRadius"] = properties.GetShadowRadius();
358 }
359 if (!ROSEN_EQ(properties.GetShadowIsFilled(), false)) {
360 out["ShadowIsFilled"] = properties.GetShadowIsFilled();
361 }
362 }
363
DumpNodePropertiesEffects(const RSProperties & properties,JsonWriter & out)364 void RSProfiler::DumpNodePropertiesEffects(const RSProperties& properties, JsonWriter& out)
365 {
366 if (properties.border_ && properties.border_->HasBorder()) {
367 out["Border"] = properties.border_->ToString();
368 }
369 auto filter = properties.GetFilter();
370 if (filter && filter->IsValid()) {
371 out["Filter"] = filter->GetDescription();
372 }
373 auto backgroundFilter = properties.GetBackgroundFilter();
374 if (backgroundFilter && backgroundFilter->IsValid()) {
375 out["BackgroundFilter"] = backgroundFilter->GetDescription();
376 }
377 auto foregroundFilterCache = properties.GetForegroundFilterCache();
378 if (foregroundFilterCache && foregroundFilterCache->IsValid()) {
379 out["ForegroundFilter"] = foregroundFilterCache->GetDescription();
380 }
381 if (properties.outline_ && properties.outline_->HasBorder()) {
382 out["Outline"] = properties.outline_->ToString();
383 }
384 if (!ROSEN_EQ(properties.GetFrameGravity(), Gravity::DEFAULT)) {
385 out["FrameGravity"] = static_cast<int>(properties.GetFrameGravity());
386 }
387 if (properties.GetUseEffect()) {
388 out["GetUseEffect"] = true;
389 }
390 auto grayScale = properties.GetGrayScale();
391 if (grayScale.has_value() && !ROSEN_EQ(*grayScale, 0.f)) {
392 out["GrayScale"] = *grayScale;
393 }
394 if (!ROSEN_EQ(properties.GetLightUpEffect(), 1.f)) {
395 out["LightUpEffect"] = properties.GetLightUpEffect();
396 }
397 auto dynamicLightUpRate = properties.GetDynamicLightUpRate();
398 if (dynamicLightUpRate.has_value() && !ROSEN_EQ(*dynamicLightUpRate, 0.f)) {
399 out["DynamicLightUpRate"] = *dynamicLightUpRate;
400 }
401 auto dynamicLightUpDegree = properties.GetDynamicLightUpDegree();
402 if (dynamicLightUpDegree.has_value() && !ROSEN_EQ(*dynamicLightUpDegree, 0.f)) {
403 out["DynamicLightUpDegree"] = *dynamicLightUpDegree;
404 }
405 }
406
DumpNodePropertiesColor(const RSProperties & properties,JsonWriter & out)407 void RSProfiler::DumpNodePropertiesColor(const RSProperties& properties, JsonWriter& out)
408 {
409 auto brightness = properties.GetBrightness();
410 if (brightness.has_value() && !ROSEN_EQ(*brightness, 1.f)) {
411 out["Brightness"] = *brightness;
412 }
413 auto contrast = properties.GetContrast();
414 if (contrast.has_value() && !ROSEN_EQ(*contrast, 1.f)) {
415 out["Contrast"] = *contrast;
416 }
417 auto saturate = properties.GetSaturate();
418 if (saturate.has_value() && !ROSEN_EQ(*saturate, 1.f)) {
419 out["Saturate"] = *saturate;
420 }
421 auto sepia = properties.GetSepia();
422 if (sepia.has_value() && !ROSEN_EQ(*sepia, 0.f)) {
423 out["Sepia"] = *sepia;
424 }
425 auto invert = properties.GetInvert();
426 if (invert.has_value() && !ROSEN_EQ(*invert, 0.f)) {
427 out["Invert"] = *invert;
428 }
429 auto hueRotate = properties.GetHueRotate();
430 if (hueRotate.has_value() && !ROSEN_EQ(*hueRotate, 0.f)) {
431 out["HueRotate"] = *hueRotate;
432 }
433 auto colorBlend = properties.GetColorBlend();
434 if (colorBlend.has_value() && !ROSEN_EQ(*colorBlend, RgbPalette::Transparent())) {
435 out["ColorBlend"] = "#" + Hex(colorBlend->AsArgbInt()) + " (ARGB)";
436 }
437 if (!ROSEN_EQ(properties.GetColorBlendMode(), 0)) {
438 out["skblendmode"] = properties.GetColorBlendMode() - 1;
439 out["blendType"] = properties.GetColorBlendApplyType();
440 }
441 }
442
DumpNodeAnimations(const RSAnimationManager & animationManager,JsonWriter & out)443 void RSProfiler::DumpNodeAnimations(const RSAnimationManager& animationManager, JsonWriter& out)
444 {
445 if (animationManager.animations_.empty()) {
446 return;
447 }
448 auto& animations = out["RSAnimationManager"];
449 animations.PushArray();
450 for (auto [id, animation] : animationManager.animations_) {
451 if (animation) {
452 DumpNodeAnimation(*animation, animations);
453 }
454 }
455 animations.PopArray();
456 }
457
DumpNodeAnimation(const RSRenderAnimation & animation,JsonWriter & out)458 void RSProfiler::DumpNodeAnimation(const RSRenderAnimation& animation, JsonWriter& out)
459 {
460 out.PushObject();
461 out["id"] = animation.id_;
462 std::string type;
463 animation.DumpAnimationType(type);
464 out["type"] = type;
465 out["AnimationState"] = static_cast<int>(animation.state_);
466 out["StartDelay"] = animation.animationFraction_.GetDuration();
467 out["Duration"] = animation.animationFraction_.GetStartDelay();
468 out["Speed"] = animation.animationFraction_.GetSpeed();
469 out["RepeatCount"] = animation.animationFraction_.GetRepeatCount();
470 out["AutoReverse"] = animation.animationFraction_.GetAutoReverse();
471 out["Direction"] = animation.animationFraction_.GetDirection();
472 out["FillMode"] = static_cast<int>(animation.animationFraction_.GetFillMode());
473 out["RepeatCallbackEnable"] = animation.animationFraction_.GetRepeatCallbackEnable();
474 out["FrameRateRange_min"] = animation.animationFraction_.GetFrameRateRange().min_;
475 out["FrameRateRange_max"] = animation.animationFraction_.GetFrameRateRange().max_;
476 out["FrameRateRange_prefered"] = animation.animationFraction_.GetFrameRateRange().preferred_;
477 out.PopObject();
478 }
479
DumpNodeChildrenListUpdate(const RSRenderNode & node,JsonWriter & out)480 void RSProfiler::DumpNodeChildrenListUpdate(const RSRenderNode& node, JsonWriter& out)
481 {
482 if (!node.isFullChildrenListValid_) {
483 auto& childrenUpdate = out["children update"];
484 childrenUpdate.PushObject();
485 childrenUpdate["current count"] = node.fullChildrenList_->size();
486 std::string expected = std::to_string(node.GetSortedChildren()->size());
487 if (!node.disappearingChildren_.empty()) {
488 childrenUpdate["disappearing count"] = node.disappearingChildren_.size();
489 expected += " + " + std::to_string(node.disappearingChildren_.size());
490 }
491 childrenUpdate["expected count"] = expected;
492 childrenUpdate.PopObject();
493 }
494 }
495
496 } // namespace OHOS::Rosen