• 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 "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