• 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 "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