1 /*
2 * Copyright (c) 2021-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 "pipeline/rs_render_service_visitor.h"
17
18 #include "include/core/SkCanvas.h"
19 #include "include/core/SkPoint.h"
20 #include "include/core/SkRect.h"
21 #include "rs_divided_render_util.h"
22 #include "rs_trace.h"
23
24 #include "common/rs_obj_abs_geometry.h"
25 #include "pipeline/rs_base_render_node.h"
26 #include "pipeline/rs_display_render_node.h"
27 #include "pipeline/rs_processor.h"
28 #include "pipeline/rs_processor_factory.h"
29 #include "pipeline/rs_surface_render_node.h"
30 #include "platform/common/rs_log.h"
31 #include "platform/common/rs_innovation.h"
32 #include "platform/drawing/rs_surface.h"
33 #include "screen_manager/rs_screen_manager.h"
34 #include "screen_manager/screen_types.h"
35
36 namespace OHOS {
37 namespace Rosen {
38
RSRenderServiceVisitor(bool parallel)39 RSRenderServiceVisitor::RSRenderServiceVisitor(bool parallel) : mParallelEnable(parallel) {}
40
~RSRenderServiceVisitor()41 RSRenderServiceVisitor::~RSRenderServiceVisitor() {}
42
PrepareBaseRenderNode(RSBaseRenderNode & node)43 void RSRenderServiceVisitor::PrepareBaseRenderNode(RSBaseRenderNode& node)
44 {
45 for (auto& child : node.GetSortedChildren()) {
46 child->Prepare(shared_from_this());
47 }
48 }
49
ProcessBaseRenderNode(RSBaseRenderNode & node)50 void RSRenderServiceVisitor::ProcessBaseRenderNode(RSBaseRenderNode& node)
51 {
52 for (auto& child : node.GetSortedChildren()) {
53 child->Process(shared_from_this());
54 }
55 if (!mParallelEnable) {
56 // clear SortedChildren, it will be generated again in next frame
57 node.ResetSortedChildren();
58 }
59 }
60
PrepareDisplayRenderNode(RSDisplayRenderNode & node)61 void RSRenderServiceVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode& node)
62 {
63 node.ApplyModifiers();
64 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
65 if (!screenManager) {
66 RS_LOGE("RSRenderServiceVisitor::PrepareDisplayRenderNode ScreenManager is nullptr");
67 return;
68 }
69 offsetX_ = node.GetDisplayOffsetX();
70 offsetY_ = node.GetDisplayOffsetY();
71 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
72 ScreenState state = curScreenInfo.state;
73 switch (state) {
74 case ScreenState::PRODUCER_SURFACE_ENABLE:
75 node.SetCompositeType(RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE);
76 break;
77 case ScreenState::HDI_OUTPUT_ENABLE:
78 node.SetCompositeType(node.IsForceSoftComposite() ?
79 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE:
80 RSDisplayRenderNode::CompositeType::HARDWARE_COMPOSITE);
81 break;
82 default:
83 RS_LOGE("RSRenderServiceVisitor::PrepareDisplayRenderNode State is unusual");
84 return;
85 }
86
87 ScreenRotation rotation = node.GetRotation();
88 int32_t logicalScreenWidth = static_cast<int32_t>(node.GetRenderProperties().GetFrameWidth());
89 int32_t logicalScreenHeight = static_cast<int32_t>(node.GetRenderProperties().GetFrameHeight());
90
91 if (logicalScreenWidth <= 0 || logicalScreenHeight <= 0) {
92 logicalScreenWidth = static_cast<int32_t>(curScreenInfo.width);
93 logicalScreenHeight = static_cast<int32_t>(curScreenInfo.height);
94
95 if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
96 std::swap(logicalScreenWidth, logicalScreenHeight);
97 }
98 }
99
100 if (node.IsMirrorDisplay()) {
101 auto mirrorSource = node.GetMirrorSource();
102 auto existingSource = mirrorSource.lock();
103 if (!existingSource) {
104 RS_LOGI("RSRenderServiceVisitor::PrepareDisplayRenderNode mirrorSource haven't existed");
105 return;
106 }
107 if (mParallelEnable) {
108 skCanvas_ = std::make_unique<SkCanvas>(logicalScreenWidth, logicalScreenHeight);
109 canvas_ = std::make_shared<RSPaintFilterCanvas>(skCanvas_.get());
110 canvas_->clipRect(SkRect::MakeWH(logicalScreenWidth, logicalScreenHeight));
111 }
112 PrepareBaseRenderNode(*existingSource);
113 } else {
114 auto boundsGeoPtr = std::static_pointer_cast<RSObjAbsGeometry>(node.GetRenderProperties().GetBoundsGeometry());
115 RSDividedRenderUtil::SetNeedClient(boundsGeoPtr && boundsGeoPtr->IsNeedClientCompose());
116 skCanvas_ = std::make_unique<SkCanvas>(logicalScreenWidth, logicalScreenHeight);
117 canvas_ = std::make_shared<RSPaintFilterCanvas>(skCanvas_.get());
118 canvas_->clipRect(SkRect::MakeWH(logicalScreenWidth, logicalScreenHeight));
119 PrepareBaseRenderNode(node);
120 }
121
122 node.GetCurAllSurfaces().clear();
123 node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(), false);
124 }
125
ProcessDisplayRenderNode(RSDisplayRenderNode & node)126 void RSRenderServiceVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
127 {
128 isSecurityDisplay_ = node.GetSecurityDisplay();
129 RS_LOGD("RsDebug RSRenderServiceVisitor::ProcessDisplayRenderNode: nodeid:[%" PRIu64 "] screenid:[%" PRIu64 "] \
130 isSecurityDisplay:[%s] child size:[%d] total size:[%d]",
131 node.GetId(), node.GetScreenId(), isSecurityDisplay_ ? "true" : "false", node.GetChildrenCount(),
132 node.GetSortedChildren().size());
133 globalZOrder_ = 0.0f;
134 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
135 if (!screenManager) {
136 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode ScreenManager is nullptr");
137 return;
138 }
139 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
140 RS_TRACE_NAME("ProcessDisplayRenderNode[" + std::to_string(node.GetScreenId()) + "]");
141 // skip frame according to skipFrameInterval value of SetScreenSkipFrameInterval interface
142 if (node.SkipFrame(curScreenInfo.skipFrameInterval)) {
143 return;
144 }
145 processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType());
146 if (processor_ == nullptr) {
147 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode: RSProcessor is null!");
148 return;
149 }
150 auto mirrorNode = node.GetMirrorSource().lock();
151 if (!processor_->Init(node, node.GetDisplayOffsetX(), node.GetDisplayOffsetY(),
152 mirrorNode ? mirrorNode->GetScreenId() : INVALID_SCREEN_ID)) {
153 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode: processor init failed!");
154 return;
155 }
156
157 if (node.IsMirrorDisplay()) {
158 auto mirrorSource = node.GetMirrorSource();
159 auto existingSource = mirrorSource.lock();
160 if (!existingSource) {
161 RS_LOGI("RSRenderServiceVisitor::ProcessDisplayRenderNode mirrorSource haven't existed");
162 return;
163 }
164 ProcessBaseRenderNode(*existingSource);
165 } else {
166 ProcessBaseRenderNode(node);
167 }
168 processor_->PostProcess();
169 }
170
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)171 void RSRenderServiceVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
172 {
173 if (RSInnovation::GetParallelCompositionEnabled()) {
174 typedef bool (*CheckForSerialForcedFunc)(std::string&);
175 CheckForSerialForcedFunc CheckForSerialForced =
176 reinterpret_cast<CheckForSerialForcedFunc>(RSInnovation::_s_checkForSerialForced);
177 auto name = node.GetName();
178 mForceSerial |= CheckForSerialForced(name);
179 }
180
181 if (isSecurityDisplay_ && node.GetSecurityLayer()) {
182 RS_LOGI("RSRenderServiceVisitor::PrepareSurfaceRenderNode node[%" PRIu64 "] prepare paused because of \
183 security DisplayNode.",
184 node.GetId());
185 return;
186 }
187 if (!canvas_) {
188 RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : %" PRIu64 " canvas is nullptr", node.GetId());
189 return;
190 }
191 node.ApplyModifiers();
192 if (!node.ShouldPaint()) {
193 RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : %" PRIu64 " is invisible", node.GetId());
194 return;
195 }
196 node.SetOffset(offsetX_, offsetY_);
197 node.PrepareRenderBeforeChildren(*canvas_);
198 PrepareBaseRenderNode(node);
199 node.PrepareRenderAfterChildren(*canvas_);
200 }
201
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)202 void RSRenderServiceVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
203 {
204 if (!processor_) {
205 RS_LOGE("RSRenderServiceVisitor::ProcessSurfaceRenderNode processor is nullptr");
206 return;
207 }
208 if (isSecurityDisplay_ && node.GetSecurityLayer()) {
209 RS_LOGI("RSRenderServiceVisitor::ProcessSurfaceRenderNode node[%" PRIu64 "] process paused because of \
210 security DisplayNode.",
211 node.GetId());
212 return;
213 }
214 if (!node.ShouldPaint()) {
215 RS_LOGD("RSRenderServiceVisitor::ProcessSurfaceRenderNode node : %" PRIu64 " is invisible", node.GetId());
216 return;
217 }
218 if (!node.GetOcclusionVisible() && !doAnimate_ && RSSystemProperties::GetOcclusionEnabled()) {
219 return;
220 }
221 if (mParallelEnable) {
222 node.ParallelVisitLock();
223 }
224 ProcessBaseRenderNode(node);
225 node.SetGlobalZOrder(globalZOrder_);
226 globalZOrder_ = globalZOrder_ + 1;
227 processor_->ProcessSurface(node);
228 RSBaseRenderUtil::WriteSurfaceRenderNodeToPng(node);
229 if (mParallelEnable) {
230 node.ParallelVisitUnlock();
231 }
232 }
233 } // namespace Rosen
234 } // namespace OHOS
235