1 /*
2 * Copyright (c) 2023 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_node_cost_manager.h"
17 #include "pipeline/rs_surface_render_node.h"
18 #include "platform/common/rs_system_properties.h"
19 #include "rs_parallel_render_manager.h"
20 #include "rs_trace.h"
21 namespace OHOS::Rosen {
22
RSNodeCostManager(bool doAnimate,bool opDropped,bool isSecurityDisplay)23 RSNodeCostManager::RSNodeCostManager(bool doAnimate, bool opDropped, bool isSecurityDisplay)
24 {
25 doAnimate_ = doAnimate;
26 isOpDropped_ = opDropped;
27 isSecurityDisplay_ = isSecurityDisplay;
28 isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
29 partialRenderType_ = RSSystemProperties::GetPartialRenderEnabled();
30 }
31
AddNodeCost(int32_t cost)32 void RSNodeCostManager::AddNodeCost(int32_t cost)
33 {
34 dirtyNodeCost_ += cost;
35 }
36
GetDirtyNodeCost() const37 int32_t RSNodeCostManager::GetDirtyNodeCost() const
38 {
39 return dirtyNodeCost_;
40 }
41
CalcNodeCost(RSSurfaceRenderNode & node)42 void RSNodeCostManager::CalcNodeCost(RSSurfaceRenderNode& node)
43 {
44 dirtyNodeCost_ = 0;
45 CalcSurfaceRenderNodeCost(node);
46 }
47
IsSkipProcessing(RSSurfaceRenderNode & node) const48 bool RSNodeCostManager::IsSkipProcessing(RSSurfaceRenderNode& node) const
49 {
50 if (isSecurityDisplay_ && node.GetSecurityLayer()) {
51 return true;
52 }
53 if (!node.ShouldPaint()) {
54 return true;
55 }
56 if (!node.GetOcclusionVisible() && !doAnimate_ && isOcclusionEnabled_ && !isSecurityDisplay_) {
57 return true;
58 }
59 if (node.IsAbilityComponent() && node.GetDstRect().IsEmpty()) {
60 return true;
61 }
62 #ifdef RS_ENABLE_EGLQUERYSURFACE
63 // skip clean surface node
64 if (isOpDropped_ && node.IsAppWindow()) {
65 if (!node.SubNodeNeedDraw(node.GetOldDirtyInSurface(), partialRenderType_)) {
66 return true;
67 }
68 }
69 #endif
70 return false;
71 }
72
CalcBaseRenderNodeCost(RSBaseRenderNode & node)73 void RSNodeCostManager::CalcBaseRenderNodeCost(RSBaseRenderNode& node)
74 {
75 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_GL)
76 for (auto& child : node.GetChildren()) {
77 switch (child->GetType()) {
78 case RSRenderNodeType::SURFACE_NODE: {
79 auto surfaceNodePtr = child->ReinterpretCastTo<RSSurfaceRenderNode>();
80 CalcSurfaceRenderNodeCost(*surfaceNodePtr);
81 break;
82 }
83 case RSRenderNodeType::CANVAS_NODE: {
84 auto canvasNodePtr = child->ReinterpretCastTo<RSCanvasRenderNode>();
85 CalcCanvasRenderNodeCost(*canvasNodePtr);
86 break;
87 }
88 case RSRenderNodeType::RS_NODE:
89 case RSRenderNodeType::DISPLAY_NODE:
90 case RSRenderNodeType::PROXY_NODE:
91 case RSRenderNodeType::ROOT_NODE: {
92 CalcBaseRenderNodeCost(*child);
93 break;
94 }
95 default: {
96 break;
97 }
98 }
99 }
100 #endif
101 }
102
CalcCanvasRenderNodeCost(RSCanvasRenderNode & node)103 void RSNodeCostManager::CalcCanvasRenderNodeCost(RSCanvasRenderNode& node)
104 {
105 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_GL)
106 if (!node.ShouldPaint()) {
107 return;
108 }
109 #ifdef RS_ENABLE_EGLQUERYSURFACE
110 if (isOpDropped_ && costSurfaceNode_ &&
111 !costSurfaceNode_->SubNodeNeedDraw(node.GetOldDirtyInSurface(), partialRenderType_) &&
112 !node.HasChildrenOutOfRect()) {
113 return;
114 }
115 #endif
116 if ((costSurfaceNode_ == nullptr) ||
117 (!costSurfaceNode_->SubNodeNeedDraw(node.GetOldDirtyInSurface(), partialRenderType_) &&
118 !node.HasChildrenOutOfRect())) {
119 return;
120 }
121 auto parallelRenderManager = RSParallelRenderManager::Instance();
122 AddNodeCost(parallelRenderManager->GetCost(node));
123 CalcBaseRenderNodeCost(node);
124 #endif
125 }
126
CalcSurfaceRenderNodeCost(RSSurfaceRenderNode & node)127 void RSNodeCostManager::CalcSurfaceRenderNodeCost(RSSurfaceRenderNode& node)
128 {
129 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_GL)
130 if (IsSkipProcessing(node)) {
131 RS_TRACE_NAME(node.GetName() + " QuickReject Skip");
132 return;
133 }
134 switch (node.GetSurfaceNodeType()) {
135 case RSSurfaceNodeType::SELF_DRAWING_NODE:
136 case RSSurfaceNodeType::ABILITY_COMPONENT_NODE: {
137 auto parallelRenderManager = RSParallelRenderManager::Instance();
138 AddNodeCost(parallelRenderManager->GetSelfDrawNodeCost());
139 return;
140 }
141 case RSSurfaceNodeType::LEASH_WINDOW_NODE: {
142 CalcBaseRenderNodeCost(node);
143 return;
144 }
145 case RSSurfaceNodeType::APP_WINDOW_NODE: {
146 RS_TRACE_NAME_FMT("CalcSurfaceRenderNodeCost %s",
147 node.GetName().c_str());
148 costSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
149 CalcBaseRenderNodeCost(node);
150 RS_TRACE_NAME_FMT("CalcSurfaceRenderNodeCost %s cost %d", node.GetName().c_str(),
151 GetDirtyNodeCost());
152 break;
153 }
154 case RSSurfaceNodeType::STARTING_WINDOW_NODE:
155 case RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE:
156 default: {
157 return;
158 }
159 }
160 #endif
161 }
162 } // OHOS::Rosen