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     ScreenState state = curScreenInfo.state;
73     switch (state) {
74         case ScreenState::PRODUCER_SURFACE_ENABLE:
75             node.SetCompositeType(RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE);
76             break;
77         case ScreenState::HDI_OUTPUT_ENABLE:
78             node.SetCompositeType(node.IsForceSoftComposite() ?
79                 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE:
80                 RSDisplayRenderNode::CompositeType::HARDWARE_COMPOSITE);
81             break;
82         default:
83             RS_LOGE("RSRenderServiceVisitor::PrepareDisplayRenderNode State is unusual");
84             return;
85     }
86 
87     ScreenRotation rotation = node.GetRotation();
88     int32_t logicalScreenWidth = static_cast<int32_t>(node.GetRenderProperties().GetFrameWidth());
89     int32_t logicalScreenHeight = static_cast<int32_t>(node.GetRenderProperties().GetFrameHeight());
90     if (logicalScreenWidth <= 0 || logicalScreenHeight <= 0) {
91         logicalScreenWidth = static_cast<int32_t>(curScreenInfo.width);
92         logicalScreenHeight = static_cast<int32_t>(curScreenInfo.height);
93         if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
94             std::swap(logicalScreenWidth, logicalScreenHeight);
95         }
96     }
97 
98     if (node.IsMirrorDisplay()) {
99         auto mirrorSource = node.GetMirrorSource();
100         auto existingSource = mirrorSource.lock();
101         if (!existingSource) {
102             RS_LOGI("RSRenderServiceVisitor::PrepareDisplayRenderNode mirrorSource haven't existed");
103             return;
104         }
105         if (mParallelEnable) {
106             drawingCanvas_ = std::make_unique<Drawing::Canvas>(logicalScreenWidth, logicalScreenHeight);
107             canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas_.get());
108             Drawing::Rect tmpRect(0, 0, logicalScreenWidth, logicalScreenHeight);
109             canvas_->ClipRect(tmpRect, Drawing::ClipOp::INTERSECT, false);
110         }
111         PrepareChildren(*existingSource);
112     } else {
113         auto& boundsGeoPtr = (node.GetRenderProperties().GetBoundsGeometry());
114         RSBaseRenderUtil::SetNeedClient(boundsGeoPtr && boundsGeoPtr->IsNeedClientCompose());
115         drawingCanvas_ = std::make_unique<Drawing::Canvas>(logicalScreenWidth, logicalScreenHeight);
116         canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas_.get());
117         Drawing::Rect tmpRect(0, 0, logicalScreenWidth, logicalScreenHeight);
118         canvas_->ClipRect(tmpRect, Drawing::ClipOp::INTERSECT, false);
119         PrepareChildren(node);
120     }
121 
122     node.GetCurAllSurfaces().clear();
123     node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(), false, false);
124 }
125 
ProcessDisplayRenderNode(RSDisplayRenderNode & node)126 void RSRenderServiceVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
127 {
128     /* need reset isSecurityDisplay_ on ProcessDisplayRenderNode */
129     isSecurityDisplay_ = node.GetSecurityDisplay();
130     RS_LOGD("RsDebug RSRenderServiceVisitor::ProcessDisplayRenderNode: nodeid:[%{public}" PRIu64 "]"
131         " screenid:[%{public}" PRIu64 "] \
132         isSecurityDisplay:[%{public}s] child size:[%{public}d]",
133         node.GetId(), node.GetScreenId(), isSecurityDisplay_ ? "true" : "false", node.GetChildrenCount());
134     globalZOrder_ = 0.0f;
135     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
136     if (!screenManager) {
137         RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode ScreenManager is nullptr");
138         return;
139     }
140     ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
141     RS_TRACE_NAME("ProcessDisplayRenderNode[" + std::to_string(node.GetScreenId()) + "]");
142     RSScreenModeInfo modeInfo = {};
143     ScreenId defaultScreenId = screenManager->GetDefaultScreenId();
144     screenManager->GetScreenActiveMode(defaultScreenId, modeInfo);
145     uint32_t refreshRate = modeInfo.GetScreenRefreshRate();
146     // skip frame according to skipFrameInterval value of SetScreenSkipFrameInterval interface
147     if (node.SkipFrame(refreshRate, curScreenInfo.skipFrameInterval)) {
148         RS_TRACE_NAME("SkipFrame, screenId:" + std::to_string(node.GetScreenId()));
149         screenManager->ForceRefreshOneFrameIfNoRNV();
150         return;
151     }
152     processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType());
153     if (processor_ == nullptr) {
154         RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode: RSProcessor is null!");
155         return;
156     }
157     auto mirrorNode = node.GetMirrorSource().lock();
158 
159     auto mainThread = RSMainThread::Instance();
160     if (mainThread != nullptr) {
161         processorRenderEngine_ = mainThread->GetRenderEngine();
162     }
163     if (!processor_->Init(node, node.GetDisplayOffsetX(), node.GetDisplayOffsetY(),
164         mirrorNode ? mirrorNode->GetScreenId() : INVALID_SCREEN_ID, processorRenderEngine_)) {
165         RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode: processor init failed!");
166         return;
167     }
168 
169     if (node.IsMirrorDisplay()) {
170         auto mirrorSource = node.GetMirrorSource();
171         auto existingSource = mirrorSource.lock();
172         if (!existingSource) {
173             RS_LOGI("RSRenderServiceVisitor::ProcessDisplayRenderNode mirrorSource haven't existed");
174             return;
175         }
176         if (isSecurityDisplay_ && displayHasSecSurface_[node.GetScreenId()]) {
177             processor_->SetSecurityDisplay(isSecurityDisplay_);
178             processor_->SetDisplayHasSecSurface(true);
179             processor_->PostProcess();
180             return;
181         }
182         ProcessChildren(*existingSource);
183     } else {
184         ProcessChildren(node);
185     }
186     for (auto& [_, funcs] : foregroundSurfaces_) {
187         for (const auto& func : funcs) {
188             func();
189         }
190     }
191     foregroundSurfaces_.clear();
192     processor_->PostProcess();
193 }
194 
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)195 void RSRenderServiceVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
196 {
197     if (RSInnovation::GetParallelCompositionEnabled(false)) {
198         typedef bool (*CheckForSerialForcedFunc)(std::string&);
199         CheckForSerialForcedFunc CheckForSerialForced =
200             reinterpret_cast<CheckForSerialForcedFunc>(RSInnovation::_s_checkForSerialForced);
201         auto name = node.GetName();
202         mForceSerial |= CheckForSerialForced(name);
203     }
204 
205     if (isSecurityDisplay_ && node.GetSecurityLayer()) {
206         displayHasSecSurface_[currentVisitDisplay_] = true;
207         RS_LOGI("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : [%{public}" PRIu64 "] prepare paused \
208             because of security SurfaceNode.", node.GetId());
209         return;
210     }
211 
212     if (isSecurityDisplay_ && node.GetSkipLayer()) {
213         RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : [%{public}" PRIu64 "] prepare paused \
214             because of skip SurfaceNode.", node.GetId());
215         return;
216     }
217     if (!canvas_) {
218         RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : %{public}" PRIu64 " canvas is nullptr",
219             node.GetId());
220         return;
221     }
222     if (!node.ShouldPaint()) {
223         RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : %{public}" PRIu64 " is invisible",
224             node.GetId());
225         return;
226     }
227     node.SetOffset(offsetX_, offsetY_);
228     node.PrepareRenderBeforeChildren(*canvas_);
229     PrepareChildren(node);
230     node.PrepareRenderAfterChildren(*canvas_);
231 }
232 
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)233 void RSRenderServiceVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
234 {
235     if (!processor_) {
236         RS_LOGE("RSRenderServiceVisitor::ProcessSurfaceRenderNode processor is nullptr");
237         return;
238     }
239 
240     if (!node.ShouldPaint()) {
241         RS_LOGD("RSRenderServiceVisitor::ProcessSurfaceRenderNode node : %{public}" PRIu64 " is invisible",
242             node.GetId());
243         return;
244     }
245     if (!node.GetOcclusionVisible() && !doAnimate_ && RSSystemProperties::GetOcclusionEnabled()) {
246         return;
247     }
248     if (isSecurityDisplay_ && node.GetSkipLayer()) {
249         RS_LOGD("RSRenderServiceVisitor::ProcessSurfaceRenderNode node[%{public}" PRIu64 "] process paused \
250             because of skip SurfaceNode.", node.GetId());
251         return;
252     }
253     if (mParallelEnable) {
254         node.ParallelVisitLock();
255     }
256     ProcessChildren(node);
257     auto func = [nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>(), this]() {
258         nodePtr->GetMutableRSSurfaceHandler()->SetGlobalZOrder(globalZOrder_);
259         globalZOrder_ = globalZOrder_ + 1;
260         processor_->ProcessSurface(*nodePtr);
261     };
262     if (node.GetIsForeground()) {
263         auto parent = node.GetParent().lock();
264         foregroundSurfaces_[parent ? parent->GetId() : 0].push_back(func);
265     } else {
266         func();
267     }
268     auto it = foregroundSurfaces_.find(node.GetId());
269     if (it != foregroundSurfaces_.end()) {
270         for (auto f : foregroundSurfaces_[node.GetId()]) {
271             f();
272         }
273         foregroundSurfaces_.erase(it);
274     }
275     RSBaseRenderUtil::WriteSurfaceRenderNodeToPng(node);
276     if (mParallelEnable) {
277         node.ParallelVisitUnlock();
278     }
279 }
280 } // namespace Rosen
281 } // namespace OHOS
282