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