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