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