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 #ifndef USE_ROSEN_DRAWING
19 #include "include/core/SkCanvas.h"
20 #include "include/core/SkPoint.h"
21 #include "include/core/SkRect.h"
22 #endif
23 #include "rs_divided_render_util.h"
24 #include "rs_trace.h"
25
26 #include "common/rs_obj_abs_geometry.h"
27 #include "pipeline/rs_main_thread.h"
28 #include "pipeline/rs_base_render_node.h"
29 #include "pipeline/rs_display_render_node.h"
30 #include "pipeline/rs_processor.h"
31 #include "pipeline/rs_processor_factory.h"
32 #include "pipeline/rs_surface_render_node.h"
33 #include "platform/common/rs_log.h"
34 #include "platform/common/rs_innovation.h"
35 #ifdef NEW_RENDER_CONTEXT
36 #include "rs_render_surface.h"
37 #else
38 #include "platform/drawing/rs_surface.h"
39 #endif
40 #include "screen_manager/rs_screen_manager.h"
41 #include "screen_manager/screen_types.h"
42
43 namespace OHOS {
44 namespace Rosen {
45
RSRenderServiceVisitor(bool parallel)46 RSRenderServiceVisitor::RSRenderServiceVisitor(bool parallel) : mParallelEnable(parallel) {}
47
~RSRenderServiceVisitor()48 RSRenderServiceVisitor::~RSRenderServiceVisitor() {}
49
PrepareChildren(RSRenderNode & node)50 void RSRenderServiceVisitor::PrepareChildren(RSRenderNode& node)
51 {
52 for (auto& child : *node.GetSortedChildren()) {
53 child->Prepare(shared_from_this());
54 }
55 }
56
ProcessChildren(RSRenderNode & node)57 void RSRenderServiceVisitor::ProcessChildren(RSRenderNode& node)
58 {
59 for (auto& child : *node.GetSortedChildren()) {
60 child->Process(shared_from_this());
61 }
62 }
63
PrepareDisplayRenderNode(RSDisplayRenderNode & node)64 void RSRenderServiceVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode& node)
65 {
66 isSecurityDisplay_ = node.GetSecurityDisplay();
67 currentVisitDisplay_ = node.GetScreenId();
68 displayHasSecSurface_.emplace(currentVisitDisplay_, false);
69 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
70 if (!screenManager) {
71 RS_LOGE("RSRenderServiceVisitor::PrepareDisplayRenderNode ScreenManager is nullptr");
72 return;
73 }
74 offsetX_ = node.GetDisplayOffsetX();
75 offsetY_ = node.GetDisplayOffsetY();
76 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
77 ScreenState state = curScreenInfo.state;
78 switch (state) {
79 case ScreenState::PRODUCER_SURFACE_ENABLE:
80 node.SetCompositeType(RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE);
81 break;
82 case ScreenState::HDI_OUTPUT_ENABLE:
83 node.SetCompositeType(node.IsForceSoftComposite() ?
84 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE:
85 RSDisplayRenderNode::CompositeType::HARDWARE_COMPOSITE);
86 break;
87 default:
88 RS_LOGE("RSRenderServiceVisitor::PrepareDisplayRenderNode State is unusual");
89 return;
90 }
91
92 ScreenRotation rotation = node.GetRotation();
93 int32_t logicalScreenWidth = static_cast<int32_t>(node.GetRenderProperties().GetFrameWidth());
94 int32_t logicalScreenHeight = static_cast<int32_t>(node.GetRenderProperties().GetFrameHeight());
95 if (logicalScreenWidth <= 0 || logicalScreenHeight <= 0) {
96 logicalScreenWidth = static_cast<int32_t>(curScreenInfo.width);
97 logicalScreenHeight = static_cast<int32_t>(curScreenInfo.height);
98 if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
99 std::swap(logicalScreenWidth, logicalScreenHeight);
100 }
101 }
102
103 if (node.IsMirrorDisplay()) {
104 auto mirrorSource = node.GetMirrorSource();
105 auto existingSource = mirrorSource.lock();
106 if (!existingSource) {
107 RS_LOGI("RSRenderServiceVisitor::PrepareDisplayRenderNode mirrorSource haven't existed");
108 return;
109 }
110 if (mParallelEnable) {
111 #ifndef USE_ROSEN_DRAWING
112 skCanvas_ = std::make_unique<SkCanvas>(logicalScreenWidth, logicalScreenHeight);
113 canvas_ = std::make_shared<RSPaintFilterCanvas>(skCanvas_.get());
114 canvas_->clipRect(SkRect::MakeWH(logicalScreenWidth, logicalScreenHeight));
115 #else
116 drawingCanvas_ = std::make_unique<Drawing::Canvas>(logicalScreenWidth, logicalScreenHeight);
117 canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas_.get());
118 Drawing::Rect tmpRect(0, 0, logicalScreenWidth, logicalScreenHeight);
119 canvas_->ClipRect(tmpRect, Drawing::ClipOp::INTERSECT, false);
120 #endif
121 }
122 PrepareChildren(*existingSource);
123 } else {
124 auto boundsGeoPtr = (node.GetRenderProperties().GetBoundsGeometry());
125 RSBaseRenderUtil::SetNeedClient(boundsGeoPtr && boundsGeoPtr->IsNeedClientCompose());
126 #ifndef USE_ROSEN_DRAWING
127 skCanvas_ = std::make_unique<SkCanvas>(logicalScreenWidth, logicalScreenHeight);
128 canvas_ = std::make_shared<RSPaintFilterCanvas>(skCanvas_.get());
129 canvas_->clipRect(SkRect::MakeWH(logicalScreenWidth, logicalScreenHeight));
130 #else
131 drawingCanvas_ = std::make_unique<Drawing::Canvas>(logicalScreenWidth, logicalScreenHeight);
132 canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas_.get());
133 Drawing::Rect tmpRect(0, 0, logicalScreenWidth, logicalScreenHeight);
134 canvas_->ClipRect(tmpRect, Drawing::ClipOp::INTERSECT, false);
135 #endif
136 PrepareChildren(node);
137 }
138
139 node.GetCurAllSurfaces().clear();
140 node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(), false, false);
141 }
142
ProcessDisplayRenderNode(RSDisplayRenderNode & node)143 void RSRenderServiceVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
144 {
145 /* need reset isSecurityDisplay_ on ProcessDisplayRenderNode */
146 isSecurityDisplay_ = node.GetSecurityDisplay();
147 RS_LOGD("RsDebug RSRenderServiceVisitor::ProcessDisplayRenderNode: nodeid:[%{public}" PRIu64 "]"
148 " screenid:[%{public}" PRIu64 "] \
149 isSecurityDisplay:[%{public}s] child size:[%{public}d]",
150 node.GetId(), node.GetScreenId(), isSecurityDisplay_ ? "true" : "false", node.GetChildrenCount());
151 globalZOrder_ = 0.0f;
152 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
153 if (!screenManager) {
154 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode ScreenManager is nullptr");
155 return;
156 }
157 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
158 RS_TRACE_NAME("ProcessDisplayRenderNode[" + std::to_string(node.GetScreenId()) + "]");
159 // skip frame according to skipFrameInterval value of SetScreenSkipFrameInterval interface
160 if (node.SkipFrame(curScreenInfo.skipFrameInterval)) {
161 return;
162 }
163 processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType());
164 if (processor_ == nullptr) {
165 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode: RSProcessor is null!");
166 return;
167 }
168 auto mirrorNode = node.GetMirrorSource().lock();
169
170 auto mainThread = RSMainThread::Instance();
171 if (mainThread != nullptr) {
172 processorRenderEngine_ = mainThread->GetRenderEngine();
173 }
174 if (!processor_->Init(node, node.GetDisplayOffsetX(), node.GetDisplayOffsetY(),
175 mirrorNode ? mirrorNode->GetScreenId() : INVALID_SCREEN_ID, processorRenderEngine_)) {
176 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode: processor init failed!");
177 return;
178 }
179
180 if (node.IsMirrorDisplay()) {
181 auto mirrorSource = node.GetMirrorSource();
182 auto existingSource = mirrorSource.lock();
183 if (!existingSource) {
184 RS_LOGI("RSRenderServiceVisitor::ProcessDisplayRenderNode mirrorSource haven't existed");
185 return;
186 }
187 if (isSecurityDisplay_ && displayHasSecSurface_[node.GetScreenId()]) {
188 processor_->SetSecurityDisplay(isSecurityDisplay_);
189 processor_->SetDisplayHasSecSurface(true);
190 processor_->PostProcess();
191 return;
192 }
193 ProcessChildren(*existingSource);
194 } else {
195 ProcessChildren(node);
196 }
197 for (auto& [_, funcs] : foregroundSurfaces_) {
198 for (const auto& func : funcs) {
199 func();
200 }
201 }
202 foregroundSurfaces_.clear();
203 processor_->PostProcess();
204 }
205
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)206 void RSRenderServiceVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
207 {
208 if (RSInnovation::GetParallelCompositionEnabled(false)) {
209 typedef bool (*CheckForSerialForcedFunc)(std::string&);
210 CheckForSerialForcedFunc CheckForSerialForced =
211 reinterpret_cast<CheckForSerialForcedFunc>(RSInnovation::_s_checkForSerialForced);
212 auto name = node.GetName();
213 mForceSerial |= CheckForSerialForced(name);
214 }
215
216 if (isSecurityDisplay_ && node.GetSecurityLayer()) {
217 displayHasSecSurface_[currentVisitDisplay_] = true;
218 RS_LOGI("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : [%{public}" PRIu64 "] prepare paused \
219 because of security SurfaceNode.", node.GetId());
220 return;
221 }
222
223 if (isSecurityDisplay_ && node.GetSkipLayer()) {
224 RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : [%{public}" PRIu64 "] prepare paused \
225 because of skip SurfaceNode.", node.GetId());
226 return;
227 }
228 if (!canvas_) {
229 RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : %{public}" PRIu64 " canvas is nullptr",
230 node.GetId());
231 return;
232 }
233 if (!node.ShouldPaint()) {
234 RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : %{public}" PRIu64 " is invisible",
235 node.GetId());
236 return;
237 }
238 node.SetOffset(offsetX_, offsetY_);
239 node.PrepareRenderBeforeChildren(*canvas_);
240 PrepareChildren(node);
241 node.PrepareRenderAfterChildren(*canvas_);
242 }
243
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)244 void RSRenderServiceVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
245 {
246 if (!processor_) {
247 RS_LOGE("RSRenderServiceVisitor::ProcessSurfaceRenderNode processor is nullptr");
248 return;
249 }
250
251 if (!node.ShouldPaint()) {
252 RS_LOGD("RSRenderServiceVisitor::ProcessSurfaceRenderNode node : %{public}" PRIu64 " is invisible",
253 node.GetId());
254 return;
255 }
256 if (!node.GetOcclusionVisible() && !doAnimate_ && RSSystemProperties::GetOcclusionEnabled()) {
257 return;
258 }
259 if (isSecurityDisplay_ && node.GetSkipLayer()) {
260 RS_LOGD("RSRenderServiceVisitor::ProcessSurfaceRenderNode node[%{public}" PRIu64 "] process paused \
261 because of skip SurfaceNode.", node.GetId());
262 return;
263 }
264 if (mParallelEnable) {
265 node.ParallelVisitLock();
266 }
267 ProcessChildren(node);
268 auto func = [nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>(), this]() {
269 nodePtr->SetGlobalZOrder(globalZOrder_);
270 globalZOrder_ = globalZOrder_ + 1;
271 processor_->ProcessSurface(*nodePtr);
272 };
273 if (node.GetIsForeground()) {
274 auto parent = node.GetParent().lock();
275 foregroundSurfaces_[parent ? parent->GetId() : 0].push_back(func);
276 } else {
277 func();
278 }
279 auto it = foregroundSurfaces_.find(node.GetId());
280 if (it != foregroundSurfaces_.end()) {
281 for (auto f : foregroundSurfaces_[node.GetId()]) {
282 f();
283 }
284 foregroundSurfaces_.erase(it);
285 }
286 RSBaseRenderUtil::WriteSurfaceRenderNodeToPng(node);
287 if (mParallelEnable) {
288 node.ParallelVisitUnlock();
289 }
290 }
291 } // namespace Rosen
292 } // namespace OHOS
293