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 node.ApplyChildrenModifiers();
53 for (auto& child : node.GetSortedChildren()) {
54 child->Prepare(shared_from_this());
55 }
56 }
57
ProcessChildren(RSRenderNode & node)58 void RSRenderServiceVisitor::ProcessChildren(RSRenderNode& node)
59 {
60 for (auto& child : node.GetSortedChildren()) {
61 child->Process(shared_from_this());
62 }
63 }
64
PrepareDisplayRenderNode(RSDisplayRenderNode & node)65 void RSRenderServiceVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode& node)
66 {
67 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
68 if (!screenManager) {
69 RS_LOGE("RSRenderServiceVisitor::PrepareDisplayRenderNode ScreenManager is nullptr");
70 return;
71 }
72 offsetX_ = node.GetDisplayOffsetX();
73 offsetY_ = node.GetDisplayOffsetY();
74 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
75 ScreenState state = curScreenInfo.state;
76 switch (state) {
77 case ScreenState::PRODUCER_SURFACE_ENABLE:
78 node.SetCompositeType(RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE);
79 break;
80 case ScreenState::HDI_OUTPUT_ENABLE:
81 node.SetCompositeType(node.IsForceSoftComposite() ?
82 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE:
83 RSDisplayRenderNode::CompositeType::HARDWARE_COMPOSITE);
84 break;
85 default:
86 RS_LOGE("RSRenderServiceVisitor::PrepareDisplayRenderNode State is unusual");
87 return;
88 }
89
90 ScreenRotation rotation = node.GetRotation();
91 int32_t logicalScreenWidth = static_cast<int32_t>(node.GetRenderProperties().GetFrameWidth());
92 int32_t logicalScreenHeight = static_cast<int32_t>(node.GetRenderProperties().GetFrameHeight());
93
94 if (logicalScreenWidth <= 0 || logicalScreenHeight <= 0) {
95 logicalScreenWidth = static_cast<int32_t>(curScreenInfo.width);
96 logicalScreenHeight = static_cast<int32_t>(curScreenInfo.height);
97
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 Drawing::Bitmap bitmapTmp;
117 Drawing::BitmapFormat formatTmp { Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL };
118 bitmapTmp.Build(logicalScreenWidth, logicalScreenHeight, formatTmp);
119 drawingCanvas_ = std::make_unique<Drawing::Canvas>();
120 drawingCanvas_->Bind(bitmapTmp);
121 canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas_.get());
122 Drawing::Rect tmpRect(0, 0, logicalScreenWidth, logicalScreenHeight);
123 canvas_->ClipRect(tmpRect, Drawing::ClipOp::INTERSECT, false);
124 #endif
125 }
126 PrepareChildren(*existingSource);
127 } else {
128 auto boundsGeoPtr = (node.GetRenderProperties().GetBoundsGeometry());
129 RSBaseRenderUtil::SetNeedClient(boundsGeoPtr && boundsGeoPtr->IsNeedClientCompose());
130 #ifndef USE_ROSEN_DRAWING
131 skCanvas_ = std::make_unique<SkCanvas>(logicalScreenWidth, logicalScreenHeight);
132 canvas_ = std::make_shared<RSPaintFilterCanvas>(skCanvas_.get());
133 canvas_->clipRect(SkRect::MakeWH(logicalScreenWidth, logicalScreenHeight));
134 #else
135 Drawing::Bitmap bitmap;
136 Drawing::BitmapFormat format { Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL };
137 bitmap.Build(logicalScreenWidth, logicalScreenHeight, format);
138 drawingCanvas_ = std::make_unique<Drawing::Canvas>();
139 drawingCanvas_->Bind(bitmap);
140 canvas_ = std::make_shared<RSPaintFilterCanvas>(drawingCanvas_.get());
141 Drawing::Rect tmpRect(0, 0, logicalScreenWidth, logicalScreenHeight);
142 canvas_->ClipRect(tmpRect, Drawing::ClipOp::INTERSECT, false);
143 #endif
144 PrepareChildren(node);
145 }
146
147 node.GetCurAllSurfaces().clear();
148 node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(), false, false);
149 }
150
ProcessDisplayRenderNode(RSDisplayRenderNode & node)151 void RSRenderServiceVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
152 {
153 isSecurityDisplay_ = node.GetSecurityDisplay();
154 RS_LOGD("RsDebug RSRenderServiceVisitor::ProcessDisplayRenderNode: nodeid:[%" PRIu64 "] screenid:[%" PRIu64 "] \
155 isSecurityDisplay:[%s] child size:[%d] total size:[%d]",
156 node.GetId(), node.GetScreenId(), isSecurityDisplay_ ? "true" : "false", node.GetChildrenCount(),
157 node.GetSortedChildren().size());
158 globalZOrder_ = 0.0f;
159 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
160 if (!screenManager) {
161 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode ScreenManager is nullptr");
162 return;
163 }
164 ScreenInfo curScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
165 RS_TRACE_NAME("ProcessDisplayRenderNode[" + std::to_string(node.GetScreenId()) + "]");
166 // skip frame according to skipFrameInterval value of SetScreenSkipFrameInterval interface
167 if (node.SkipFrame(curScreenInfo.skipFrameInterval)) {
168 return;
169 }
170 processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType());
171 if (processor_ == nullptr) {
172 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode: RSProcessor is null!");
173 return;
174 }
175 auto mirrorNode = node.GetMirrorSource().lock();
176
177 auto mainThread = RSMainThread::Instance();
178 if (mainThread != nullptr) {
179 processorRenderEngine_ = mainThread->GetRenderEngine();
180 }
181 if (!processor_->Init(node, node.GetDisplayOffsetX(), node.GetDisplayOffsetY(),
182 mirrorNode ? mirrorNode->GetScreenId() : INVALID_SCREEN_ID, processorRenderEngine_)) {
183 RS_LOGE("RSRenderServiceVisitor::ProcessDisplayRenderNode: processor init failed!");
184 return;
185 }
186
187 if (node.IsMirrorDisplay()) {
188 auto mirrorSource = node.GetMirrorSource();
189 auto existingSource = mirrorSource.lock();
190 if (!existingSource) {
191 RS_LOGI("RSRenderServiceVisitor::ProcessDisplayRenderNode mirrorSource haven't existed");
192 return;
193 }
194 ProcessChildren(*existingSource);
195 } else {
196 ProcessChildren(node);
197 }
198 processor_->PostProcess();
199 }
200
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)201 void RSRenderServiceVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
202 {
203 if (RSInnovation::GetParallelCompositionEnabled(false)) {
204 typedef bool (*CheckForSerialForcedFunc)(std::string&);
205 CheckForSerialForcedFunc CheckForSerialForced =
206 reinterpret_cast<CheckForSerialForcedFunc>(RSInnovation::_s_checkForSerialForced);
207 auto name = node.GetName();
208 mForceSerial |= CheckForSerialForced(name);
209 }
210
211 if (isSecurityDisplay_ && node.GetSecurityLayer()) {
212 RS_LOGI("RSRenderServiceVisitor::PrepareSurfaceRenderNode node[%" PRIu64 "] prepare paused because of \
213 security DisplayNode.",
214 node.GetId());
215 return;
216 }
217 if (!canvas_) {
218 RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : %" PRIu64 " canvas is nullptr", node.GetId());
219 return;
220 }
221 if (!node.ShouldPaint()) {
222 RS_LOGD("RSRenderServiceVisitor::PrepareSurfaceRenderNode node : %" PRIu64 " is invisible", node.GetId());
223 return;
224 }
225 node.SetOffset(offsetX_, offsetY_);
226 node.PrepareRenderBeforeChildren(*canvas_);
227 PrepareChildren(node);
228 node.PrepareRenderAfterChildren(*canvas_);
229 }
230
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)231 void RSRenderServiceVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
232 {
233 if (!processor_) {
234 RS_LOGE("RSRenderServiceVisitor::ProcessSurfaceRenderNode processor is nullptr");
235 return;
236 }
237 if (isSecurityDisplay_ && node.GetSecurityLayer()) {
238 RS_LOGI("RSRenderServiceVisitor::ProcessSurfaceRenderNode node[%" PRIu64 "] process paused because of \
239 security DisplayNode.",
240 node.GetId());
241 return;
242 }
243 if (!node.ShouldPaint()) {
244 RS_LOGD("RSRenderServiceVisitor::ProcessSurfaceRenderNode node : %" PRIu64 " is invisible", node.GetId());
245 return;
246 }
247 if (!node.GetOcclusionVisible() && !doAnimate_ && RSSystemProperties::GetOcclusionEnabled()) {
248 return;
249 }
250 if (mParallelEnable) {
251 node.ParallelVisitLock();
252 }
253 ProcessChildren(node);
254 node.SetGlobalZOrder(globalZOrder_);
255 globalZOrder_ = globalZOrder_ + 1;
256 processor_->ProcessSurface(node);
257 RSBaseRenderUtil::WriteSurfaceRenderNodeToPng(node);
258 if (mParallelEnable) {
259 node.ParallelVisitUnlock();
260 }
261 }
262 } // namespace Rosen
263 } // namespace OHOS
264