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 "rs_profiler_test_tree.h"
17
18 #include "recording/cmd_list_helper.h"
19 #include "recording/draw_cmd.h"
20 #include "recording/recording_handle.h"
21 #include "rs_profiler.h"
22 #include "rs_profiler_capture_recorder.h"
23 #include "rs_profiler_capturedata.h"
24 #include "rs_profiler_command.h"
25 #include "rs_profiler_file.h"
26 #include "rs_profiler_log.h"
27 #include "rs_profiler_settings.h"
28 #include "rs_profiler_utils.h"
29
30 #include "command/rs_base_node_command.h"
31 #include "command/rs_canvas_drawing_node_command.h"
32 #include "command/rs_canvas_node_command.h"
33 #include "command/rs_display_node_command.h"
34 #include "command/rs_effect_node_command.h"
35 #include "command/rs_node_command.h"
36 #include "command/rs_proxy_node_command.h"
37 #include "command/rs_root_node_command.h"
38 #include "command/rs_surface_node_command.h"
39 #include "common/rs_common_def.h"
40 #include "common/rs_rect.h"
41 #include "common/rs_vector4.h"
42 #include "draw/color.h"
43 #include "draw/core_canvas.h"
44 #include "image/bitmap.h"
45 #include "image/image.h"
46 #include "modifier_ng/background/rs_background_color_render_modifier.h"
47 #include "modifier_ng/geometry/rs_bounds_render_modifier.h"
48 #include "modifier_ng/geometry/rs_frame_render_modifier.h"
49 #include "modifier_ng/geometry/rs_transform_render_modifier.h"
50 #include "pipeline/main_thread/rs_main_thread.h"
51 #include "pipeline/main_thread/rs_render_service_connection.h"
52 #include "pipeline/render_thread/rs_uni_render_util.h"
53 #include "pipeline/rs_render_node.h"
54 #include "pipeline/rs_render_node_gc.h"
55 #include "pipeline/rs_screen_render_node.h"
56 #include "platform/common/rs_log.h"
57 #include "render/rs_typeface_cache.h"
58 #include "transaction/rs_marshalling_helper.h"
59 #include "utils/rect.h"
60 #include "utils/sampling_options.h"
61
62 namespace OHOS::Rosen {
63
GenerateRandomImage(int width,int height)64 Drawing::Image TestTreeBuilder::GenerateRandomImage(int width, int height)
65 {
66 const auto& bitmapFormat = Drawing::BitmapFormat {
67 .colorType = Drawing::COLORTYPE_RGBA_8888,
68 .alphaType = Drawing::ALPHATYPE_OPAQUE,
69 };
70 auto bitmap = Drawing::Bitmap();
71 bitmap.Build(width, height, bitmapFormat);
72 auto pixelsPtr = static_cast<uint8_t*>(bitmap.GetPixels());
73 if (pixelsPtr) {
74 const auto& imageInfo = bitmap.GetImageInfo();
75 size_t bytesPerPixel = static_cast<size_t>(imageInfo.GetBytesPerPixel());
76 int heightImage = bitmap.GetHeight();
77 int rowBytes = bitmap.GetRowBytes();
78
79 for (int i = 0; i < heightImage; ++i) {
80 for (int j = 0; j < rowBytes; ++j) {
81 *pixelsPtr = distribution_(mt_);
82 pixelsPtr += 1;
83 }
84 }
85 }
86 auto image = Drawing::Image();
87 image.BuildFromBitmap(bitmap);
88 return image;
89 }
90
TestTreeBuilder()91 TestTreeBuilder::TestTreeBuilder()
92 : mt_(std::random_device()()), insideId_(0), withDisplay_(false), withScreenNode_(false),
93 withPatchedGlobalRoot_(false)
94 {}
95
CreateNode00(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)96 void TestTreeBuilder::CreateNode00(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
97 {
98 // DISPLAY or ROOT node +0
99 NodeId screenNodeId = insideId_++;
100 NodeId currentId = insideId_++;
101 if (withDisplay_) {
102 if (withPatchedGlobalRoot_) {
103 RootNodeCommandHelper::Create(context, Utils::PatchNodeId(0));
104 }
105 if (withScreenNode_) {
106 auto node = std::make_shared<RSScreenRenderNode>(screenNodeId, screenNodeId, context.weak_from_this());
107 context.GetMutableNodeMap().RegisterRenderNode(node);
108
109 if (withPatchedGlobalRoot_) {
110 BaseNodeCommandHelper::AddChild(context, Utils::PatchNodeId(0), screenNodeId, 0);
111 } else {
112 context.GetGlobalRootRenderNode()->AddChild(node);
113 }
114
115 HRPIDN("BuildTestTree: Builded Render Screen node wit id: %" PRIu64, screenNodeId);
116 }
117 RSDisplayNodeConfig displayNodeConfig {};
118 displayNodeConfig.screenId = screenNodeId;
119 DisplayNodeCommandHelper::Create(context, currentId, displayNodeConfig);
120
121 HRPIDN("BuildTestTree: Builded Display node wit id: %" PRIu64, currentId);
122 } else {
123 RootNodeCommandHelper::Create(context, currentId);
124 HRPIDN("BuildTestTree: Builded Root node wit id: %" PRIu64, currentId);
125 }
126
127 auto positionZProperty = std::make_shared<RSRenderAnimatableProperty<float>>(visibleZPosition);
128 auto positionZModifier = std::make_shared<ModifierNG::RSTransformRenderModifier>();
129 positionZModifier->AttachProperty(ModifierNG::RSPropertyType::POSITION_Z, positionZProperty);
130
131 RSNodeCommandHelper::AddModifierNG(context, currentId, positionZModifier);
132 const auto& node = RSProfiler::GetRenderNode(currentId);
133 if (!node) {
134 return;
135 }
136 node->ApplyModifiers();
137 tree.push_back(node);
138 }
139
CreateNode01(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)140 void TestTreeBuilder::CreateNode01(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
141 {
142 // CANVAS node +1
143 NodeId currentId = insideId_++;
144 RSCanvasNodeCommandHelper::Create(context, currentId);
145
146 auto boundsProperty =
147 std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(startX, startY, width, height), zero);
148 auto boundsModifier = std::make_shared<ModifierNG::RSBoundsRenderModifier>();
149 boundsModifier->AttachProperty(ModifierNG::RSPropertyType::BOUNDS, boundsProperty);
150 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifier);
151
152 auto frameProperty =
153 std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(startX, startY, width, height), one);
154 auto frameModifier = std::make_shared<ModifierNG::RSFrameRenderModifier>();
155 frameModifier->AttachProperty(ModifierNG::RSPropertyType::FRAME, frameProperty);
156 RSNodeCommandHelper::AddModifierNG(context, currentId, frameModifier);
157
158 auto positionZProperty = std::make_shared<RSRenderAnimatableProperty<float>>(visibleZPosition, two);
159 auto positionZModifier = std::make_shared<ModifierNG::RSTransformRenderModifier>();
160 positionZModifier->AttachProperty(ModifierNG::RSPropertyType::POSITION_Z, positionZProperty);
161 RSNodeCommandHelper::AddModifierNG(context, currentId, positionZModifier);
162
163 auto backgroundColorProperty = std::make_shared<RSRenderAnimatableProperty<Color>>(almostWhite_, three);
164 auto backgroundColorModifier = std::make_shared<ModifierNG::RSBackgroundColorRenderModifier>();
165 backgroundColorModifier->AttachProperty(ModifierNG::RSPropertyType::BACKGROUND_COLOR, backgroundColorProperty);
166 RSNodeCommandHelper::AddModifierNG(context, currentId, backgroundColorModifier);
167
168 BaseNodeCommandHelper::AddChild(context, currentId - one, currentId, zero);
169
170 auto node = RSProfiler::GetRenderNode(currentId);
171 if (!node) {
172 return;
173 }
174 node->ApplyModifiers();
175 tree.push_back(node);
176 HRPIDN("BuildTestTree: Builded Canvas node wit id: %" PRIu64, currentId);
177 }
178
CreateNode02(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)179 void TestTreeBuilder::CreateNode02(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
180 {
181 // DRAWING_CANVAS node +2
182 NodeId currentId = insideId_++;
183 RSCanvasDrawingNodeCommandHelper::Create(context, currentId);
184
185 auto boundsPropertyV11 = std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(0, 0, width13, height));
186 auto boundsModifierV11 = std::make_shared<ModifierNG::RSBoundsRenderModifier>();
187 boundsModifierV11->AttachProperty(ModifierNG::RSPropertyType::BOUNDS, boundsPropertyV11);
188 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifierV11);
189
190 BaseNodeCommandHelper::AddChild(context, currentId - one, currentId, zero);
191
192 auto node = RSProfiler::GetRenderNode(currentId);
193 if (!node) {
194 return;
195 }
196 node->ApplyModifiers();
197 tree.push_back(node);
198 HRPIDN("BuildTestTree: Builded Drawing Canvas node wit id: %" PRIu64, currentId);
199 }
200
CreateNode03(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)201 void TestTreeBuilder::CreateNode03(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
202 {
203 // SURFACE node +3
204 NodeId currentId = insideId_++;
205 SurfaceNodeCommandHelper::Create(context, currentId);
206
207 auto boundsPropertyV20 =
208 std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(width13, 0, width23, height));
209 auto boundsModifierV20 = std::make_shared<ModifierNG::RSBoundsRenderModifier>();
210 boundsModifierV20->AttachProperty(ModifierNG::RSPropertyType::BOUNDS, boundsPropertyV20);
211 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifierV20);
212
213 BaseNodeCommandHelper::AddChild(context, currentId - two, currentId, zero);
214
215 auto node = RSProfiler::GetRenderNode(currentId);
216 if (!node) {
217 return;
218 }
219 node->ApplyModifiers();
220 tree.push_back(node);
221 HRPIDN("BuildTestTree: Builded Surface node wit id: %" PRIu64, currentId);
222 }
223
CreateNode04(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)224 void TestTreeBuilder::CreateNode04(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
225 {
226 // EFFECT node +4
227 NodeId currentId = insideId_++;
228 EffectNodeCommandHelper::Create(context, currentId);
229
230 auto boundsPropertyV12 = std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(0, 0, width13, height));
231 auto boundsModifierV12 = std::make_shared<ModifierNG::RSBoundsRenderModifier>();
232 boundsModifierV12->AttachProperty(ModifierNG::RSPropertyType::BOUNDS, boundsPropertyV12);
233 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifierV12);
234
235 BaseNodeCommandHelper::AddChild(context, currentId - one, currentId, zero);
236
237 auto node = RSProfiler::GetRenderNode(currentId);
238 if (!node) {
239 return;
240 }
241 node->ApplyModifiers();
242 tree.push_back(node);
243 HRPIDN("BuildTestTree: Builded Effect node wit id: %" PRIu64, currentId);
244 }
245
CreateNode05(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)246 void TestTreeBuilder::CreateNode05(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
247 {
248 // CANVAS node +5
249 NodeId currentId = insideId_++;
250 RSCanvasNodeCommandHelper::Create(context, currentId);
251
252 auto rect = Drawing::Rect(0, 0, width13, height);
253 auto roundRect = Drawing::RoundRect(rect, static_cast<float>(width13) / two, static_cast<float>(height) / five);
254
255 auto color = Drawing::Color::COLOR_RED;
256 auto paint = Drawing::Paint(color);
257 paint.SetStyle(Drawing::Paint::PaintStyle::PAINT_FILL);
258 auto drawRoundRect = std::make_shared<Drawing::DrawRoundRectOpItem>(roundRect, paint);
259 auto drawCmds =
260 std::make_shared<Drawing::DrawCmdList>(width13, height, Drawing::DrawCmdList::UnmarshalMode::DEFERRED);
261 drawCmds->AddDrawOp(drawRoundRect);
262 RSCanvasNodeCommandHelper::UpdateRecording(
263 context, currentId, drawCmds, static_cast<uint16_t>(ModifierNG::RSModifierType::CONTENT_STYLE));
264
265 auto boundsPropertyV120 = std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(0, 0, width13, height));
266 auto boundsModifierV120 = std::make_shared<ModifierNG::RSBoundsRenderModifier>();
267 boundsModifierV120->AttachProperty(ModifierNG::RSPropertyType::BOUNDS, boundsPropertyV120);
268 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifierV120);
269
270 auto frameModifierV120 = std::make_shared<ModifierNG::RSFrameRenderModifier>();
271 frameModifierV120->AttachProperty(ModifierNG::RSPropertyType::FRAME, boundsPropertyV120);
272 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifierV120);
273
274 BaseNodeCommandHelper::AddChild(context, currentId - one, currentId, zero);
275
276 auto node = RSProfiler::GetRenderNode(currentId);
277 if (!node) {
278 return;
279 }
280 node->ApplyModifiers();
281 tree.push_back(node);
282 HRPIDN("BuildTestTree: Builded Canvas node wit id: %" PRIu64, currentId);
283 }
284
CreateNode06(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)285 void TestTreeBuilder::CreateNode06(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
286 {
287 // CANVAS node +6
288 NodeId currentId = insideId_++;
289 RSCanvasNodeCommandHelper::Create(context, currentId);
290
291 auto boundsPropertyV21 =
292 std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(width13, 0, width13, height13));
293 auto boundsModifierV21 = std::make_shared<ModifierNG::RSBoundsRenderModifier>();
294 boundsModifierV21->AttachProperty(ModifierNG::RSPropertyType::BOUNDS, boundsPropertyV21);
295 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifierV21);
296
297 auto drawCmds =
298 std::make_shared<Drawing::DrawCmdList>(width13, height13, Drawing::DrawCmdList::UnmarshalMode::DEFERRED);
299 RSCanvasNodeCommandHelper::UpdateRecording(
300 context, currentId, drawCmds, static_cast<uint16_t>(ModifierNG::RSModifierType::CONTENT_STYLE));
301
302 BaseNodeCommandHelper::AddChild(context, currentId - three, currentId, zero);
303
304 auto node = RSProfiler::GetRenderNode(currentId);
305 if (!node) {
306 return;
307 }
308 node->ApplyModifiers();
309 tree.push_back(node);
310 HRPIDN("BuildTestTree: Builded Canvas node wit id: %" PRIu64, currentId);
311 }
312
CreateNode07(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)313 void TestTreeBuilder::CreateNode07(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
314 {
315 // CANVAS node +7
316 NodeId currentId = insideId_++;
317 RSCanvasNodeCommandHelper::Create(context, currentId);
318
319 auto boundsPropertyV22 =
320 std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(width13, height13, width13, height13));
321 auto boundsModifierV22 = std::make_shared<ModifierNG::RSBoundsRenderModifier>();
322 boundsModifierV22->AttachProperty(ModifierNG::RSPropertyType::BOUNDS, boundsPropertyV22);
323 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifierV22);
324
325 auto drawCmds =
326 std::make_shared<Drawing::DrawCmdList>(width13, height13, Drawing::DrawCmdList::UnmarshalMode::DEFERRED);
327 RSCanvasNodeCommandHelper::UpdateRecording(
328 context, currentId, drawCmds, static_cast<uint16_t>(ModifierNG::RSModifierType::BACKGROUND_STYLE));
329 BaseNodeCommandHelper::AddChild(context, currentId - four, currentId, zero);
330
331 auto node = RSProfiler::GetRenderNode(currentId);
332 if (!node) {
333 return;
334 }
335 node->ApplyModifiers();
336 tree.push_back(node);
337 HRPIDN("BuildTestTree: Builded Canvas node wit id: %" PRIu64, currentId);
338 }
339
CreateNode08(RSContext & context,std::vector<std::shared_ptr<RSRenderNode>> & tree)340 void TestTreeBuilder::CreateNode08(RSContext& context, std::vector<std::shared_ptr<RSRenderNode>>& tree)
341 {
342 // CANVAS node +8
343 NodeId currentId = insideId_++;
344 RSCanvasNodeCommandHelper::Create(context, currentId);
345
346 auto boundsPropertyV23 =
347 std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(width13, height23, width13, height23));
348 auto boundsModifierV23 = std::make_shared<ModifierNG::RSBoundsRenderModifier>();
349 boundsModifierV23->AttachProperty(ModifierNG::RSPropertyType::BOUNDS, boundsPropertyV23);
350 RSNodeCommandHelper::AddModifierNG(context, currentId, boundsModifierV23);
351
352 auto framePropertyV23 =
353 std::make_shared<RSRenderAnimatableProperty<Vector4f>>(Vector4f(width13, height23, width13, height23));
354 auto frameModifierV23 = std::make_shared<ModifierNG::RSFrameRenderModifier>();
355 frameModifierV23->AttachProperty(ModifierNG::RSPropertyType::FRAME, framePropertyV23);
356 RSNodeCommandHelper::AddModifierNG(context, currentId, frameModifierV23);
357
358 auto drawCmds =
359 std::make_shared<Drawing::DrawCmdList>(width13, height13, Drawing::DrawCmdList::UnmarshalMode::DEFERRED);
360 const float singleRadius = 0.5f;
361 std::vector<Drawing::Point> radius = {
362 { singleRadius, singleRadius },
363 { singleRadius, singleRadius },
364 { singleRadius, singleRadius },
365 { singleRadius, singleRadius },
366 };
367 auto clipAdaptiveRoundRectOpItem = Drawing::ClipAdaptiveRoundRectOpItem(radius);
368 auto clipAdaptiveRoundRectOpItemPtr =
369 std::make_shared<Drawing::ClipAdaptiveRoundRectOpItem>(clipAdaptiveRoundRectOpItem);
370 drawCmds->AddDrawOp(clipAdaptiveRoundRectOpItemPtr);
371 RSCanvasNodeCommandHelper::UpdateRecording(
372 context, currentId, drawCmds, static_cast<uint16_t>(ModifierNG::RSModifierType::CONTENT_STYLE));
373
374 RSCanvasNodeCommandHelper::UpdateRecording(context, currentId,
375 std::make_shared<Drawing::DrawCmdList>(width13, height13, Drawing::DrawCmdList::UnmarshalMode::DEFERRED),
376 static_cast<uint16_t>(ModifierNG::RSModifierType::OVERLAY_STYLE));
377
378 BaseNodeCommandHelper::AddChild(context, currentId - five, currentId, zero);
379
380 auto node = RSProfiler::GetRenderNode(currentId);
381 if (!node) {
382 return;
383 }
384 node->ApplyModifiers();
385 tree.push_back(node);
386 HRPIDN("BuildTestTree: Builded Canvas node wit id: %" PRIu64, currentId);
387 }
388
Build(RSContext & context,NodeId topId,bool withDisplay,bool withScreenNode,bool withPatchedGlobalRoot)389 std::vector<std::shared_ptr<RSRenderNode>> TestTreeBuilder::Build(
390 RSContext& context, NodeId topId, bool withDisplay, bool withScreenNode, bool withPatchedGlobalRoot)
391 {
392 using OHOS::Rosen::DisplayNodeCommandHelper;
393 using OHOS::Rosen::EffectNodeCommandHelper;
394 using OHOS::Rosen::RSCanvasNodeCommandHelper;
395 using OHOS::Rosen::SurfaceNodeCommandHelper;
396
397 std::vector<std::shared_ptr<RSRenderNode>> tree;
398 insideId_ = topId;
399 withDisplay_ = withDisplay;
400 withScreenNode_ = withScreenNode;
401 withPatchedGlobalRoot_ = withPatchedGlobalRoot;
402
403 /* graph structure of tree:
404
405 DISPLAY node OR ROOT node
406 |- CANVAS node +1
407 |- DRAWING_CANVAS node +2
408 |- SURFACE node +3
409 |- EFFECT node +4
410 | |- CANVAS node +5
411 |- CANVAS node +6
412 |- CANVAS node +7
413 |- CANVAS node +8
414 */
415
416 CreateNode00(context, tree);
417 CreateNode01(context, tree);
418 CreateNode02(context, tree);
419 CreateNode03(context, tree);
420 CreateNode04(context, tree);
421 CreateNode05(context, tree);
422 CreateNode06(context, tree);
423 CreateNode07(context, tree);
424 CreateNode08(context, tree);
425
426 for (const auto& node : tree) {
427 if (!node) {
428 continue;
429 }
430 node->SetContentDirty();
431 node->SetDirty();
432 }
433
434 return tree;
435 }
436 } // namespace OHOS::Rosen