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