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/main_thread/rs_render_service_visitor.h"
17
18 #include "pipeline/render_thread/rs_divided_render_util.h"
19 #include "pipeline/rs_logical_display_render_node.h"
20 #include "rs_trace.h"
21
22 #include "common/rs_obj_abs_geometry.h"
23 #include "pipeline/main_thread/rs_main_thread.h"
24 #include "pipeline/rs_base_render_node.h"
25 #include "pipeline/rs_processor.h"
26 #include "pipeline/rs_processor_factory.h"
27 #include "pipeline/rs_screen_render_node.h"
28 #include "pipeline/rs_surface_render_node.h"
29 #include "platform/common/rs_log.h"
30 #include "platform/common/rs_innovation.h"
31 #include "platform/drawing/rs_surface.h"
32 #include "screen_manager/rs_screen_manager.h"
33 #include "screen_manager/screen_types.h"
34
35 #undef LOG_TAG
36 #define LOG_TAG "RSRenderServiceVisitor"
37
38 namespace OHOS {
39 namespace Rosen {
40
RSRenderServiceVisitor(bool parallel)41 RSRenderServiceVisitor::RSRenderServiceVisitor(bool parallel) : mParallelEnable(parallel) {}
42
~RSRenderServiceVisitor()43 RSRenderServiceVisitor::~RSRenderServiceVisitor() {}
44
PrepareChildren(RSRenderNode & node)45 void RSRenderServiceVisitor::PrepareChildren(RSRenderNode& node)
46 {
47 for (auto& child : *node.GetSortedChildren()) {
48 child->Prepare(shared_from_this());
49 }
50 }
51
ProcessChildren(RSRenderNode & node)52 void RSRenderServiceVisitor::ProcessChildren(RSRenderNode& node)
53 {
54 for (auto& child : *node.GetSortedChildren()) {
55 child->Process(shared_from_this());
56 }
57 }
58
PrepareScreenRenderNode(RSScreenRenderNode & node)59 void RSRenderServiceVisitor::PrepareScreenRenderNode(RSScreenRenderNode& node)
60 {
61 currentVisitDisplay_ = node.GetScreenId();
62 displayHasSecSurface_.emplace(currentVisitDisplay_, false);
63 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
64 if (!screenManager) {
65 RS_LOGE("PrepareScreenRenderNode ScreenManager is nullptr");
66 return;
67 }
68 node.SetScreenInfo(screenManager->QueryScreenInfo(node.GetScreenId()));
69 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
70 offsetX_ = curScreenInfo.offsetX;
71 offsetY_ = curScreenInfo.offsetY;
72 UpdateScreenNodeCompositeType(node, curScreenInfo);
73
74 ResetSurfaceNodeAttrsInScreenNode(node);
75
76 curScreenNode_ = node.shared_from_this()->ReinterpretCastTo<RSScreenRenderNode>();
77
78 int32_t logicalScreenWidth = static_cast<int32_t>(node.GetRenderProperties().GetFrameWidth());
79 int32_t logicalScreenHeight = static_cast<int32_t>(node.GetRenderProperties().GetFrameHeight());
80 if (logicalScreenWidth <= 0 || logicalScreenHeight <= 0) {
81 logicalScreenWidth = static_cast<int32_t>(curScreenInfo.width);
82 logicalScreenHeight = static_cast<int32_t>(curScreenInfo.height);
83 }
84
85 if (node.IsMirrorScreen()) {
86 auto mirrorSource = node.GetMirrorSource();
87 auto existingSource = mirrorSource.lock();
88 if (!existingSource) {
89 RS_LOGI("PrepareScreenRenderNode mirrorSource haven't existed");
90 return;
91 }
92 if (mParallelEnable) {
93 CreateCanvas(logicalScreenWidth, logicalScreenHeight, true);
94 }
95 PrepareChildren(*existingSource);
96 } else {
97 auto& boundsGeoPtr = (node.GetRenderProperties().GetBoundsGeometry());
98 RSBaseRenderUtil::SetNeedClient(boundsGeoPtr && boundsGeoPtr->IsNeedClientCompose());
99 CreateCanvas(logicalScreenWidth, logicalScreenHeight);
100 PrepareChildren(node);
101 }
102 node.GetCurAllSurfaces().clear();
103 node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(), false, false);
104 }
105
PrepareLogicalDisplayRenderNode(RSLogicalDisplayRenderNode & node)106 void RSRenderServiceVisitor::PrepareLogicalDisplayRenderNode(RSLogicalDisplayRenderNode& node)
107 {
108 PrepareChildren(node);
109 }
110
ProcessScreenRenderNode(RSScreenRenderNode & node)111 void RSRenderServiceVisitor::ProcessScreenRenderNode(RSScreenRenderNode& node)
112 {
113 // need reset isSecurityDisplay_ on ProcessScreenRenderNode
114 RS_LOGD("RsDebug ProcessScreenRenderNode: nodeid:[%{public}" PRIu64 "]"
115 " screenid:[%{public}" PRIu64 "] isSecurityDisplay:[%{public}s] child size:[%{public}d]",
116 node.GetId(), node.GetScreenId(), isSecurityDisplay_ ? "true" : "false", node.GetChildrenCount());
117 globalZOrder_ = 0.0f;
118 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
119 if (!screenManager) {
120 RS_LOGE("ProcessScreenRenderNode ScreenManager is nullptr");
121 return;
122 }
123 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
124 RS_TRACE_NAME("ProcessScreenRenderNode[" + std::to_string(node.GetScreenId()) + "]");
125 RSScreenModeInfo modeInfo = {};
126 screenManager->GetDefaultScreenActiveMode(modeInfo);
127 uint32_t refreshRate = modeInfo.GetScreenRefreshRate();
128 screenManager->RemoveForceRefreshTask();
129 // skip frame according to skipFrameInterval value of SetScreenSkipFrameInterval interface
130 if (node.SkipFrame(refreshRate, curScreenInfo.skipFrameInterval)) {
131 RS_TRACE_NAME("SkipFrame, screenId:" + std::to_string(node.GetScreenId()));
132 screenManager->PostForceRefreshTask();
133 return;
134 }
135
136 curScreenNode_ = node.shared_from_this()->ReinterpretCastTo<RSScreenRenderNode>();
137
138 if (!CreateProcessor(node)) {
139 return;
140 }
141
142 if (node.IsMirrorScreen()) {
143 auto mirrorSource = node.GetMirrorSource();
144 auto existingSource = mirrorSource.lock();
145 if (!existingSource) {
146 RS_LOGI("ProcessScreenRenderNode mirrorSource haven't existed");
147 return;
148 }
149 if (isSecurityDisplay_ && displayHasSecSurface_[node.GetScreenId()]) {
150 processor_->SetSecurityDisplay(isSecurityDisplay_);
151 processor_->SetDisplayHasSecSurface(true);
152 processor_->PostProcess();
153 return;
154 }
155 ProcessChildren(*existingSource);
156 } else {
157 ProcessChildren(node);
158 }
159 processor_->PostProcess();
160 }
161
ProcessLogicalDisplayRenderNode(RSLogicalDisplayRenderNode & node)162 void RSRenderServiceVisitor::ProcessLogicalDisplayRenderNode(RSLogicalDisplayRenderNode& node)
163 {
164 ProcessChildren(node);
165 for (auto& [_, funcs] : foregroundSurfaces_) {
166 for (const auto& func : funcs) {
167 func();
168 }
169 }
170 foregroundSurfaces_.clear();
171 }
172
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)173 void RSRenderServiceVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
174 {
175 if (RSInnovation::GetParallelCompositionEnabled(false)) {
176 typedef bool (*CheckForSerialForcedFunc)(std::string&);
177 CheckForSerialForcedFunc CheckForSerialForced =
178 reinterpret_cast<CheckForSerialForcedFunc>(RSInnovation::_s_checkForSerialForced);
179 auto name = node.GetName();
180 mForceSerial |= CheckForSerialForced(name);
181 }
182
183 if (isSecurityDisplay_ && node.GetSpecialLayerMgr().Find(SpecialLayerType::SECURITY)) {
184 displayHasSecSurface_[currentVisitDisplay_] = true;
185 RS_LOGI("PrepareSurfaceRenderNode node: [%{public}" PRIu64 "] prepare paused "
186 "because of security SurfaceNode.", node.GetId());
187 return;
188 }
189
190 if (isSecurityDisplay_ && node.GetSpecialLayerMgr().Find(SpecialLayerType::SKIP)) {
191 RS_LOGD("PrepareSurfaceRenderNode node : [%{public}" PRIu64 "] prepare paused "
192 "because of skip SurfaceNode.", node.GetId());
193 return;
194 }
195 if (!canvas_) {
196 RS_LOGD("PrepareSurfaceRenderNode node : %{public}" PRIu64 " canvas is nullptr",
197 node.GetId());
198 return;
199 }
200 if (!node.ShouldPaint()) {
201 RS_LOGD("PrepareSurfaceRenderNode node : %{public}" PRIu64 " is invisible",
202 node.GetId());
203 return;
204 }
205
206 node.SetVisibleRegion(Occlusion::Region());
207 node.SetOffset(offsetX_, offsetY_);
208 node.PrepareRenderBeforeChildren(*canvas_);
209 PrepareChildren(node);
210 node.PrepareRenderAfterChildren(*canvas_);
211
212 if (curScreenNode_) {
213 StoreSurfaceNodeAttrsToScreenNode(*curScreenNode_, node);
214 }
215 }
216
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)217 void RSRenderServiceVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
218 {
219 if (!processor_) {
220 RS_LOGE("ProcessSurfaceRenderNode processor is nullptr");
221 return;
222 }
223
224 if (curScreenNode_) {
225 RestoreSurfaceNodeAttrsFromScreenNode(*curScreenNode_, node);
226 node.SetOffset(curScreenNode_->GetScreenOffsetX(), curScreenNode_->GetScreenOffsetY());
227 }
228
229 if (!node.ShouldPaint()) {
230 RS_LOGD("ProcessSurfaceRenderNode node : %{public}" PRIu64 " is invisible",
231 node.GetId());
232 return;
233 }
234 if (!node.GetOcclusionVisible() && !doAnimate_ && RSSystemProperties::GetOcclusionEnabled()) {
235 return;
236 }
237 if (isSecurityDisplay_ && node.GetMultableSpecialLayerMgr().Find(SpecialLayerType::SKIP)) {
238 RS_LOGD("ProcessSurfaceRenderNode node[%{public}" PRIu64 "] process paused "
239 "because of skip SurfaceNode.", node.GetId());
240 return;
241 }
242 if (mParallelEnable) {
243 node.ParallelVisitLock();
244 }
245 ProcessChildren(node);
246 auto func = [nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>(), this]() {
247 nodePtr->GetMutableRSSurfaceHandler()->SetGlobalZOrder(globalZOrder_);
248 globalZOrder_ = globalZOrder_ + 1;
249 processor_->ProcessSurface(*nodePtr);
250 };
251 if (node.GetIsForeground()) {
252 auto parent = node.GetParent().lock();
253 foregroundSurfaces_[parent ? parent->GetId() : 0].push_back(func);
254 } else {
255 func();
256 }
257 auto it = foregroundSurfaces_.find(node.GetId());
258 if (it != foregroundSurfaces_.end()) {
259 for (auto f : foregroundSurfaces_[node.GetId()]) {
260 f();
261 }
262 foregroundSurfaces_.erase(it);
263 }
264 RSBaseRenderUtil::WriteSurfaceRenderNodeToPng(node);
265 if (mParallelEnable) {
266 node.ParallelVisitUnlock();
267 }
268 }
269
CreateCanvas(int32_t width,int32_t height,bool isMirrored)270 void RSRenderServiceVisitor::CreateCanvas(int32_t width, int32_t height, bool isMirrored)
271 {
272 drawingCanvas_ = std::make_unique<Drawing::Canvas>(width, height);
273 canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas_.get());
274 Drawing::Rect tmpRect(0, 0, width, height);
275 canvas_->ClipRect(tmpRect, Drawing::ClipOp::INTERSECT, false);
276 if (!isMirrored) {
277 Drawing::Matrix matrix;
278 matrix.Translate(offsetX_ * -1, offsetY_ * -1);
279 canvas_->SetMatrix(matrix);
280 }
281 }
282
CreateProcessor(RSScreenRenderNode & node)283 bool RSRenderServiceVisitor::CreateProcessor(RSScreenRenderNode& node)
284 {
285 processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType());
286 if (processor_ == nullptr) {
287 RS_LOGE("CreateProcessor: processor_ is null!");
288 return false;
289 }
290
291 auto mirrorNode = node.GetMirrorSource().lock();
292
293 auto mainThread = RSMainThread::Instance();
294 if (mainThread != nullptr) {
295 processorRenderEngine_ = mainThread->GetRenderEngine();
296 }
297
298 if (!processor_->Init(node, node.GetScreenOffsetX(), node.GetScreenOffsetY(),
299 mirrorNode ? mirrorNode->GetScreenId() : INVALID_SCREEN_ID, processorRenderEngine_)) {
300 RS_LOGE("ProcessDisplayRenderNode: processor init failed!");
301 return false;
302 }
303
304 return true;
305 }
306
UpdateScreenNodeCompositeType(RSScreenRenderNode & node,const ScreenInfo & screenInfo)307 void RSRenderServiceVisitor::UpdateScreenNodeCompositeType(RSScreenRenderNode& node, const ScreenInfo& screenInfo)
308 {
309 ScreenState state = screenInfo.state;
310 switch (state) {
311 case ScreenState::SOFTWARE_OUTPUT_ENABLE:
312 node.SetCompositeType(CompositeType::SOFTWARE_COMPOSITE);
313 break;
314 case ScreenState::HDI_OUTPUT_ENABLE:
315 node.SetCompositeType(node.IsForceSoftComposite() ?
316 CompositeType::SOFTWARE_COMPOSITE:
317 CompositeType::HARDWARE_COMPOSITE);
318 break;
319 default:
320 RS_LOGE("PrepareDisplayRenderNode State is unusual");
321 return;
322 }
323 }
324
StoreSurfaceNodeAttrsToScreenNode(RSScreenRenderNode & screenNode,const RSSurfaceRenderNode & surfaceNode)325 void RSRenderServiceVisitor::StoreSurfaceNodeAttrsToScreenNode(
326 RSScreenRenderNode& screenNode, const RSSurfaceRenderNode& surfaceNode)
327 {
328 screenNode.SetSurfaceSrcRect(surfaceNode.GetId(), surfaceNode.GetSrcRect());
329 screenNode.SetSurfaceDstRect(surfaceNode.GetId(), surfaceNode.GetDstRect());
330 screenNode.SetSurfaceTotalMatrix(surfaceNode.GetId(), surfaceNode.GetTotalMatrix());
331 }
332
RestoreSurfaceNodeAttrsFromScreenNode(const RSScreenRenderNode & screenNode,RSSurfaceRenderNode & surfaceNode)333 void RSRenderServiceVisitor::RestoreSurfaceNodeAttrsFromScreenNode(
334 const RSScreenRenderNode& screenNode, RSSurfaceRenderNode& surfaceNode)
335 {
336 surfaceNode.SetSrcRect(screenNode.GetSurfaceSrcRect(surfaceNode.GetId()));
337 surfaceNode.SetDstRect(screenNode.GetSurfaceDstRect(surfaceNode.GetId()));
338 surfaceNode.SetTotalMatrix(screenNode.GetSurfaceTotalMatrix(surfaceNode.GetId()));
339 }
340
ResetSurfaceNodeAttrsInScreenNode(RSScreenRenderNode & screenNode)341 void RSRenderServiceVisitor::ResetSurfaceNodeAttrsInScreenNode(RSScreenRenderNode& screenNode)
342 {
343 screenNode.ClearSurfaceSrcRect();
344 screenNode.ClearSurfaceDstRect();
345 screenNode.ClearSurfaceTotalMatrix();
346 }
347
348 } // namespace Rosen
349 } // namespace OHOS
350