1 /*
2 * Copyright (c) 2022 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_parallel_pack_visitor.h"
17 #include "pipeline/rs_base_render_node.h"
18 #include "pipeline/rs_surface_render_node.h"
19 #include "pipeline/rs_display_render_node.h"
20 #include "pipeline/parallel_render/rs_parallel_render_manager.h"
21 #include "pipeline/rs_uni_render_visitor.h"
22 #include "rs_trace.h"
23 #include "common/rs_optional_trace.h"
24
25 namespace OHOS {
26 namespace Rosen {
RSParallelPackVisitor(RSUniRenderVisitor & visitor)27 RSParallelPackVisitor::RSParallelPackVisitor(RSUniRenderVisitor &visitor)
28 : partialRenderType_(RSSystemProperties::GetUniPartialRenderEnabled())
29 {
30 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
31 isPartialRenderEnabled_ = visitor.GetIsPartialRenderEnabled();
32 isOpDropped_ = visitor.GetIsOpDropped();
33 doAnimate_ = visitor.GetAnimateState();
34 }
35
PrepareChildren(RSRenderNode & node)36 void RSParallelPackVisitor::PrepareChildren(RSRenderNode &node)
37 {
38 node.ApplyChildrenModifiers();
39 for (auto& child : node.GetSortedChildren()) {
40 child->Prepare(shared_from_this());
41 }
42 }
43
PrepareDisplayRenderNode(RSDisplayRenderNode & node)44 void RSParallelPackVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode &node)
45 {
46 isFirstSurfaceNode_ = true;
47 PrepareChildren(node);
48 }
49
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)50 void RSParallelPackVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode &node)
51 {
52 if (!isFirstSurfaceNode_) {
53 RSParallelRenderManager::Instance()->PackRenderTask(node, TaskType::PREPARE_TASK);
54 } else {
55 isFirstSurfaceNode_ = false;
56 RSParallelRenderManager::Instance()->WorkSerialTask(node);
57 }
58 }
59
ProcessChildren(RSRenderNode & node)60 void RSParallelPackVisitor::ProcessChildren(RSRenderNode &node)
61 {
62 for (auto &child : node.GetSortedChildren()) {
63 child->Process(shared_from_this());
64 }
65 }
66
ProcessDisplayRenderNode(RSDisplayRenderNode & node)67 void RSParallelPackVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode &node)
68 {
69 RSParallelRenderManager::Instance()->ClearFilterSurfaceRenderNode();
70 isSecurityDisplay_ = node.GetSecurityDisplay();
71 ProcessChildren(node);
72 }
73
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)74 void RSParallelPackVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode &node)
75 {
76 auto instance = RSParallelRenderManager::Instance();
77 // DockView and windows whose z-order is larger than DockView are drawn in render service main thread.
78 if (node.GetName() == "DockView" || instance->GetFilterSurfaceRenderNodeCount() > 0) {
79 instance->SetFilterSurfaceRenderNode(node);
80 return;
81 }
82 RS_TRACE_NAME("RSParallelPackVisitor::Process:[" + node.GetName() + "]" + node.GetDstRect().ToString());
83 RS_LOGD("RSParallelPackVisitor::ProcessSurfaceRenderNode node: %" PRIu64 ", child size:%u %s", node.GetId(),
84 node.GetChildrenCount(), node.GetName().c_str());
85 node.UpdatePositionZ();
86 if (IsSkipProcessing(node)) {
87 return;
88 }
89 instance->PackRenderTask(node, TaskType::PROCESS_TASK);
90 }
91
IsSkipProcessing(RSSurfaceRenderNode & node) const92 bool RSParallelPackVisitor::IsSkipProcessing(RSSurfaceRenderNode& node) const
93 {
94 if (isSecurityDisplay_ && node.GetSecurityLayer()) {
95 RS_OPTIONAL_TRACE_NAME("SecurityLayer Skip");
96 return true;
97 }
98
99 if (!node.ShouldPaint()) {
100 RS_LOGD("RSParallelPackVisitor::ProcessSurfaceRenderNode node: %" PRIu64 " invisible", node.GetId());
101 return true;
102 }
103 if (!node.GetOcclusionVisible() && !doAnimate_
104 && RSSystemProperties::GetOcclusionEnabled() && !isSecurityDisplay_) {
105 RS_OPTIONAL_TRACE_NAME("Occlusion Skip");
106 return true;
107 }
108 #ifdef RS_ENABLE_EGLQUERYSURFACE
109 // skip clean surface node
110 if (isOpDropped_ && node.IsAppWindow()) {
111 if (!node.SubNodeNeedDraw(node.GetOldDirtyInSurface(), partialRenderType_)) {
112 RS_OPTIONAL_TRACE_NAME("QuickReject Skip");
113 RS_LOGD("RSParallelPackVisitor::ProcessSurfaceRenderNode skip: %s", node.GetName().c_str());
114 return true;
115 }
116 }
117 #endif
118 return false;
119 }
120
CalcSurfaceRenderNodeCost(RSSurfaceRenderNode & node) const121 void RSParallelPackVisitor::CalcSurfaceRenderNodeCost(RSSurfaceRenderNode& node) const
122 {
123 if (IsSkipProcessing(node)) {
124 return;
125 }
126 RSParallelRenderManager::Instance()->PackRenderTask(node, TaskType::CALC_COST_TASK);
127 }
128
CalcDisplayRenderNodeCost(RSDisplayRenderNode & node) const129 void RSParallelPackVisitor::CalcDisplayRenderNodeCost(RSDisplayRenderNode& node) const
130 {
131 for (auto& child : node.GetChildren()) {
132 auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
133 if (surface != nullptr) {
134 CalcSurfaceRenderNodeCost(*surface);
135 }
136 }
137 }
138 } // namespace Rosen
139 } // namespace OHOS
140