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