• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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