1 /*
2 * Copyright (c) 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_uni_render_visitor.h"
17
18 #ifdef RS_ENABLE_VK
19 #include <vulkan_window.h>
20 #endif
21
22 #ifndef USE_ROSEN_DRAWING
23 #include "include/core/SkRegion.h"
24 #include "include/core/SkTextBlob.h"
25 #else
26 #include "recording/recording_canvas.h"
27 #endif
28
29 #include "common/rs_background_thread.h"
30 #include "common/rs_common_def.h"
31 #include "common/rs_obj_abs_geometry.h"
32 #include "common/rs_optional_trace.h"
33 #include "memory/rs_tag_tracker.h"
34 #include "pipeline/rs_base_render_node.h"
35 #include "pipeline/rs_base_render_util.h"
36 #include "pipeline/rs_canvas_drawing_render_node.h"
37 #include "pipeline/rs_cold_start_thread.h"
38 #include "pipeline/rs_display_render_node.h"
39 #include "pipeline/rs_draw_cmd.h"
40 #include "pipeline/rs_effect_render_node.h"
41 #include "pipeline/rs_main_thread.h"
42 #include "pipeline/rs_paint_filter_canvas.h"
43 #include "pipeline/rs_processor_factory.h"
44 #include "pipeline/rs_proxy_render_node.h"
45 #include "pipeline/rs_recording_canvas.h"
46 #include "pipeline/rs_root_render_node.h"
47 #include "pipeline/rs_surface_render_node.h"
48 #include "pipeline/rs_uni_render_listener.h"
49 #include "pipeline/rs_uni_render_virtual_processor.h"
50 #include "pipeline/rs_uni_render_util.h"
51 #include "platform/common/rs_log.h"
52 #include "platform/common/rs_system_properties.h"
53 #include "property/rs_properties_painter.h"
54 #include "render/rs_skia_filter.h"
55 #include "pipeline/parallel_render/rs_parallel_render_manager.h"
56 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
57 #include "system/rs_system_parameters.h"
58 #include "scene_board_judgement.h"
59 #include "hgm_core.h"
60 #ifdef RS_ENABLE_RECORDING
61 #include "benchmarks/rs_recording_thread.h"
62 #endif
63 #include "scene_board_judgement.h"
64
65 namespace OHOS {
66 namespace Rosen {
67 namespace {
68 constexpr uint32_t PHONE_MAX_APP_WINDOW_NUM = 1;
69 constexpr uint32_t CACHE_MAX_UPDATE_TIME = 2;
70 constexpr uint32_t CACHE_RENDER_NODE_MAP_COUNT = 2;
71 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
72 static std::map<NodeId, uint32_t> cacheRenderNodeMap = {};
73 static uint32_t cacheReuseTimes = 0;
74 static std::mutex cacheRenderNodeMapMutex;
75 static std::unordered_map<NodeId, std::pair<RSUniRenderVisitor::RenderParam,
76 std::unordered_map<NodeId, RSUniRenderVisitor::RenderParam>>> groupedTransitionNodes = {};
77
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)78 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
79 {
80 if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
81 auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
82 const auto& property = rootNode->GetRenderProperties();
83 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
84 return true;
85 }
86 }
87 return false;
88 }
89
IsFirstFrameReadyToDraw(RSSurfaceRenderNode & node)90 bool IsFirstFrameReadyToDraw(RSSurfaceRenderNode& node)
91 {
92 bool result = false;
93 for (auto& child : node.GetSortedChildren()) {
94 result = CheckRootNodeReadyToDraw(child);
95 // when appWindow has abilityComponent node
96 if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
97 for (auto& surfaceNodeChild : child->GetSortedChildren()) {
98 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
99 }
100 }
101 }
102 return result;
103 }
104 }
105
106 #if defined(RS_ENABLE_PARALLEL_RENDER) && (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK))
107 constexpr uint32_t PARALLEL_RENDER_MINIMUM_RENDER_NODE_NUMBER = 50;
108 #endif
109
RSUniRenderVisitor()110 RSUniRenderVisitor::RSUniRenderVisitor()
111 : curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
112 {
113 auto mainThread = RSMainThread::Instance();
114 renderEngine_ = mainThread->GetRenderEngine();
115 partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
116 quickSkipPrepareType_ = RSSystemParameters::GetQuickSkipPrepareType();
117 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
118 auto screenNum = screenManager->GetAllScreenIds().size();
119 isPartialRenderEnabled_ = (screenNum <= 1) && (partialRenderType_ != PartialRenderType::DISABLED);
120 isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_);
121 dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
122 isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
123 (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
124 isOpaqueRegionDfxEnabled_ = RSSystemProperties::GetOpaqueRegionDfxEnabled();
125 isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
126 isOpDropped_ = isPartialRenderEnabled_ && (partialRenderType_ != PartialRenderType::SET_DAMAGE)
127 && (!isDirtyRegionDfxEnabled_ && !isTargetDirtyRegionDfxEnabled_ && !isOpaqueRegionDfxEnabled_);
128 isQuickSkipPreparationEnabled_ = (quickSkipPrepareType_ != QuickSkipPrepareType::DISABLED);
129 isHardwareComposerEnabled_ = RSSystemProperties::GetHardwareComposerEnabled();
130 isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
131 RSTagTracker::UpdateReleaseGpuResourceEnable(RSSystemProperties::GetReleaseGpuResourceEnabled());
132 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
133 if (RSDrivenRenderManager::GetInstance().GetDrivenRenderEnabled()) {
134 drivenInfo_ = std::make_unique<DrivenInfo>();
135 }
136 #endif
137 surfaceNodePrepareMutex_ = std::make_shared<std::mutex>();
138 parallelRenderType_ = ParallelRenderingType::DISABLE;
139 #if defined(RS_ENABLE_PARALLEL_RENDER)
140 isCalcCostEnable_ = RSSystemParameters::GetCalcCostEnabled();
141 #endif
142 isUIFirst_ = RSMainThread::Instance()->IsUIFirstOn();
143 }
144
RSUniRenderVisitor(std::shared_ptr<RSPaintFilterCanvas> canvas,uint32_t surfaceIndex)145 RSUniRenderVisitor::RSUniRenderVisitor(std::shared_ptr<RSPaintFilterCanvas> canvas, uint32_t surfaceIndex)
146 : RSUniRenderVisitor()
147 {
148 #if defined(RS_ENABLE_PARALLEL_RENDER) && (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK))
149 parallelRenderVisitorIndex_ = surfaceIndex;
150 #if defined(RS_ENABLE_GL)
151 canvas_ = canvas;
152 #endif
153 #endif
154 }
155
RSUniRenderVisitor(const RSUniRenderVisitor & visitor)156 RSUniRenderVisitor::RSUniRenderVisitor(const RSUniRenderVisitor& visitor) : RSUniRenderVisitor()
157 {
158 currentVisitDisplay_ = visitor.currentVisitDisplay_;
159 screenInfo_ = visitor.screenInfo_;
160 displayHasSecSurface_ = visitor.displayHasSecSurface_;
161 parentSurfaceNodeMatrix_ = visitor.parentSurfaceNodeMatrix_;
162 curAlpha_ = visitor.curAlpha_;
163 dirtyFlag_ = visitor.dirtyFlag_;
164 curDisplayNode_ = visitor.curDisplayNode_;
165 currentFocusedNodeId_ = visitor.currentFocusedNodeId_;
166 surfaceNodePrepareMutex_ = visitor.surfaceNodePrepareMutex_;
167 prepareClipRect_ = visitor.prepareClipRect_;
168 isOpDropped_ = visitor.isOpDropped_;
169 isPartialRenderEnabled_ = visitor.isPartialRenderEnabled_;
170 isHardwareForcedDisabled_ = visitor.isHardwareForcedDisabled_;
171 doAnimate_ = visitor.doAnimate_;
172 isDirty_ = visitor.isDirty_;
173 }
174
~RSUniRenderVisitor()175 RSUniRenderVisitor::~RSUniRenderVisitor() {}
176
CopyVisitorInfos(std::shared_ptr<RSUniRenderVisitor> visitor)177 void RSUniRenderVisitor::CopyVisitorInfos(std::shared_ptr<RSUniRenderVisitor> visitor)
178 {
179 std::unique_lock<std::mutex> lock(copyVisitorInfosMutex_);
180 currentVisitDisplay_ = visitor->currentVisitDisplay_;
181 screenInfo_ = visitor->screenInfo_;
182 displayHasSecSurface_ = visitor->displayHasSecSurface_;
183 parentSurfaceNodeMatrix_ = visitor->parentSurfaceNodeMatrix_;
184 curAlpha_ = visitor->curAlpha_;
185 dirtyFlag_ = visitor->dirtyFlag_;
186 curDisplayNode_ = visitor->curDisplayNode_;
187 currentFocusedNodeId_ = visitor->currentFocusedNodeId_;
188 surfaceNodePrepareMutex_ = visitor->surfaceNodePrepareMutex_;
189 prepareClipRect_ = visitor->prepareClipRect_;
190 isOpDropped_ = visitor->isOpDropped_;
191 isPartialRenderEnabled_ = visitor->isPartialRenderEnabled_;
192 isHardwareForcedDisabled_ = visitor->isHardwareForcedDisabled_;
193 doAnimate_ = visitor->doAnimate_;
194 isDirty_ = visitor->isDirty_;
195 }
196
CopyPropertyForParallelVisitor(RSUniRenderVisitor * mainVisitor)197 void RSUniRenderVisitor::CopyPropertyForParallelVisitor(RSUniRenderVisitor *mainVisitor)
198 {
199 if (!mainVisitor) {
200 RS_LOGE("main thread visitor is nullptr");
201 return;
202 }
203 doAnimate_ = mainVisitor->doAnimate_;
204 isParallel_ = mainVisitor->isParallel_;
205 isUpdateCachedSurface_ = mainVisitor->isUpdateCachedSurface_;
206 isHardwareForcedDisabled_ = mainVisitor->isHardwareForcedDisabled_;
207 isOpDropped_ = mainVisitor->isOpDropped_;
208 isPartialRenderEnabled_ = mainVisitor->isPartialRenderEnabled_;
209 isUIFirst_ = mainVisitor->isUIFirst_;
210 isSubThread_ = true;
211 }
212
PrepareChildren(RSRenderNode & node)213 void RSUniRenderVisitor::PrepareChildren(RSRenderNode& node)
214 {
215 node.ApplyChildrenModifiers();
216 const auto& children = node.GetSortedChildren();
217
218 // GetSortedChildren() may remove disappearingChildren_ when transition animation end.
219 // So the judgement whether node has removed child should be executed after this.
220 // merge last childRect as dirty if any child has been removed
221 if (curSurfaceDirtyManager_ && node.HasRemovedChild()) {
222 RectI dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
223 if (isSubNodeOfSurfaceInPrepare_) {
224 curSurfaceDirtyManager_->MergeDirtyRect(dirtyRect);
225 if (curSurfaceDirtyManager_->IsTargetForDfx()) {
226 // since childRect includes multiple rects, defaultly marked as canvas_node
227 curSurfaceDirtyManager_->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
228 DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
229 }
230 } else {
231 curDisplayDirtyManager_->MergeDirtyRect(dirtyRect);
232 }
233 node.ResetHasRemovedChild();
234 }
235
236 // backup environment variables.
237 auto parentNode = std::move(logicParentNode_);
238 logicParentNode_ = node.weak_from_this();
239 node.ResetChildrenRect();
240 UpdateCacheChangeStatus(node);
241 int markedCachedNodeCnt = markedCachedNodes_;
242
243 for (auto& child : children) {
244 auto curRootNode = curRootNode_;
245 if (PrepareSharedTransitionNode(*child)) {
246 curDirty_ = child->IsDirty();
247 child->Prepare(shared_from_this());
248 }
249 curRootNode_ = curRootNode;
250 }
251
252 SetNodeCacheChangeStatus(node, markedCachedNodeCnt);
253 // restore environment variables
254 logicParentNode_ = std::move(parentNode);
255 }
256
UpdateCacheChangeStatus(RSBaseRenderNode & node)257 void RSUniRenderVisitor::UpdateCacheChangeStatus(RSBaseRenderNode& node)
258 {
259 node.SetChildHasFilter(false);
260 if (!isDrawingCacheEnabled_) {
261 return;
262 }
263 node.CheckDrawingCacheType();
264 if (!node.ShouldPaint()) {
265 node.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
266 }
267 // drawing group root node
268 if (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE) {
269 markedCachedNodes_++;
270 // For rootnode, init drawing changes only if there is any content dirty
271 isDrawingCacheChanged_ = curContentDirty_;
272 curCacheFilterRects_.push({});
273 childHasSurface_ = false;
274 } else {
275 // Any child node dirty causes cache change
276 isDrawingCacheChanged_ = isDrawingCacheChanged_ || curDirty_;
277 if (!curCacheFilterRects_.empty()) {
278 if (!node.IsInstanceOf<RSEffectRenderNode>() &&
279 (node.GetRenderProperties().GetBackgroundFilter() || node.GetRenderProperties().GetUseEffect())) {
280 curCacheFilterRects_.top().emplace(node.GetId(), node.GetFilterRect());
281 } else if (node.IsInstanceOf<RSSurfaceRenderNode>()) {
282 childHasSurface_ = true;
283 }
284 }
285 }
286 }
287
SetNodeCacheChangeStatus(RSBaseRenderNode & node,int markedCachedNodeCnt)288 void RSUniRenderVisitor::SetNodeCacheChangeStatus(RSBaseRenderNode& node, int markedCachedNodeCnt)
289 {
290 auto directParent = node.GetParent().lock();
291 if (directParent != nullptr && node.ChildHasFilter()) {
292 directParent->SetChildHasFilter(true);
293 }
294 if (!isDrawingCacheEnabled_ ||
295 node.GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE) {
296 return;
297 }
298 // Attention: currently not support filter. Only enable lowest marked cached node
299 // [planning] check if outofparent causes edge problem
300
301 uint32_t cacheRenderNodeMapCnt = CACHE_RENDER_NODE_MAP_COUNT;
302 {
303 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
304 cacheRenderNodeMapCnt = cacheRenderNodeMap.count(node.GetId());
305 }
306 if ((cacheRenderNodeMapCnt == 0 || isDrawingCacheChanged_) &&
307 ((markedCachedNodeCnt != markedCachedNodes_) || node.HasChildrenOutOfRect() || childHasSurface_)) {
308 node.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
309 }
310 if (!curCacheFilterRects_.empty()) {
311 allCacheFilterRects_.emplace(node.GetId(), curCacheFilterRects_.top());
312 curCacheFilterRects_.pop();
313 }
314 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::SetNodeCacheChangeStatus: node %" PRIu64 " drawingtype %d, "
315 "cacheChange %d, childHasFilter: %d, outofparent: %d, markedCachedNodeCnt|markedCachedNodes_: (%d, %d)",
316 node.GetId(), static_cast<int>(node.GetDrawingCacheType()),
317 static_cast<int>(isDrawingCacheChanged_), static_cast<int>(node.ChildHasFilter()),
318 static_cast<int>(node.HasChildrenOutOfRect()), markedCachedNodeCnt, markedCachedNodes_);
319 node.SetDrawingCacheChanged(isDrawingCacheChanged_);
320 // reset counter after executing the very first marked node
321 if (markedCachedNodeCnt == 1) {
322 markedCachedNodes_ = 0;
323 isDrawingCacheChanged_ = false;
324 childHasSurface_ = false;
325 }
326 }
327
CheckColorSpace(RSSurfaceRenderNode & node)328 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
329 {
330 if (node.IsAppWindow()) {
331 auto surfaceNodeColorSpace = node.GetColorSpace();
332 if (surfaceNodeColorSpace != GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB) {
333 ROSEN_LOGD("RSUniRenderVisitor::CheckColorSpace: node (%s) set new colorspace %d",
334 node.GetName().c_str(), surfaceNodeColorSpace);
335 if (std::find(colorGamutModes_.begin(), colorGamutModes_.end(),
336 static_cast<ScreenColorGamut>(surfaceNodeColorSpace)) != colorGamutModes_.end()) {
337 newColorSpace_ = surfaceNodeColorSpace;
338 } else {
339 RS_LOGD("RSUniRenderVisitor::CheckColorSpace: colorSpace is not supported on current screen");
340 }
341 }
342 } else {
343 if (node.GetChildrenCount() > 0) {
344 auto surfaceNodePtr = node.GetSortedChildren().front()->ReinterpretCastTo<RSSurfaceRenderNode>();
345 if (!surfaceNodePtr) {
346 return;
347 }
348 CheckColorSpace(*surfaceNodePtr);
349 }
350 }
351 }
352
GetNodePreferred(std::vector<HgmModifierProfile> hgmModifierProfileList) const353 int32_t RSUniRenderVisitor::GetNodePreferred(std::vector<HgmModifierProfile> hgmModifierProfileList) const
354 {
355 if (hgmModifierProfileList.size() == 0) {
356 return 0;
357 }
358 auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
359 int32_t nodePreferred = 0;
360 for (auto &hgmModifierProfile : hgmModifierProfileList) {
361 auto modifierPreferred = hgmCore.CalModifierPreferred(hgmModifierProfile);
362 nodePreferred = std::max(nodePreferred, modifierPreferred);
363 }
364 return nodePreferred;
365 }
366
PrepareDisplayRenderNode(RSDisplayRenderNode & node)367 void RSUniRenderVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode& node)
368 {
369 currentVisitDisplay_ = node.GetScreenId();
370 displayHasSecSurface_.emplace(currentVisitDisplay_, 0);
371 dirtySurfaceNodeMap_.clear();
372
373 auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
374 hgmCore.SetActiveScreenId(currentVisitDisplay_);
375
376 RS_TRACE_NAME("RSUniRender:PrepareDisplay " + std::to_string(currentVisitDisplay_));
377 curDisplayDirtyManager_ = node.GetDirtyManager();
378 curDisplayDirtyManager_->Clear();
379 curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
380 curRootNode_ = node.shared_from_this();
381
382 dirtyFlag_ = isDirty_;
383 isClipBoundDirty_ = false;
384 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
385 if (!screenManager) {
386 RS_LOGE("RSUniRenderVisitor::PrepareDisplayRenderNode ScreenManager is nullptr");
387 return;
388 }
389 screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
390 prepareClipRect_.SetAll(0, 0, screenInfo_.width, screenInfo_.height);
391 screenManager->GetScreenSupportedColorGamuts(node.GetScreenId(), colorGamutModes_);
392 for (auto& child : node.GetSortedChildren()) {
393 auto surfaceNodePtr = child->ReinterpretCastTo<RSSurfaceRenderNode>();
394 if (!surfaceNodePtr) {
395 RS_LOGE("RSUniRenderVisitor::PrepareDisplayRenderNode ReinterpretCastTo fail");
396 continue;
397 }
398 CheckColorSpace(*surfaceNodePtr);
399 }
400 #ifndef USE_ROSEN_DRAWING
401 parentSurfaceNodeMatrix_ = SkMatrix::I();
402 #else
403 parentSurfaceNodeMatrix_ = Drawing::Matrix();
404 #endif
405 auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
406 if (geoPtr != nullptr) {
407 geoPtr->UpdateByMatrixFromSelf();
408 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
409 if (geoPtr->IsNeedClientCompose()) {
410 isHardwareForcedDisabled_ = true;
411 }
412 }
413 dirtyFlag_ = dirtyFlag_ || node.IsRotationChanged();
414 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
415 if (drivenInfo_) {
416 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty =
417 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty || dirtyFlag_;
418 }
419 #endif
420 // when display is in rotation state, occlusion relationship will be ruined,
421 // hence partial-render quick-reject should be disabled.
422 if(node.IsRotationChanged()) {
423 isOpDropped_ = false;
424 RS_TRACE_NAME("ClosePartialRender 1 RotationChanged");
425 }
426 node.UpdateRotation();
427 curAlpha_ = node.GetRenderProperties().GetAlpha();
428 isParallel_ = false;
429 #if defined(RS_ENABLE_PARALLEL_RENDER) && (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK))
430 ParallelPrepareDisplayRenderNodeChildrens(node);
431 #else
432 PrepareChildren(node);
433 #endif
434 auto mirrorNode = node.GetMirrorSource().lock();
435 if (mirrorNode) {
436 mirroredDisplays_.insert(mirrorNode->GetScreenId());
437 }
438
439 node.GetCurAllSurfaces().clear();
440 node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(), true, false);
441
442 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
443 if (drivenInfo_) {
444 RS_OPTIONAL_TRACE_BEGIN("RSUniRender:DrivenRenderPrepare");
445 drivenInfo_->prepareInfo.hasInvalidScene = drivenInfo_->prepareInfo.hasInvalidScene ||
446 node.GetChildrenCount() >= 8 || // default value, count > 8 means invalid scene
447 isHardwareForcedDisabled_ || node.GetRotation() != ScreenRotation::ROTATION_0;
448 drivenInfo_->prepareInfo.screenRect = RectI(0, 0, screenInfo_.width, screenInfo_.height),
449 // prepare driven render tree
450 RSDrivenRenderManager::GetInstance().DoPrepareRenderTask(drivenInfo_->prepareInfo);
451 // merge dirty rect for driven render
452 auto uniDrivenRenderMode = RSDrivenRenderManager::GetInstance().GetUniDrivenRenderMode();
453 if (uniDrivenRenderMode == DrivenUniRenderMode::RENDER_WITH_CLIP_HOLE &&
454 drivenInfo_->surfaceDirtyManager != nullptr) {
455 auto drivenRenderDirtyRect = RSDrivenRenderManager::GetInstance().GetUniRenderSurfaceClipHoleRect();
456 RS_OPTIONAL_TRACE_NAME("merge driven render dirty rect: " + drivenRenderDirtyRect.ToString());
457 drivenInfo_->surfaceDirtyManager->MergeDirtyRect(drivenRenderDirtyRect);
458 }
459 RS_OPTIONAL_TRACE_END();
460 }
461 #endif
462 if (!unpairedTransitionNodes_.empty()) {
463 RS_LOGE("RSUniRenderVisitor::PrepareDisplayRenderNode unpairedTransitionNodes_ is not empty.");
464 // We can't find the paired transition node, so we should clear the transition param.
465 for (auto& [key, params] : unpairedTransitionNodes_) {
466 std::get<std::shared_ptr<RSRenderNode>>(params)->SetSharedTransitionParam(std::nullopt);
467 }
468 unpairedTransitionNodes_.clear();
469 }
470
471 CollectFrameRateRange(node);
472 }
473
ParallelPrepareDisplayRenderNodeChildrens(RSDisplayRenderNode & node)474 void RSUniRenderVisitor::ParallelPrepareDisplayRenderNodeChildrens(RSDisplayRenderNode& node)
475 {
476 #if defined(RS_ENABLE_PARALLEL_RENDER) && (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK))
477 auto parallelRenderManager = RSParallelRenderManager::Instance();
478 doParallelRender_ = (node.GetChildrenCount() >= PARALLEL_RENDER_MINIMUM_RENDER_NODE_NUMBER) &&
479 (!doParallelComposition_);
480 isParallel_ = AdaptiveSubRenderThreadMode(doParallelRender_) && parallelRenderManager->GetParallelMode();
481 isDirtyRegionAlignedEnable_ = false;
482 // we will open prepare parallel after check all properties.
483 if (isParallel_ &&
484 RSSystemProperties::GetPrepareParallelRenderingEnabled() != ParallelRenderingType::DISABLE) {
485 parallelRenderManager->CopyPrepareVisitorAndPackTask(*this, node);
486 parallelRenderManager->LoadBalanceAndNotify(TaskType::PREPARE_TASK);
487 parallelRenderManager->WaitPrepareEnd(*this);
488 } else {
489 PrepareChildren(node);
490 }
491 #endif
492 }
493
CheckIfSurfaceRenderNodeStatic(RSSurfaceRenderNode & node)494 bool RSUniRenderVisitor::CheckIfSurfaceRenderNodeStatic(RSSurfaceRenderNode& node)
495 {
496 // dirtyFlag_ includes leashWindow dirty
497 // window layout change(e.g. move or zooming) | proxyRenderNode's cmd
498 if (dirtyFlag_ || node.IsDirty() || node.GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
499 return false;
500 }
501 // if node has to be prepared, it's not static
502 bool isClassifyByRootNode = (quickSkipPrepareType_ == QuickSkipPrepareType::STATIC_WIDGET);
503 NodeId rootId = node.GetInstanceRootNodeId();
504 if (RSMainThread::Instance()->CheckNodeHasToBePreparedByPid(node.GetId(), rootId, isClassifyByRootNode)) {
505 return false;
506 }
507 if (node.IsMainWindowType()) {
508 curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
509 curRootNode_ = node.shared_from_this();
510 // [Attention] node's ability pid could be different but should have same rootId
511 auto abilityNodeIds = node.GetAbilityNodeIds();
512 auto iter = std::any_of(abilityNodeIds.begin(), abilityNodeIds.end(),
513 [&](uint64_t nodeId) {
514 return RSMainThread::Instance()->CheckNodeHasToBePreparedByPid(nodeId, rootId, isClassifyByRootNode);
515 });
516 if (iter) {
517 return false;
518 }
519 }
520 RS_OPTIONAL_TRACE_BEGIN("Skip static surface " + node.GetName() + " nodeid - pid: " +
521 std::to_string(node.GetId()) + " - " + std::to_string(ExtractPid(node.GetId())));
522 // static node's dirty region is empty
523 curSurfaceDirtyManager_ = node.GetDirtyManager();
524 if (curSurfaceDirtyManager_) {
525 curSurfaceDirtyManager_->Clear();
526 curSurfaceDirtyManager_->UpdateVisitedDirtyRects(accumulatedDirtyRegions_);
527 node.UpdateFilterCacheStatusIfNodeStatic(prepareClipRect_);
528 }
529 // static surface keeps same position
530 curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), curDisplayNode_->GetLastFrameSurfacePos(node.GetId()));
531 RS_OPTIONAL_TRACE_END();
532 return true;
533 }
534
IsHardwareComposerEnabled()535 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
536 {
537 return !isHardwareForcedDisabled_ && !doAnimate_ && isHardwareComposerEnabled_;
538 }
539
ClearTransparentBeforeSaveLayer()540 void RSUniRenderVisitor::ClearTransparentBeforeSaveLayer()
541 {
542 RS_TRACE_NAME("ClearTransparentBeforeSaveLayer");
543 if (!IsHardwareComposerEnabled()) {
544 return;
545 }
546 for (auto& node : hardwareEnabledNodes_) {
547 if (!node->ShouldPaint()) {
548 continue;
549 }
550 auto dstRect = node->GetDstRect();
551 if (dstRect.IsEmpty()) {
552 continue;
553 }
554 #ifndef USE_ROSEN_DRAWING
555 canvas_->save();
556 canvas_->clipRect({ static_cast<float>(dstRect.GetLeft()), static_cast<float>(dstRect.GetTop()),
557 static_cast<float>(dstRect.GetRight()), static_cast<float>(dstRect.GetBottom()) });
558 canvas_->clear(SK_ColorTRANSPARENT);
559 canvas_->restore();
560 #else
561 canvas_->Save();
562 canvas_->ClipRect({ static_cast<float>(dstRect.GetLeft()), static_cast<float>(dstRect.GetTop()),
563 static_cast<float>(dstRect.GetRight()), static_cast<float>(dstRect.GetBottom()) },
564 Drawing::ClipOp::INTERSECT, false);
565 canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
566 canvas_->Restore();
567 #endif
568 }
569 }
570
MarkSubHardwareEnableNodeState(RSSurfaceRenderNode & surfaceNode)571 void RSUniRenderVisitor::MarkSubHardwareEnableNodeState(RSSurfaceRenderNode& surfaceNode)
572 {
573 if (!IsHardwareComposerEnabled()) {
574 return;
575 }
576
577 // hardware enabled type case: mark self
578 if (surfaceNode.IsHardwareEnabledType()) {
579 surfaceNode.SetHardwareForcedDisabledState(true);
580 return;
581 }
582
583 if (!surfaceNode.IsAppWindow() && !surfaceNode.IsAbilityComponent() && !surfaceNode.IsLeashWindow()) {
584 return;
585 }
586
587 // ability component type case: check pid
588 if (surfaceNode.IsAbilityComponent()) {
589 pid_t pid = ExtractPid(surfaceNode.GetId());
590 for (auto& childNode : hardwareEnabledNodes_) {
591 pid_t childPid = ExtractPid(childNode->GetId());
592 if (pid == childPid) {
593 childNode->SetHardwareForcedDisabledState(true);
594 }
595 }
596 return;
597 }
598 std::vector<std::weak_ptr<RSSurfaceRenderNode>> hardwareEnabledNodes;
599 if (surfaceNode.IsAppWindow()) {
600 hardwareEnabledNodes = surfaceNode.GetChildHardwareEnabledNodes();
601 } else {
602 for (auto& child : surfaceNode.GetChildren()) {
603 auto appNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
604 if (appNode && appNode->IsAppWindow()) {
605 hardwareEnabledNodes = appNode->GetChildHardwareEnabledNodes();
606 break;
607 }
608 }
609 }
610 // app window type case: mark all child hardware enabled nodes
611 for (auto& node : hardwareEnabledNodes) {
612 auto childNode = node.lock();
613 if (childNode) {
614 childNode->SetHardwareForcedDisabledState(true);
615 }
616 }
617 }
618
AdjustLocalZOrder(std::shared_ptr<RSSurfaceRenderNode> surfaceNode)619 void RSUniRenderVisitor::AdjustLocalZOrder(std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
620 {
621 if (!IsHardwareComposerEnabled() || !surfaceNode || !surfaceNode->IsAppWindow()) {
622 return;
623 }
624
625 auto hardwareEnabledNodes = surfaceNode->GetChildHardwareEnabledNodes();
626 if (hardwareEnabledNodes.empty()) {
627 return;
628 }
629 localZOrder_ = static_cast<float>(hardwareEnabledNodes.size());
630 if (isParallel_ && !isUIFirst_) {
631 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_GL)
632 RSParallelRenderManager::Instance()->AddAppWindowNode(parallelRenderVisitorIndex_, surfaceNode);
633 #endif
634 } else {
635 appWindowNodesInZOrder_.emplace_back(surfaceNode);
636 }
637 }
638
PrepareTypesOfSurfaceRenderNodeBeforeUpdate(RSSurfaceRenderNode & node)639 void RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeBeforeUpdate(RSSurfaceRenderNode& node)
640 {
641 // if current surfacenode is a main window type, reset the curSurfaceDirtyManager
642 // reset leash window's dirtyManager pointer to avoid curSurfaceDirtyManager mis-pointing
643 if (node.IsMainWindowType() || node.IsLeashWindow()) {
644 node.SetFilterCacheFullyCovered(false);
645 node.ResetFilterNodes();
646 curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
647 curSurfaceDirtyManager_ = node.GetDirtyManager();
648 if (curSurfaceDirtyManager_ == nullptr) {
649 RS_LOGE("RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeBeforeUpdate %s has no SurfaceDirtyManager",
650 node.GetName().c_str());
651 return;
652 }
653 curRootNode_ = node.shared_from_this();
654 curSurfaceDirtyManager_->Clear();
655 curSurfaceDirtyManager_->UpdateVisitedDirtyRects(accumulatedDirtyRegions_);
656 curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
657 if (isTargetDirtyRegionDfxEnabled_ && CheckIfSurfaceTargetedForDFX(node.GetName())) {
658 curSurfaceDirtyManager_->MarkAsTargetForDfx();
659 }
660 }
661 // collect ability nodeId info within same app since it belongs to another process
662 if (node.IsAbilityComponent() && curSurfaceNode_) {
663 curSurfaceNode_->UpdateAbilityNodeIds(node.GetId());
664 }
665
666 // collect app window node's child hardware enabled node
667 if (node.IsHardwareEnabledType() && node.GetBuffer() != nullptr && curSurfaceNode_) {
668 curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
669 node.SetLocalZOrder(localZOrder_++);
670 }
671
672 if (node.IsSelfDrawingType()) {
673 if (node.IsHardwareEnabledType()) {
674 if (!IsHardwareComposerEnabled() &&
675 (node.IsCurrentFrameBufferConsumed() || node.IsLastFrameHardwareEnabled())) {
676 node.SetContentDirty();
677 }
678 } else if (node.IsCurrentFrameBufferConsumed()) {
679 node.SetContentDirty();
680 }
681 }
682 }
683
PrepareTypesOfSurfaceRenderNodeAfterUpdate(RSSurfaceRenderNode & node)684 void RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeAfterUpdate(RSSurfaceRenderNode& node)
685 {
686 if (!curSurfaceDirtyManager_) {
687 return;
688 }
689 const auto& properties = node.GetRenderProperties();
690 if (properties.NeedFilter()) {
691 UpdateForegroundFilterCacheWithDirty(node);
692 if (auto parentNode = node.GetParent().lock()) {
693 parentNode->SetChildHasFilter(true);
694 }
695 if (curSurfaceNode_) {
696 curSurfaceNode_->UpdateFilterNodes(node.shared_from_this());
697 }
698 }
699 if (node.IsAppWindow()) {
700 bool hasFilter = node.IsTransparent()
701 && (properties.NeedFilter() || !node.GetChildrenNeedFilterRects().empty());
702 bool hasHardwareNode = !node.GetChildHardwareEnabledNodes().empty();
703 bool hasAbilityComponent = !node.GetAbilityNodeIds().empty();
704 auto rsParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
705 if (rsParent && rsParent->IsLeashWindow()) {
706 rsParent->SetHasFilter(hasFilter);
707 rsParent->SetHasHardwareNode(hasHardwareNode);
708 rsParent->SetHasAbilityComponent(hasAbilityComponent);
709 } else {
710 node.SetHasFilter(hasFilter);
711 node.SetHasHardwareNode(hasHardwareNode);
712 node.SetHasAbilityComponent(hasAbilityComponent);
713 }
714 #ifndef USE_ROSEN_DRAWING
715 if (hasFilter && curSurfaceDirtyManager_->IfCacheableFilterRectFullyCover(node.GetOldDirtyInSurface())) {
716 node.SetFilterCacheFullyCovered(true);
717 RS_LOGD("SetFilterCacheFullyCovered surfacenode %" PRIu64 " [%s]", node.GetId(), node.GetName().c_str());
718 }
719 #endif
720 RS_OPTIONAL_TRACE_NAME(node.GetName() + " PreparedNodes: " +
721 std::to_string(preparedCanvasNodeInCurrentSurface_));
722 preparedCanvasNodeInCurrentSurface_ = 0;
723 }
724 // accumulate all visited dirty rects including leash window's shadow dirty
725 if ((node.IsMainWindowType() || node.IsLeashWindow()) && curSurfaceDirtyManager_->IsCurrentFrameDirty()) {
726 accumulatedDirtyRegions_.emplace_back(curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion());
727 }
728 }
729
UpdateForegroundFilterCacheWithDirty(RSRenderNode & node)730 void RSUniRenderVisitor::UpdateForegroundFilterCacheWithDirty(RSRenderNode& node)
731 {
732 #ifndef USE_ROSEN_DRAWING
733 node.UpdateFilterCacheManagerWithCacheRegion(prepareClipRect_);
734 node.UpdateFilterCacheWithDirty(*curSurfaceDirtyManager_, true);
735 // record node's rect if it has valid filter cache
736 if (node.IsFilterCacheValid()) {
737 curSurfaceDirtyManager_->UpdateCacheableFilterRect(node.GetOldDirtyInSurface());
738 }
739 #endif
740 }
741
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)742 void RSUniRenderVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
743 {
744 RS_TRACE_NAME("RSUniRender::Prepare:[" + node.GetName() + "] pid: " + std::to_string(ExtractPid(node.GetId())) +
745 ", nodeType " + std::to_string(static_cast<uint>(node.GetSurfaceNodeType())));
746 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
747 needCacheImg_ = true;
748 captureWindowZorder_ = static_cast<uint32_t>(node.GetRenderProperties().GetPositionZ());
749 } else {
750 needCacheImg_ = captureWindowZorder_ > static_cast<uint32_t>(node.GetRenderProperties().GetPositionZ());
751 }
752 if (node.GetFingerprint() && node.GetBuffer() != nullptr) {
753 hasFingerprint_ = true;
754 }
755 if (node.GetSecurityLayer()) {
756 displayHasSecSurface_[currentVisitDisplay_]++;
757 }
758 if (curDisplayNode_ == nullptr) {
759 return;
760 }
761 // avoid EntryView upload texture while screen rotation
762 if (node.GetName() == "EntryView") {
763 node.SetStaticCached(curDisplayNode_->IsRotationChanged());
764 }
765 node.UpdatePositionZ();
766 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
767 if (drivenInfo_ && (node.GetName() == "imeWindow" || node.GetName() == "RecentView")) {
768 drivenInfo_->prepareInfo.hasInvalidScene = true;
769 }
770 #endif
771 // stop traversal if node keeps static
772 if (isQuickSkipPreparationEnabled_ && CheckIfSurfaceRenderNodeStatic(node)) {
773 return;
774 }
775 node.CleanDstRectChanged();
776 curContentDirty_ = node.IsContentDirty();
777 bool dirtyFlag = dirtyFlag_;
778 bool isClipBoundDirty = isClipBoundDirty_;
779
780 RectI prepareClipRect = prepareClipRect_;
781 bool isQuickSkipPreparationEnabled = isQuickSkipPreparationEnabled_;
782
783 // update geoptr with ContextMatrix
784 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
785 auto& property = node.GetMutableRenderProperties();
786 auto geoPtr = (property.GetBoundsGeometry());
787 if (geoPtr == nullptr) {
788 return;
789 }
790 float alpha = curAlpha_;
791 curAlpha_ *= (property.GetAlpha());
792 node.SetGlobalAlpha(curAlpha_);
793 // before node update, prepare node's setting by types
794 PrepareTypesOfSurfaceRenderNodeBeforeUpdate(node);
795
796 if (curSurfaceDirtyManager_ == nullptr) {
797 RS_LOGE("RSUniRenderVisitor::PrepareSurfaceRenderNode %s curSurfaceDirtyManager is nullptr",
798 node.GetName().c_str());
799 return;
800 }
801 if (isUIFirst_) {
802 auto skipNodeMap = RSMainThread::Instance()->GetCacheCmdSkippedNodes();
803 if (skipNodeMap.count(node.GetId()) != 0) {
804 auto parentNode = node.GetParent().lock();
805 auto rsParent = (parentNode);
806 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent, dirtyFlag_, false, prepareClipRect_);
807 dirtyFlag_ = dirtyFlag;
808 isClipBoundDirty_ = isClipBoundDirty;
809 RS_TRACE_NAME(node.GetName() + " PreparedNodes cacheCmdSkiped");
810 return;
811 }
812 }
813 // Update node properties, including position (dstrect), OldDirty()
814 auto parentNode = node.GetParent().lock();
815 auto rsParent = (parentNode);
816 auto rsSurfaceParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentNode);
817 if (node.IsAppWindow() && rsSurfaceParent && rsSurfaceParent->IsLeashWindow()
818 && rsSurfaceParent->GetDstRect().IsEmpty()) {
819 prepareClipRect_ = RectI {0, 0, 0, 0};
820 }
821 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent, dirtyFlag_, isClipBoundDirty_, prepareClipRect_);
822 isClipBoundDirty_ |= (dirtyFlag_ && node.IsClipBound());
823
824 if (curDisplayNode_ == nullptr) {
825 ROSEN_LOGE("RSUniRenderVisitor::PrepareSurfaceRenderNode, curDisplayNode_ is nullptr.");
826 return;
827 }
828 // Calculate the absolute destination rectangle of the node, initialize with absolute bounds rect
829 auto dstRect = geoPtr->GetAbsRect();
830 // If the screen is expanded, intersect the destination rectangle with the screen rectangle
831 dstRect = dstRect.IntersectRect(RectI(curDisplayNode_->GetDisplayOffsetX(), curDisplayNode_->GetDisplayOffsetY(),
832 screenInfo_.width, screenInfo_.height));
833 // Remove the offset of the screen
834 dstRect = RectI(dstRect.left_ - curDisplayNode_->GetDisplayOffsetX(),
835 dstRect.top_ - curDisplayNode_->GetDisplayOffsetY(), dstRect.GetWidth(), dstRect.GetHeight());
836 // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
837 if (node.IsHardwareEnabledType()) {
838 dstRect = dstRect.IntersectRect(prepareClipRect_);
839 }
840 // Set the destination rectangle of the node
841 node.SetDstRect(dstRect);
842
843 if (node.IsMainWindowType() || node.IsLeashWindow()) {
844 // record node position for display render node dirtyManager
845 curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirty());
846
847 if (node.IsAppWindow()) {
848 // if update appwindow, its children should not skip
849 localZOrder_ = 0.0f;
850 isQuickSkipPreparationEnabled_ = false;
851 node.ResetAbilityNodeIds();
852 node.ResetChildHardwareEnabledNodes();
853 #ifndef USE_ROSEN_DRAWING
854 boundsRect_ = SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight());
855 #else
856 boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
857 #endif
858 frameGravity_ = property.GetFrameGravity();
859 }
860 }
861
862 // [planning] Remove this after skia is upgraded, the clipRegion is supported
863 // reset childrenFilterRects
864 node.ResetChildrenFilterRects();
865
866 dirtyFlag_ = dirtyFlag_ || node.GetDstRectChanged();
867 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
868 #ifndef USE_ROSEN_DRAWING
869 if (!(parentSurfaceNodeMatrix_.getSkewX() < std::numeric_limits<float>::epsilon() &&
870 parentSurfaceNodeMatrix_.getSkewY() < std::numeric_limits<float>::epsilon())) {
871 #else
872 if (!(parentSurfaceNodeMatrix_.Get(Drawing::Matrix::SKEW_X) < std::numeric_limits<float>::epsilon() &&
873 parentSurfaceNodeMatrix_.Get(Drawing::Matrix::SKEW_Y) < std::numeric_limits<float>::epsilon())) {
874 #endif
875 isSurfaceRotationChanged_ = true;
876 doAnimate_ = doAnimate_ || isSurfaceRotationChanged_;
877 node.SetAnimateState();
878 }
879 auto screenRotation = curDisplayNode_->GetRotation();
880 auto screenRect = RectI(0, 0, screenInfo_.width, screenInfo_.height);
881 if (!node.CheckOpaqueRegionBaseInfo(
882 screenRect, geoPtr->GetAbsRect(), screenRotation, node.IsFocusedNode(currentFocusedNodeId_))
883 && node.GetSurfaceNodeType() != RSSurfaceNodeType::SELF_DRAWING_NODE) {
884 node.ResetSurfaceOpaqueRegion(screenRect, geoPtr->GetAbsRect(),
885 screenRotation, node.IsFocusedNode(currentFocusedNodeId_));
886 }
887 node.SetOpaqueRegionBaseInfo(
888 screenRect, geoPtr->GetAbsRect(), screenRotation, node.IsFocusedNode(currentFocusedNodeId_));
889
890 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
891 bool isLeashWindowNode = false;
892 if (drivenInfo_) {
893 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty =
894 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty || dirtyFlag_;
895 if (drivenInfo_->drivenUniTreePrepareMode == DrivenUniTreePrepareMode::PREPARE_DRIVEN_NODE_BEFORE) {
896 drivenInfo_->prepareInfo.dirtyInfo.backgroundDirty =
897 drivenInfo_->prepareInfo.dirtyInfo.backgroundDirty || dirtyFlag_;
898 } else if (drivenInfo_->drivenUniTreePrepareMode == DrivenUniTreePrepareMode::PREPARE_DRIVEN_NODE_AFTER) {
899 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty =
900 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty || node.GetRenderProperties().NeedFilter();
901 }
902
903 if (node.GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
904 isLeashWindowNode = true;
905 drivenInfo_->isPrepareLeashWinSubTree = true;
906 }
907 if (node.IsSelfDrawingType()) {
908 drivenInfo_->prepareInfo.hasInvalidScene = true;
909 }
910 }
911 #endif
912
913 bool isSubNodeOfSurfaceInPrepare = isSubNodeOfSurfaceInPrepare_;
914 if (node.IsMainWindowType() || node.IsLeashWindow()) {
915 isSubNodeOfSurfaceInPrepare_ = true;
916 }
917 node.UpdateChildrenOutOfRectFlag(false);
918 if (node.ShouldPrepareSubnodes()) {
919 PrepareChildren(node);
920 }
921 #if defined(RS_ENABLE_PARALLEL_RENDER) && (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK))
922 rsParent = (logicParentNode_.lock());
923 if (rsParent == curDisplayNode_) {
924 std::unique_lock<std::mutex> lock(*surfaceNodePrepareMutex_);
925 node.UpdateParentChildrenRect(logicParentNode_.lock());
926 } else {
927 node.UpdateParentChildrenRect(logicParentNode_.lock());
928 }
929 #else
930 node.UpdateParentChildrenRect(logicParentNode_.lock());
931 #endif
932 // restore flags
933 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
934 curAlpha_ = alpha;
935 dirtyFlag_ = dirtyFlag;
936 isClipBoundDirty_ = isClipBoundDirty;
937 isQuickSkipPreparationEnabled_ = isQuickSkipPreparationEnabled;
938 prepareClipRect_ = prepareClipRect;
939 if (node.IsMainWindowType() || node.IsLeashWindow()) {
940 isSubNodeOfSurfaceInPrepare_ = isSubNodeOfSurfaceInPrepare;
941 }
942
943 PrepareTypesOfSurfaceRenderNodeAfterUpdate(node);
944 if (node.GetDstRectChanged() || (node.GetDirtyManager() && node.GetDirtyManager()->IsCurrentFrameDirty())) {
945 dirtySurfaceNodeMap_.emplace(node.GetId(), node.ReinterpretCastTo<RSSurfaceRenderNode>());
946 }
947 if (node.IsLeashWindow()) {
948 auto matrix = geoPtr->GetAbsMatrix();
949 // 1.0f means node does not have scale
950 #ifndef USE_ROSEN_DRAWING
951 bool isScale = (matrix.getScaleX() > 0 && matrix.getScaleX() != 1.0f)
952 || (matrix.getScaleY() > 0 && matrix.getScaleY() != 1.0f);
953 #else
954 bool isScale = (matrix.Get(Drawing::Matrix::SCALE_X) > 0 && matrix.Get(Drawing::Matrix::SCALE_X) != 1.0f)
955 || (matrix.Get(Drawing::Matrix::SCALE_Y) > 0 && matrix.Get(Drawing::Matrix::SCALE_Y) != 1.0f);
956 #endif
957 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
958 #ifndef USE_ROSEN_DRAWING
959 isScale = isScale && matrix.getSkewX() < std::numeric_limits<float>::epsilon() &&
960 matrix.getSkewX() < std::numeric_limits<float>::epsilon();
961 #else
962 isScale = isScale && matrix.Get(Drawing::Matrix::SKEW_X) < std::numeric_limits<float>::epsilon() &&
963 matrix.Get(Drawing::Matrix::SKEW_X) < std::numeric_limits<float>::epsilon();
964 #endif
965 }
966 node.SetIsScale(isScale);
967 }
968 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
969 if (drivenInfo_ && isLeashWindowNode) {
970 drivenInfo_->isPrepareLeashWinSubTree = false;
971 }
972 #endif
973
974 CollectFrameRateRange(node);
975 }
976
977 void RSUniRenderVisitor::PrepareProxyRenderNode(RSProxyRenderNode& node)
978 {
979 // alpha is not affected by dirty flag, always update
980 node.SetContextAlpha(curAlpha_);
981 // skip matrix & clipRegion update if not dirty
982 if (!dirtyFlag_) {
983 return;
984 }
985 auto rsParent = (logicParentNode_.lock());
986 if (rsParent == nullptr) {
987 return;
988 }
989 auto& property = rsParent->GetMutableRenderProperties();
990 auto geoPtr = (property.GetBoundsGeometry());
991
992 // Context matrix should be relative to the parent surface node, so we need to revert the parentSurfaceNodeMatrix_.
993 #ifndef USE_ROSEN_DRAWING
994 SkMatrix invertMatrix;
995 auto contextMatrix = geoPtr->GetAbsMatrix();
996 if (parentSurfaceNodeMatrix_.invert(&invertMatrix)) {
997 contextMatrix.preConcat(invertMatrix);
998 } else {
999 ROSEN_LOGE("RSUniRenderVisitor::PrepareProxyRenderNode, invert parentSurfaceNodeMatrix_ failed");
1000 }
1001 #else
1002 Drawing::Matrix invertMatrix;
1003 Drawing::Matrix contextMatrix = geoPtr->GetAbsMatrix();
1004
1005 if (parentSurfaceNodeMatrix_.Invert(invertMatrix)) {
1006 contextMatrix.PreConcat(invertMatrix);
1007 } else {
1008 ROSEN_LOGE("RSUniRenderVisitor::PrepareProxyRenderNode, invert parentSurfaceNodeMatrix_ failed");
1009 }
1010 #endif
1011 node.SetContextMatrix(contextMatrix);
1012
1013 // For now, we only set the clipRegion if the parent node has ClipToBounds set to true.
1014 if (!property.GetClipToBounds()) {
1015 node.SetContextClipRegion(std::nullopt);
1016 } else {
1017 // Maybe we should use prepareClipRect_ and make the clipRegion in device coordinate, but it will be more
1018 // complex to calculate the intersect, and it will make app developers confused.
1019 auto rect = property.GetBoundsRect();
1020 // Context clip region is in the parent node coordinate, so we don't need to map it.
1021 #ifndef USE_ROSEN_DRAWING
1022 node.SetContextClipRegion(SkRect::MakeXYWH(rect.left_, rect.top_, rect.width_, rect.height_));
1023 #else
1024 node.SetContextClipRegion(Drawing::Rect(
1025 rect.GetLeft(), rect.GetTop(), rect.GetWidth() + rect.GetLeft(), rect.GetHeight() + rect.GetTop()));
1026 #endif
1027 }
1028
1029 // prepare children
1030 PrepareChildren(node);
1031 }
1032
1033 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
1034 {
1035 bool dirtyFlag = dirtyFlag_;
1036 float alpha = curAlpha_;
1037 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
1038 RectI prepareClipRect = prepareClipRect_;
1039 bool isClipBoundDirty = isClipBoundDirty_;
1040
1041 auto rsParent = (node.GetParent().lock());
1042 const auto& property = node.GetRenderProperties();
1043 bool geoDirty = property.IsGeoDirty();
1044 auto geoPtr = (property.GetBoundsGeometry());
1045
1046 if (curSurfaceDirtyManager_ == nullptr) {
1047 RS_LOGE("RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
1048 return;
1049 }
1050 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent, dirtyFlag_, isClipBoundDirty_);
1051 isClipBoundDirty_ |= (dirtyFlag_ && node.IsClipBound());
1052 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
1053 if (drivenInfo_) {
1054 drivenInfo_->currentRootNode = node.shared_from_this();
1055 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty =
1056 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty || dirtyFlag_;
1057 if (drivenInfo_->drivenUniTreePrepareMode == DrivenUniTreePrepareMode::PREPARE_DRIVEN_NODE_BEFORE) {
1058 drivenInfo_->prepareInfo.dirtyInfo.backgroundDirty = dirtyFlag_;
1059 } else if (drivenInfo_->drivenUniTreePrepareMode == DrivenUniTreePrepareMode::PREPARE_DRIVEN_NODE_AFTER) {
1060 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty =
1061 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty || node.GetRenderProperties().NeedFilter();
1062 }
1063 }
1064 #endif
1065 curAlpha_ *= property.GetAlpha();
1066 if (rsParent == curSurfaceNode_) {
1067 const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
1068 const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
1069 #ifndef USE_ROSEN_DRAWING
1070 SkMatrix gravityMatrix;
1071 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
1072 RectF { 0.0f, 0.0f, boundsRect_.width(), boundsRect_.height() }, rootWidth, rootHeight, gravityMatrix);
1073 #else
1074 Drawing::Matrix gravityMatrix;
1075 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
1076 RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
1077 rootWidth, rootHeight, gravityMatrix);
1078 #endif
1079 // Only Apply gravityMatrix when rootNode is dirty
1080 if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
1081 geoPtr->ConcatMatrix(gravityMatrix);
1082 }
1083 }
1084
1085 if (geoPtr != nullptr) {
1086 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
1087 }
1088 node.UpdateChildrenOutOfRectFlag(false);
1089 PrepareChildren(node);
1090 node.UpdateParentChildrenRect(logicParentNode_.lock());
1091
1092 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
1093 curAlpha_ = alpha;
1094 dirtyFlag_ = dirtyFlag;
1095 prepareClipRect_ = prepareClipRect;
1096 isClipBoundDirty_ = isClipBoundDirty;
1097
1098 CollectFrameRateRange(node);
1099 }
1100
1101 void RSUniRenderVisitor::PrepareCanvasRenderNode(RSCanvasRenderNode &node)
1102 {
1103 preparedCanvasNodeInCurrentSurface_++;
1104 curContentDirty_ = node.IsContentDirty();
1105 bool dirtyFlag = dirtyFlag_;
1106 RectI prepareClipRect = prepareClipRect_;
1107 bool isClipBoundDirty = isClipBoundDirty_;
1108
1109 auto nodeParent = node.GetParent().lock();
1110 while (nodeParent && nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>() &&
1111 nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>()->GetSurfaceNodeType() ==
1112 RSSurfaceNodeType::SELF_DRAWING_NODE) {
1113 nodeParent = nodeParent->GetParent().lock();
1114 }
1115
1116 if (curSurfaceDirtyManager_ == nullptr || curDisplayDirtyManager_ == nullptr) {
1117 RS_LOGE("RSUniRenderVisitor::PrepareCanvasRenderNode curXDirtyManager is nullptr");
1118 return;
1119 }
1120 node.GetMutableRenderProperties().UpdateSandBoxMatrix(parentSurfaceNodeMatrix_);
1121 if (!isSubNodeOfSurfaceInPrepare_) {
1122 // if canvasNode is not sub node of surfaceNode, merge the dirtyRegion to curDisplayDirtyManager_
1123 dirtyFlag_ = node.Update(*curDisplayDirtyManager_, nodeParent, dirtyFlag_, isClipBoundDirty_, prepareClipRect_);
1124 } else {
1125 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, nodeParent, dirtyFlag_, isClipBoundDirty_, prepareClipRect_);
1126 }
1127 isClipBoundDirty_ |= (dirtyFlag_ && node.IsClipBound());
1128
1129 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
1130 // driven render
1131 bool isContentCanvasNode = false;
1132 bool isBeforeContentNodeDirty = false;
1133 if (drivenInfo_ && currentVisitDisplay_ == 0 && drivenInfo_->isPrepareLeashWinSubTree && node.IsMarkDriven()) {
1134 auto drivenCanvasNode = RSDrivenRenderManager::GetInstance().GetContentSurfaceNode()->GetDrivenCanvasNode();
1135 if (node.IsMarkDrivenRender() ||
1136 (!drivenInfo_->hasDrivenNodeMarkRender &&
1137 drivenCanvasNode != nullptr && node.GetId() == drivenCanvasNode->GetId())) {
1138 drivenInfo_->prepareInfo.backgroundNode = drivenInfo_->currentRootNode;
1139 drivenInfo_->prepareInfo.contentNode = node.shared_from_this();
1140 drivenInfo_->drivenUniTreePrepareMode = DrivenUniTreePrepareMode::PREPARE_DRIVEN_NODE;
1141 drivenInfo_->prepareInfo.dirtyInfo.contentDirty = false;
1142 drivenInfo_->surfaceDirtyManager = curSurfaceDirtyManager_;
1143 isContentCanvasNode = true;
1144 isBeforeContentNodeDirty = drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty;
1145 if (node.IsMarkDrivenRender()) {
1146 drivenInfo_->prepareInfo.dirtyInfo.type = DrivenDirtyType::MARK_DRIVEN_RENDER;
1147 } else {
1148 drivenInfo_->prepareInfo.dirtyInfo.type = DrivenDirtyType::MARK_DRIVEN;
1149 }
1150 }
1151 }
1152 if (drivenInfo_) {
1153 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty =
1154 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty || dirtyFlag_;
1155 if (drivenInfo_->drivenUniTreePrepareMode == DrivenUniTreePrepareMode::PREPARE_DRIVEN_NODE_BEFORE) {
1156 drivenInfo_->prepareInfo.dirtyInfo.backgroundDirty =
1157 drivenInfo_->prepareInfo.dirtyInfo.backgroundDirty || dirtyFlag_;
1158 } else if (drivenInfo_->drivenUniTreePrepareMode == DrivenUniTreePrepareMode::PREPARE_DRIVEN_NODE_AFTER) {
1159 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty =
1160 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty || node.GetRenderProperties().NeedFilter();
1161 } else {
1162 if (node.IsContentChanged()) {
1163 drivenInfo_->prepareInfo.dirtyInfo.contentDirty = true;
1164 }
1165 }
1166 if (node.IsContentChanged()) {
1167 node.SetIsContentChanged(false);
1168 }
1169 }
1170 #endif
1171
1172 const auto& property = node.GetRenderProperties();
1173 auto geoPtr = (property.GetBoundsGeometry());
1174 // Dirty Region use abstract coordinate, property of node use relative coordinate
1175 // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
1176 if (property.GetClipToBounds()) {
1177 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
1178 }
1179 // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
1180 if (property.GetClipToFrame()) {
1181 // MapAbsRect do not handle the translation of OffsetX and OffsetY
1182 #ifndef USE_ROSEN_DRAWING
1183 RectF frameRect{
1184 property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().getScaleX(),
1185 property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().getScaleY(),
1186 property.GetFrameWidth(), property.GetFrameHeight()};
1187 #else
1188 RectF frameRect{
1189 property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
1190 property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
1191 property.GetFrameWidth(), property.GetFrameHeight()};
1192 #endif
1193 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
1194 }
1195
1196 float alpha = curAlpha_;
1197 curAlpha_ *= property.GetAlpha();
1198 node.SetGlobalAlpha(curAlpha_);
1199 node.UpdateChildrenOutOfRectFlag(false);
1200
1201 PrepareChildren(node);
1202 // attention: accumulate direct parent's childrenRect
1203 node.UpdateParentChildrenRect(logicParentNode_.lock());
1204 node.UpdateEffectRegion(effectRegion_);
1205 if (property.NeedFilter() || property.GetUseEffect()) {
1206 // filterRects_ is used in RSUniRenderVisitor::CalcDirtyFilterRegion
1207 // When oldDirtyRect of node with filter has intersect with any surfaceNode or displayNode dirtyRegion,
1208 // the whole oldDirtyRect should be render in this vsync.
1209 // Partial rendering of node with filter would cause display problem.
1210 if (auto directParent = node.GetParent().lock()) {
1211 directParent->SetChildHasFilter(true);
1212 }
1213 if (curSurfaceDirtyManager_->IsTargetForDfx()) {
1214 curSurfaceDirtyManager_->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
1215 DirtyRegionType::FILTER_RECT, node.GetOldDirtyInSurface());
1216 }
1217 if (curSurfaceNode_) {
1218 curSurfaceNode_->UpdateChildrenFilterRects(node.GetOldDirtyInSurface());
1219 curSurfaceNode_->UpdateFilterNodes(node.shared_from_this());
1220 }
1221 UpdateForegroundFilterCacheWithDirty(node);
1222 }
1223 curAlpha_ = alpha;
1224 dirtyFlag_ = dirtyFlag;
1225 prepareClipRect_ = prepareClipRect;
1226 isClipBoundDirty_ = isClipBoundDirty;
1227 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
1228 // skip content node and its children, calculate dirty contain background and foreground
1229 if (drivenInfo_ && isContentCanvasNode) {
1230 drivenInfo_->prepareInfo.dirtyInfo.nonContentDirty = isBeforeContentNodeDirty;
1231 drivenInfo_->drivenUniTreePrepareMode = DrivenUniTreePrepareMode::PREPARE_DRIVEN_NODE_AFTER;
1232 }
1233 #endif
1234
1235 CollectFrameRateRange(node);
1236 }
1237
1238 void RSUniRenderVisitor::PrepareEffectRenderNode(RSEffectRenderNode& node)
1239 {
1240 bool dirtyFlag = dirtyFlag_;
1241 RectI prepareClipRect = prepareClipRect_;
1242 bool isClipBoundDirty = isClipBoundDirty_;
1243 float alpha = curAlpha_;
1244 auto effectRegion = effectRegion_;
1245
1246 #ifndef USE_ROSEN_DRAWING
1247 effectRegion_ = SkPath();
1248 #else
1249 effectRegion_ = Drawing::Path();
1250 #endif
1251 const auto& property = node.GetRenderProperties();
1252 curAlpha_ *= property.GetAlpha();
1253
1254 auto parentNode = node.GetParent().lock();
1255 auto rsParent = (parentNode);
1256 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent, dirtyFlag_, isClipBoundDirty_, prepareClipRect_);
1257 isClipBoundDirty_ |= (dirtyFlag_ && node.IsClipBound());
1258
1259 node.UpdateChildrenOutOfRectFlag(false);
1260 PrepareChildren(node);
1261 node.UpdateParentChildrenRect(logicParentNode_.lock());
1262 node.SetEffectRegion(effectRegion_);
1263 UpdateForegroundFilterCacheWithDirty(node);
1264
1265 effectRegion_ = effectRegion;
1266 curAlpha_ = alpha;
1267 dirtyFlag_ = dirtyFlag;
1268 prepareClipRect_ = prepareClipRect;
1269 isClipBoundDirty_ = isClipBoundDirty;
1270
1271 CollectFrameRateRange(node);
1272 }
1273
1274 void RSUniRenderVisitor::CollectFrameRateRange(RSRenderNode& node)
1275 {
1276 //[Planning]: Support multi-display in the future.
1277 if (currentVisitDisplay_ != 0) {
1278 return;
1279 }
1280 frameRateRangeData_.screenId = currentVisitDisplay_;
1281 pid_t nodePid = ExtractPid(node.GetId());
1282 auto currRange = node.GetUIFrameRateRange();
1283 if (currRange.IsValid()) {
1284 if (frameRateRangeData_.multiAppRange.count(nodePid)) {
1285 frameRateRangeData_.multiAppRange[nodePid].Merge(currRange);
1286 } else {
1287 frameRateRangeData_.multiAppRange.insert(std::make_pair(nodePid, currRange));
1288 }
1289 }
1290
1291 currRange = node.GetRSFrameRateRange();
1292 if (currRange.IsValid()) {
1293 frameRateRangeData_.rsRange.Merge(currRange);
1294 }
1295 node.ResetUIFrameRateRange();
1296 node.ResetRSFrameRateRange();
1297 }
1298
1299 void RSUniRenderVisitor::CopyForParallelPrepare(std::shared_ptr<RSUniRenderVisitor> visitor)
1300 {
1301 #if defined(RS_ENABLE_PARALLEL_RENDER) && (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK))
1302 isPartialRenderEnabled_ = isPartialRenderEnabled_ && visitor->isPartialRenderEnabled_;
1303 isOpDropped_ = isOpDropped_ && visitor->isOpDropped_;
1304 needFilter_ = needFilter_ || visitor->needFilter_;
1305 for (const auto &u : visitor->displayHasSecSurface_) {
1306 displayHasSecSurface_[u.first] += u.second;
1307 }
1308
1309 for (const auto &u : visitor->dirtySurfaceNodeMap_) {
1310 dirtySurfaceNodeMap_[u.first] = u.second;
1311 }
1312 #endif
1313 }
1314
1315 #ifndef USE_ROSEN_DRAWING
1316 void RSUniRenderVisitor::DrawDirtyRectForDFX(const RectI& dirtyRect, const SkColor color,
1317 const SkPaint::Style fillType, float alpha, int edgeWidth = 6)
1318 {
1319 if (dirtyRect.width_ <= 0 || dirtyRect.height_ <= 0) {
1320 ROSEN_LOGD("DrawDirtyRectForDFX dirty rect is invalid.");
1321 return;
1322 }
1323 ROSEN_LOGD("DrawDirtyRectForDFX current dirtyRect = %s", dirtyRect.ToString().c_str());
1324 auto skRect = SkRect::MakeXYWH(dirtyRect.left_, dirtyRect.top_, dirtyRect.width_, dirtyRect.height_);
1325 std::string position = std::to_string(dirtyRect.left_) + ',' + std::to_string(dirtyRect.top_) + ',' +
1326 std::to_string(dirtyRect.width_) + ',' + std::to_string(dirtyRect.height_);
1327 const int defaultTextOffsetX = edgeWidth;
1328 const int defaultTextOffsetY = 30; // text position has 30 pixelSize under the skRect
1329 SkPaint rectPaint;
1330 // font size: 24
1331 sk_sp<SkTextBlob> SkTextBlob = SkTextBlob::MakeFromString(position.c_str(), SkFont(nullptr, 24.0f, 1.0f, 0.0f));
1332 rectPaint.setColor(color);
1333 rectPaint.setAntiAlias(true);
1334 rectPaint.setAlphaf(alpha);
1335 rectPaint.setStyle(fillType);
1336 rectPaint.setStrokeWidth(edgeWidth);
1337 if (fillType == SkPaint::kFill_Style) {
1338 rectPaint.setStrokeJoin(SkPaint::kRound_Join);
1339 }
1340 canvas_->drawRect(skRect, rectPaint);
1341 canvas_->drawTextBlob(SkTextBlob, dirtyRect.left_ + defaultTextOffsetX,
1342 dirtyRect.top_ + defaultTextOffsetY, SkPaint());
1343 }
1344 #else
1345 void RSUniRenderVisitor::DrawDirtyRectForDFX(const RectI& dirtyRect, const Drawing::Color color,
1346 const RSPaintStyle fillType, float alpha, int edgeWidth = 6)
1347 {
1348 if (dirtyRect.width_ <= 0 || dirtyRect.height_ <= 0) {
1349 ROSEN_LOGD("DrawDirtyRectForDFX dirty rect is invalid.");
1350 return;
1351 }
1352 ROSEN_LOGD("DrawDirtyRectForDFX current dirtyRect = %s", dirtyRect.ToString().c_str());
1353 auto rect = Drawing::Rect(dirtyRect.left_, dirtyRect.top_,
1354 dirtyRect.left_ + dirtyRect.width_, dirtyRect.top_ + dirtyRect.height_);
1355 std::string position = std::to_string(dirtyRect.left_) + ',' + std::to_string(dirtyRect.top_) + ',' +
1356 std::to_string(dirtyRect.width_) + ',' + std::to_string(dirtyRect.height_);
1357 Drawing::Pen rectPen;
1358 Drawing::Brush rectBrush;
1359 // font size: 24
1360 if (fillType == RSPaintStyle::STROKE) {
1361 rectPen.SetColor(color);
1362 rectPen.SetAntiAlias(true);
1363 rectPen.SetAlphaF(alpha);
1364 rectPen.SetWidth(edgeWidth);
1365 rectPen.SetJoinStyle(Drawing::Pen::JoinStyle::ROUND_JOIN);
1366 canvas_->AttachPen(rectPen);
1367 } else {
1368 rectBrush.SetColor(color);
1369 rectBrush.SetAntiAlias(true);
1370 rectBrush.SetAlphaF(alpha);
1371 canvas_->AttachBrush(rectBrush);
1372 }
1373 canvas_->DrawRect(rect);
1374 canvas_->DetachPen();
1375 canvas_->DetachBrush();
1376 }
1377 #endif
1378
1379 void RSUniRenderVisitor::DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects)
1380 {
1381 const float fillAlpha = 0.2;
1382 for (const auto& subRect : dirtyRects) {
1383 #ifndef USE_ROSEN_DRAWING
1384 DrawDirtyRectForDFX(subRect, SK_ColorBLUE, SkPaint::kStroke_Style, fillAlpha);
1385 #else
1386 DrawDirtyRectForDFX(subRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::STROKE, fillAlpha);
1387 #endif
1388 }
1389 }
1390
1391 void RSUniRenderVisitor::DrawCacheRegionForDFX(std::vector<RectI> cacheRects)
1392 {
1393 const float fillAlpha = 0.2;
1394 for (const auto& subRect : cacheRects) {
1395 #ifndef USE_ROSEN_DRAWING
1396 DrawDirtyRectForDFX(subRect, SK_ColorBLUE, SkPaint::kFill_Style, fillAlpha);
1397 #else
1398 DrawDirtyRectForDFX(subRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::FILL, fillAlpha);
1399 #endif
1400 }
1401 }
1402
1403 void RSUniRenderVisitor::DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node, const Occlusion::Region& region)
1404 {
1405 const auto& visibleDirtyRects = region.GetRegionRects();
1406 std::vector<RectI> rects;
1407 for (auto& rect : visibleDirtyRects) {
1408 rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
1409 }
1410 DrawDirtyRegionForDFX(rects);
1411
1412 // draw display dirtyregion with red color
1413 RectI dirtySurfaceRect = node.GetDirtyManager()->GetDirtyRegion();
1414 const float fillAlpha = 0.2;
1415 #ifndef USE_ROSEN_DRAWING
1416 DrawDirtyRectForDFX(dirtySurfaceRect, SK_ColorRED, SkPaint::kStroke_Style, fillAlpha);
1417 #else
1418 DrawDirtyRectForDFX(dirtySurfaceRect, Drawing::Color::COLOR_RED, RSPaintStyle::STROKE, fillAlpha);
1419 #endif
1420 }
1421
1422 void RSUniRenderVisitor::DrawAllSurfaceOpaqueRegionForDFX(RSDisplayRenderNode& node)
1423 {
1424 for (auto& it : node.GetCurAllSurfaces()) {
1425 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(it);
1426 if (surfaceNode->IsMainWindowType()) {
1427 DrawSurfaceOpaqueRegionForDFX(*surfaceNode);
1428 }
1429 }
1430 }
1431
1432 void RSUniRenderVisitor::DrawTargetSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node)
1433 {
1434 for (auto it = node.GetCurAllSurfaces().rbegin(); it != node.GetCurAllSurfaces().rend(); ++it) {
1435 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1436 if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
1437 continue;
1438 }
1439 if (CheckIfSurfaceTargetedForDFX(surfaceNode->GetName())) {
1440 if (DrawDetailedTypesOfDirtyRegionForDFX(*surfaceNode)) {
1441 continue;
1442 }
1443 const auto& visibleDirtyRegions = surfaceNode->GetVisibleDirtyRegion().GetRegionRects();
1444 std::vector<RectI> rects;
1445 for (auto& rect : visibleDirtyRegions) {
1446 rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
1447 }
1448 const auto& visibleRegions = surfaceNode->GetVisibleRegion().GetRegionRects();
1449 auto displayDirtyRegion = node.GetDirtyManager()->GetDirtyRegion();
1450 for (auto& rect : visibleRegions) {
1451 auto visibleRect = RectI(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
1452 auto intersectRegion = displayDirtyRegion.IntersectRect(visibleRect);
1453 rects.emplace_back(intersectRegion);
1454 }
1455 DrawDirtyRegionForDFX(rects);
1456 }
1457 }
1458 }
1459
1460 void RSUniRenderVisitor::DrawAndTraceSingleDirtyRegionTypeForDFX(RSSurfaceRenderNode& node,
1461 DirtyRegionType dirtyType, bool isDrawn)
1462 {
1463 auto dirtyManager = node.GetDirtyManager();
1464 auto matchType = DIRTY_REGION_TYPE_MAP.find(dirtyType);
1465 if (dirtyManager == nullptr || matchType == DIRTY_REGION_TYPE_MAP.end()) {
1466 return;
1467 }
1468 std::map<NodeId, RectI> dirtyInfo;
1469 float fillAlpha = 0.2;
1470 std::map<RSRenderNodeType, std::pair<std::string, SkColor>> nodeConfig = {
1471 {RSRenderNodeType::CANVAS_NODE, std::make_pair("canvas", SK_ColorRED)},
1472 {RSRenderNodeType::SURFACE_NODE, std::make_pair("surface", SK_ColorGREEN)},
1473 };
1474
1475 std::string subInfo;
1476 for (const auto& [nodeType, info] : nodeConfig) {
1477 dirtyManager->GetDirtyRegionInfo(dirtyInfo, nodeType, dirtyType);
1478 subInfo += (" " + info.first + "node amount: " + std::to_string(dirtyInfo.size()));
1479 for (const auto& [nid, rect] : dirtyInfo) {
1480 if (isDrawn) {
1481 #ifndef USE_ROSEN_DRAWING
1482 DrawDirtyRectForDFX(rect, info.second, SkPaint::kStroke_Style, fillAlpha);
1483 #else
1484 DrawDirtyRectForDFX(rect, info.second, RSPaintStyle::STROKE, fillAlpha);
1485 #endif
1486 }
1487 }
1488 }
1489 RS_TRACE_NAME("DrawAndTraceSingleDirtyRegionTypeForDFX target surface node " + node.GetName() + " - id[" +
1490 std::to_string(node.GetId()) + "] has dirtytype " + matchType->second + subInfo);
1491 ROSEN_LOGD("DrawAndTraceSingleDirtyRegionTypeForDFX target surface node %s, id[%" PRIu64 "] has dirtytype %s%s",
1492 node.GetName().c_str(), node.GetId(), matchType->second.c_str(), subInfo.c_str());
1493 }
1494
1495 bool RSUniRenderVisitor::DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode& node)
1496 {
1497 if (dirtyRegionDebugType_ < DirtyRegionDebugType::CUR_DIRTY_DETAIL_ONLY_TRACE) {
1498 return false;
1499 }
1500 if (dirtyRegionDebugType_ == DirtyRegionDebugType::CUR_DIRTY_DETAIL_ONLY_TRACE) {
1501 auto i = DirtyRegionType::UPDATE_DIRTY_REGION;
1502 for (; i < DirtyRegionType::TYPE_AMOUNT; i = (DirtyRegionType)(i + 1)) {
1503 DrawAndTraceSingleDirtyRegionTypeForDFX(node, i, false);
1504 }
1505 return true;
1506 }
1507 const std::map<DirtyRegionDebugType, DirtyRegionType> DIRTY_REGION_DEBUG_TYPE_MAP {
1508 { DirtyRegionDebugType::UPDATE_DIRTY_REGION, DirtyRegionType::UPDATE_DIRTY_REGION },
1509 { DirtyRegionDebugType::OVERLAY_RECT, DirtyRegionType::OVERLAY_RECT },
1510 { DirtyRegionDebugType::FILTER_RECT, DirtyRegionType::FILTER_RECT },
1511 { DirtyRegionDebugType::SHADOW_RECT, DirtyRegionType::SHADOW_RECT },
1512 { DirtyRegionDebugType::PREPARE_CLIP_RECT, DirtyRegionType::PREPARE_CLIP_RECT },
1513 { DirtyRegionDebugType::REMOVE_CHILD_RECT, DirtyRegionType::REMOVE_CHILD_RECT },
1514 };
1515 auto matchType = DIRTY_REGION_DEBUG_TYPE_MAP.find(dirtyRegionDebugType_);
1516 if (matchType != DIRTY_REGION_DEBUG_TYPE_MAP.end()) {
1517 DrawAndTraceSingleDirtyRegionTypeForDFX(node, matchType->second);
1518 }
1519 return true;
1520 }
1521
1522 void RSUniRenderVisitor::DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode& node)
1523 {
1524 const auto& opaqueRegionRects = node.GetOpaqueRegion().GetRegionRects();
1525 for (const auto &subRect: opaqueRegionRects) {
1526 #ifndef USE_ROSEN_DRAWING
1527 DrawDirtyRectForDFX(subRect.ToRectI(), SK_ColorGREEN, SkPaint::kFill_Style, 0.2f, 0);
1528 #else
1529 DrawDirtyRectForDFX(subRect.ToRectI(), Drawing::Color::COLOR_GREEN,
1530 RSPaintStyle::FILL, 0.2f, 0);
1531 #endif
1532 }
1533 }
1534
1535 void RSUniRenderVisitor::ProcessChildren(RSRenderNode& node)
1536 {
1537 for (auto& child : node.GetSortedChildren()) {
1538 if (ProcessSharedTransitionNode(*child)) {
1539 child->Process(shared_from_this());
1540 }
1541 }
1542 }
1543
1544 void RSUniRenderVisitor::ProcessParallelDisplayRenderNode(RSDisplayRenderNode& node)
1545 {
1546 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_VK)
1547 RS_TRACE_NAME("ProcessParallelDisplayRenderNode[" + std::to_string(node.GetId()));
1548 RS_LOGD("RSUniRenderVisitor::ProcessParallelDisplayRenderNode node: %" PRIu64 ", child size:%u", node.GetId(),
1549 node.GetChildrenCount());
1550 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
1551 if (!screenManager) {
1552 RS_LOGE("RSUniRenderVisitor::ProcessParallelDisplayRenderNode ScreenManager is nullptr");
1553 return;
1554 }
1555 screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
1556 isSecurityDisplay_ = node.GetSecurityDisplay();
1557 switch (screenInfo_.state) {
1558 case ScreenState::HDI_OUTPUT_ENABLE:
1559 node.SetCompositeType(node.IsForceSoftComposite() ?
1560 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
1561 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
1562 break;
1563 case ScreenState::PRODUCER_SURFACE_ENABLE:
1564 default:
1565 RS_LOGE("RSUniRenderVisitor::ProcessParallelDisplayRenderNode ScreenState only support HDI_OUTPUT_ENABLE");
1566 return;
1567 }
1568 offsetX_ = node.GetDisplayOffsetX();
1569 offsetY_ = node.GetDisplayOffsetY();
1570 processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType());
1571 if (processor_ == nullptr) {
1572 RS_LOGE("RSUniRenderVisitor::ProcessParallelDisplayRenderNode: RSProcessor is null!");
1573 return;
1574 }
1575
1576 // ParallelDisplayRenderNode cannot have mirror source.
1577 if (!processor_->Init(node, node.GetDisplayOffsetX(), node.GetDisplayOffsetY(),
1578 INVALID_SCREEN_ID, renderEngine_)) {
1579 RS_LOGE("RSUniRenderVisitor::ProcessParallelDisplayRenderNode: processor init failed!");
1580 return;
1581 }
1582 std::shared_ptr<RSBaseRenderNode> nodePtr = node.shared_from_this();
1583 auto displayNodePtr = nodePtr->ReinterpretCastTo<RSDisplayRenderNode>();
1584 if (!displayNodePtr) {
1585 RS_LOGE("RSUniRenderVisitor::ProcessParallelDisplayRenderNode ReinterpretCastTo fail");
1586 return;
1587 }
1588 if (renderFrame_ == nullptr) {
1589 RS_LOGE("RSUniRenderVisitor::ProcessParallelDisplayRenderNode renderFrame_ nullptr");
1590 return;
1591 }
1592 std::shared_ptr<RSCanvasListener> overdrawListener = nullptr;
1593 AddOverDrawListener(renderFrame_, overdrawListener);
1594
1595 if (canvas_ == nullptr) {
1596 RS_LOGE("RSUniRenderVisitor::ProcessParallelDisplayRenderNode: failed to create canvas");
1597 return;
1598 }
1599 canvas_->clear(SK_ColorTRANSPARENT);
1600 RSPropertiesPainter::SetBgAntiAlias(true);
1601 int saveCount = canvas_->save();
1602 canvas_->SetHighContrast(renderEngine_->IsHighContrastEnabled());
1603 auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1604 if (geoPtr != nullptr) {
1605 canvas_->concat(geoPtr->GetMatrix());
1606 }
1607 for (auto& childNode : node.GetChildren()) {
1608 RSParallelRenderManager::Instance()->StartTiming(parallelRenderVisitorIndex_);
1609 childNode->Process(shared_from_this());
1610 RSParallelRenderManager::Instance()->StopTimingAndSetRenderTaskCost(
1611 parallelRenderVisitorIndex_, childNode->GetId(), TaskType::PROCESS_TASK);
1612 }
1613 canvas_->restoreToCount(saveCount);
1614
1615 if (overdrawListener != nullptr) {
1616 overdrawListener->Draw();
1617 }
1618 DrawWatermarkIfNeed();
1619 RS_TRACE_BEGIN("ProcessParallelDisplayRenderNode:FlushFrame");
1620 renderFrame_->Flush();
1621 RS_TRACE_END();
1622 RS_LOGD("RSUniRenderVisitor::ProcessParallelDisplayRenderNode end");
1623 #endif
1624 }
1625
1626 void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
1627 {
1628 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_VK)
1629 if (node.IsParallelDisplayNode()) {
1630 ProcessParallelDisplayRenderNode(node);
1631 return;
1632 }
1633 #endif
1634 RS_TRACE_NAME("ProcessDisplayRenderNode[" + std::to_string(node.GetScreenId()) + "]" +
1635 node.GetDirtyManager()->GetDirtyRegion().ToString().c_str());
1636 RS_LOGD("RSUniRenderVisitor::ProcessDisplayRenderNode node: %" PRIu64 ", child size:%u", node.GetId(),
1637 node.GetChildrenCount());
1638 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_GL)
1639 bool isNeedCalcCost = node.GetSurfaceChangedRects().size() > 0;
1640 #endif
1641 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
1642 if (!screenManager) {
1643 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode ScreenManager is nullptr");
1644 return;
1645 }
1646 screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
1647 isSecurityDisplay_ = node.GetSecurityDisplay();
1648 auto mirrorNode = node.GetMirrorSource().lock();
1649 switch (screenInfo_.state) {
1650 case ScreenState::PRODUCER_SURFACE_ENABLE:
1651 node.SetCompositeType(mirrorNode ?
1652 RSDisplayRenderNode::CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1653 RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1654 break;
1655 case ScreenState::HDI_OUTPUT_ENABLE:
1656 node.SetCompositeType(node.IsForceSoftComposite() ?
1657 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
1658 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
1659 break;
1660 default:
1661 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode ScreenState unsupported");
1662 return;
1663 }
1664 offsetX_ = node.GetDisplayOffsetX();
1665 offsetY_ = node.GetDisplayOffsetY();
1666 processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType());
1667 if (processor_ == nullptr) {
1668 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode: RSProcessor is null!");
1669 return;
1670 }
1671
1672 if (renderEngine_ == nullptr) {
1673 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode: renderEngine is null!");
1674 return;
1675 }
1676 if (!processor_->Init(node, node.GetDisplayOffsetX(), node.GetDisplayOffsetY(),
1677 mirrorNode ? mirrorNode->GetScreenId() : INVALID_SCREEN_ID, renderEngine_)) {
1678 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode: processor init failed!");
1679 return;
1680 }
1681 std::shared_ptr<RSBaseRenderNode> nodePtr = node.shared_from_this();
1682 auto displayNodePtr = nodePtr->ReinterpretCastTo<RSDisplayRenderNode>();
1683 if (!displayNodePtr) {
1684 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode ReinterpretCastTo fail");
1685 return;
1686 }
1687 if (!node.IsSurfaceCreated()) {
1688 sptr<IBufferConsumerListener> listener = new RSUniRenderListener(displayNodePtr);
1689 if (!node.CreateSurface(listener)) {
1690 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode CreateSurface failed");
1691 return;
1692 }
1693 }
1694
1695 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
1696 // [PLANNING]: processing of layers z-order to be implemented
1697 if (drivenInfo_ && !drivenInfo_->prepareInfo.hasInvalidScene) {
1698 drivenInfo_->currDrivenRenderMode = RSDrivenRenderManager::GetInstance().GetUniDrivenRenderMode();
1699 globalZOrder_ = RSDrivenRenderManager::GetInstance().GetUniRenderGlobalZOrder();
1700 }
1701 #endif
1702
1703 if (mirrorNode) {
1704 auto processor = std::static_pointer_cast<RSUniRenderVirtualProcessor>(processor_);
1705 if (displayHasSecSurface_[mirrorNode->GetScreenId()] > 0 &&
1706 mirrorNode->GetSecurityDisplay() != isSecurityDisplay_ &&
1707 processor) {
1708 canvas_ = processor->GetCanvas();
1709 if (canvas_ == nullptr) {
1710 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode failed to get canvas.");
1711 return;
1712 }
1713 #ifndef USE_ROSEN_DRAWING
1714 if (cacheImgForCapture_ && displayHasSecSurface_[mirrorNode->GetScreenId()] == 1) {
1715 canvas_->save();
1716 // If both canvas and skImage have rotated, we need to reset the canvas
1717 if (resetRotate_) {
1718 SkMatrix invertMatrix;
1719 if (processor->GetScreenTransformMatrix().invert(&invertMatrix)) {
1720 canvas_->concat(invertMatrix);
1721 }
1722 }
1723 SkPaint paint;
1724 paint.setAntiAlias(true);
1725 #ifdef NEW_SKIA
1726 canvas_->drawImage(cacheImgForCapture_, 0, 0, SkSamplingOptions(), &paint);
1727 #else
1728 paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
1729 canvas_->drawImage(cacheImgForCapture_, 0, 0, &paint);
1730 #endif
1731 canvas_->restore();
1732 DrawWatermarkIfNeed();
1733 } else {
1734 int saveCount = canvas_->save();
1735 ProcessChildren(*mirrorNode);
1736 DrawWatermarkIfNeed();
1737 canvas_->restoreToCount(saveCount);
1738 }
1739 #else
1740 if (cacheImgForCapture_ && displayHasSecSurface_[mirrorNode->GetScreenId()] == 1) {
1741 canvas_->Save();
1742 // If both canvas and skImage have rotated, we need to reset the canvas
1743 if (resetRotate_) {
1744 Drawing::Matrix invertMatrix;
1745 if (processor->GetScreenTransformMatrix().Invert(invertMatrix)) {
1746 canvas_->ConcatMatrix(invertMatrix);
1747 }
1748 }
1749 Drawing::Brush brush;
1750 brush.SetAntiAlias(true);
1751 canvas_->AttachBrush(brush);
1752 canvas_->DrawImage(*cacheImgForCapture_, 0, 0, Drawing::SamplingOptions());
1753 canvas_->DetachBrush();
1754 canvas_->Restore();
1755 DrawWatermarkIfNeed();
1756 } else {
1757 auto saveCount = canvas_->GetSaveCount();
1758 canvas_->Save();
1759 ProcessChildren(*mirrorNode);
1760 DrawWatermarkIfNeed();
1761 canvas_->RestoreToCount(saveCount);
1762 }
1763 #endif
1764 } else {
1765 processor_->ProcessDisplaySurface(*mirrorNode);
1766 }
1767 } else if (node.GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE) {
1768 auto processor = std::static_pointer_cast<RSUniRenderVirtualProcessor>(processor_);
1769 canvas_ = processor->GetCanvas();
1770 if (canvas_ == nullptr) {
1771 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode failed to get canvas.");
1772 return;
1773 }
1774 ProcessChildren(node);
1775 DrawWatermarkIfNeed();
1776 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
1777 } else if (drivenInfo_ && drivenInfo_->currDrivenRenderMode == DrivenUniRenderMode::REUSE_WITH_CLIP_HOLE) {
1778 RS_LOGD("RSUniRenderVisitor::ProcessDisplayRenderNode DrivenUniRenderMode is REUSE_WITH_CLIP_HOLE");
1779 node.SetGlobalZOrder(globalZOrder_);
1780 processor_->ProcessDisplaySurface(node);
1781 #endif
1782 } else {
1783 #ifdef RS_ENABLE_EGLQUERYSURFACE
1784 curDisplayDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1785 if (isSurfaceRotationChanged_) {
1786 curDisplayDirtyManager_->MergeSurfaceRect();
1787 isOpDropped_ = false;
1788 isSurfaceRotationChanged_ = false;
1789 }
1790 if (isPartialRenderEnabled_) {
1791 CalcDirtyDisplayRegion(displayNodePtr);
1792 AddContainerDirtyToGlobalDirty(displayNodePtr);
1793 // Aligning displayRenderNode and surfaceRenderNode dirty region before merge dirty filter region
1794 if (isDirtyRegionAlignedEnable_) {
1795 AlignGlobalAndSurfaceDirtyRegions(displayNodePtr);
1796 }
1797 CalcDirtyFilterRegion(displayNodePtr);
1798 displayNodePtr->ClearCurrentSurfacePos();
1799 } else {
1800 // if isPartialRenderEnabled_ is disabled for some reason (i.e. screen rotation),
1801 // we should keep a fullscreen dirtyregion history to avoid dirtyregion losses.
1802 // isPartialRenderEnabled_ should not be disabled after current position.
1803 curDisplayDirtyManager_->MergeSurfaceRect();
1804 curDisplayDirtyManager_->UpdateDirty(isDirtyRegionAlignedEnable_);
1805 }
1806 if (isOpDropped_ && dirtySurfaceNodeMap_.empty() && !curDisplayDirtyManager_->IsCurrentFrameDirty()) {
1807 RS_LOGD("DisplayNode skip");
1808 RS_TRACE_NAME("DisplayNode skip");
1809 if (!IsHardwareComposerEnabled()) {
1810 return;
1811 }
1812 bool needCreateDisplayNodeLayer = false;
1813 for (auto& surfaceNode: hardwareEnabledNodes_) {
1814 if (!surfaceNode->IsHardwareForcedDisabled()) {
1815 needCreateDisplayNodeLayer = true;
1816 processor_->ProcessSurface(*surfaceNode);
1817 }
1818 }
1819 if (needCreateDisplayNodeLayer) {
1820 processor_->ProcessDisplaySurface(node);
1821 processor_->PostProcess();
1822 }
1823 return;
1824 }
1825 #endif
1826
1827 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_VK)
1828 if (isParallel_ &&!isPartialRenderEnabled_) {
1829 auto parallelRenderManager = RSParallelRenderManager::Instance();
1830 vulkan::VulkanWindow::InitializeVulkan(
1831 parallelRenderManager->GetParallelThreadNumber());
1832 RS_OPTIONAL_TRACE_BEGIN("RSUniRender::VK::WaitFence");
1833 vulkan::VulkanWindow::WaitForSharedFence();
1834 vulkan::VulkanWindow::ResetSharedFence();
1835 RS_OPTIONAL_TRACE_END();
1836 parallelRenderManager->CopyVisitorAndPackTask(*this, node);
1837 parallelRenderManager->InitDisplayNodeAndRequestFrame(renderEngine_, screenInfo_);
1838 parallelRenderManager->LoadBalanceAndNotify(TaskType::PROCESS_TASK);
1839 parallelRenderManager->WaitProcessEnd();
1840 parallelRenderManager->CommitSurfaceNum(node.GetChildrenCount());
1841 vulkan::VulkanWindow::PresentAll();
1842
1843 RS_OPTIONAL_TRACE_BEGIN("RSUniRender:WaitUtilUniRenderFinished");
1844 RSMainThread::Instance()->WaitUtilUniRenderFinished();
1845 RS_OPTIONAL_TRACE_END();
1846
1847 parallelRenderManager->ProcessParallelDisplaySurface(*this);
1848 processor_->PostProcess();
1849
1850 parallelRenderManager->ReleaseBuffer();
1851
1852 isParallel_ = false;
1853 return;
1854 }
1855 #endif
1856
1857 auto rsSurface = node.GetRSSurface();
1858 if (rsSurface == nullptr) {
1859 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode No RSSurface found");
1860 return;
1861 }
1862 rsSurface->SetColorSpace(newColorSpace_);
1863 // we should request a framebuffer whose size is equals to the physical screen size.
1864 RS_TRACE_BEGIN("RSUniRender:RequestFrame");
1865 BufferRequestConfig bufferConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo_, true);
1866 if (hasFingerprint_) {
1867 bufferConfig.format = GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_1010102;
1868 RS_LOGD("RSUniRenderVisitor::ProcessDisplayRenderNode, RGBA 8888 to RGBA 1010102");
1869 }
1870 node.SetFingerprint(hasFingerprint_);
1871 RS_OPTIONAL_TRACE_BEGIN("RSUniRender::wait for bufferRequest cond");
1872 if (!RSMainThread::Instance()->WaitUntilDisplayNodeBufferReleased(node)) {
1873 RS_TRACE_NAME("RSUniRenderVisitor no released buffer");
1874 }
1875 RS_OPTIONAL_TRACE_END();
1876 #ifdef NEW_RENDER_CONTEXT
1877 renderFrame_ = renderEngine_->RequestFrame(std::static_pointer_cast<RSRenderSurfaceOhos>(rsSurface),
1878 bufferConfig);
1879 #else
1880 renderFrame_ = renderEngine_->RequestFrame(std::static_pointer_cast<RSSurfaceOhos>(rsSurface), bufferConfig);
1881 #endif
1882 RS_TRACE_END();
1883
1884 if (renderFrame_ == nullptr) {
1885 RS_LOGE("RSUniRenderVisitor Request Frame Failed");
1886 return;
1887 }
1888 std::shared_ptr<RSCanvasListener> overdrawListener = nullptr;
1889 AddOverDrawListener(renderFrame_, overdrawListener);
1890
1891 if (canvas_ == nullptr) {
1892 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode: failed to create canvas");
1893 return;
1894 }
1895
1896 #ifdef RS_ENABLE_RECORDING
1897 RSRecordingCanvas canvas(node.GetRenderProperties().GetBoundsWidth(),
1898 node.GetRenderProperties().GetBoundsHeight());
1899 std::shared_ptr<RSPaintFilterCanvas> recordingCanvas;
1900 bool recordingEnabled = false;
1901 if (RSSystemProperties::GetRecordingEnabled()) {
1902 RS_TRACE_BEGIN("RSUniRender:Recording begin");
1903 #ifdef RS_ENABLE_GL
1904 #ifdef NEW_SKIA
1905 canvas.SetGrRecordingContext(canvas_->recordingContext());
1906 #else
1907 canvas.SetGrContext(canvas_->getGrContext()); // SkImage::MakeFromCompressed need GrContext
1908 #endif
1909 #endif
1910 recordingCanvas = std::make_shared<RSPaintFilterCanvas>(&canvas);
1911 recordingEnabled = true;
1912 swap(canvas_, recordingCanvas);
1913 RSRecordingThread::Instance().CheckAndRecording();
1914 }
1915 #endif
1916
1917 #ifdef RS_ENABLE_VK
1918 canvas_->clear(SK_ColorTRANSPARENT);
1919 #endif
1920
1921 int saveLayerCnt = 0;
1922 #ifndef USE_ROSEN_DRAWING
1923 SkRegion region;
1924 #else
1925 Drawing::Region region;
1926 #endif
1927 Occlusion::Region dirtyRegionTest;
1928 std::vector<RectI> rects;
1929 bool clipPath = false;
1930 #ifdef RS_ENABLE_EGLQUERYSURFACE
1931 // Get displayNode buffer age in order to merge visible dirty region for displayNode.
1932 // And then set egl damage region to improve uni_render efficiency.
1933 if (isPartialRenderEnabled_) {
1934 // Early history buffer Merging will have impact on Overdraw display, so we need to
1935 // set the full screen dirty to avoid this impact.
1936 if (RSOverdrawController::GetInstance().IsEnabled()) {
1937 node.GetDirtyManager()->ResetDirtyAsSurfaceSize();
1938 }
1939 RS_OPTIONAL_TRACE_BEGIN("RSUniRender::GetBufferAge");
1940 int bufferAge = renderFrame_->GetBufferAge();
1941 RS_OPTIONAL_TRACE_END();
1942 RSUniRenderUtil::MergeDirtyHistory(displayNodePtr, bufferAge, isDirtyRegionAlignedEnable_);
1943 Occlusion::Region dirtyRegion = RSUniRenderUtil::MergeVisibleDirtyRegion(
1944 displayNodePtr, isDirtyRegionAlignedEnable_);
1945 dirtyRegionTest = dirtyRegion;
1946 if (isDirtyRegionAlignedEnable_) {
1947 SetSurfaceGlobalAlignedDirtyRegion(displayNodePtr, dirtyRegion);
1948 } else {
1949 SetSurfaceGlobalDirtyRegion(displayNodePtr);
1950 }
1951 rects = GetDirtyRects(dirtyRegion);
1952 RectI rect = node.GetDirtyManager()->GetDirtyRegionFlipWithinSurface();
1953 if (!rect.IsEmpty()) {
1954 rects.emplace_back(rect);
1955 }
1956 if (!isDirtyRegionAlignedEnable_) {
1957 auto disH = screenInfo_.GetRotatedHeight();
1958 for (auto& r : rects) {
1959 #ifndef USE_ROSEN_DRAWING
1960 region.op(SkIRect::MakeXYWH(r.left_, disH - r.GetBottom(), r.width_, r.height_),
1961 SkRegion::kUnion_Op);
1962 #else
1963 Drawing::Region tmpRegion;
1964 tmpRegion.SetRect(Drawing::RectI(r.left_, disH - r.GetBottom(),
1965 r.left_ + r.width_, disH - r.GetBottom() + r.height_));
1966 region.Op(tmpRegion, Drawing::RegionOp::UNION);
1967 #endif
1968 }
1969 }
1970 // SetDamageRegion and opDrop will be disabled for dirty region DFX visualization
1971 if (!isDirtyRegionDfxEnabled_ && !isTargetDirtyRegionDfxEnabled_ && !isOpaqueRegionDfxEnabled_) {
1972 renderFrame_->SetDamageRegion(rects);
1973 }
1974 }
1975 if (isOpDropped_ && !isDirtyRegionAlignedEnable_) {
1976 #ifndef USE_ROSEN_DRAWING
1977 if (region.isEmpty()) {
1978 // [planning] Remove this after frame buffer can cancel
1979 canvas_->clipRect(SkRect::MakeEmpty());
1980 } else if (region.isRect()) {
1981 canvas_->clipRegion(region);
1982 } else {
1983 RS_TRACE_NAME("RSUniRenderVisitor: clipPath");
1984 clipPath = true;
1985 SkPath dirtyPath;
1986 region.getBoundaryPath(&dirtyPath);
1987 canvas_->clipPath(dirtyPath, true);
1988 }
1989 #else
1990 RS_LOGD("[%s:%d] Drawing is not supported, canvas clipRegion", __func__, __LINE__);
1991 #endif
1992 }
1993 #endif
1994 RSPropertiesPainter::SetBgAntiAlias(true);
1995 if (!isParallel_ || isUIFirst_) {
1996 #ifndef USE_ROSEN_DRAWING
1997 int saveCount = canvas_->save();
1998 canvas_->SetHighContrast(renderEngine_->IsHighContrastEnabled());
1999 auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
2000 if (geoPtr != nullptr) {
2001 // enable cache if screen rotation is not times of 90 degree
2002 canvas_->SetCacheType(geoPtr->IsNeedClientCompose() ? RSPaintFilterCanvas::CacheType::ENABLED
2003 : RSPaintFilterCanvas::CacheType::DISABLED);
2004 }
2005
2006 bool needOffscreen = clipPath || canvas_->GetCacheType() == RSPaintFilterCanvas::CacheType::ENABLED;
2007 if (needOffscreen) {
2008 ClearTransparentBeforeSaveLayer(); // clear transparent before concat display node's matrix
2009 }
2010 if (geoPtr != nullptr) {
2011 canvas_->concat(geoPtr->GetMatrix());
2012 }
2013 if (needOffscreen) {
2014 // we are doing rotation animation, try offscreen render if capable
2015 displayNodeMatrix_ = canvas_->getTotalMatrix();
2016 PrepareOffscreenRender(node);
2017 ProcessChildren(node);
2018 FinishOffscreenRender();
2019 } else {
2020 // render directly
2021 ProcessChildren(node);
2022 }
2023 canvas_->restoreToCount(saveCount);
2024 #else
2025 int saveCount = canvas_->GetSaveCount();
2026 canvas_->Save();
2027 canvas_->SetHighContrast(renderEngine_->IsHighContrastEnabled());
2028 auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
2029 if (geoPtr != nullptr) {
2030 // enable cache if screen rotation is not times of 90 degree
2031 canvas_->SetCacheType(geoPtr->IsNeedClientCompose() ? RSPaintFilterCanvas::CacheType::ENABLED
2032 : RSPaintFilterCanvas::CacheType::DISABLED);
2033 }
2034
2035 bool needOffscreen = clipPath || canvas_->GetCacheType() == RSPaintFilterCanvas::CacheType::ENABLED;
2036 if (needOffscreen) {
2037 ClearTransparentBeforeSaveLayer(); // clear transparent before concat display node's matrix
2038 }
2039 if (geoPtr != nullptr) {
2040 canvas_->ConcatMatrix(geoPtr->GetMatrix());
2041 }
2042 if (needOffscreen) {
2043 // we are doing rotation animation, try offscreen render if capable
2044 displayNodeMatrix_ = canvas_->GetTotalMatrix();
2045 PrepareOffscreenRender(node);
2046 ProcessChildren(node);
2047 FinishOffscreenRender();
2048 } else {
2049 // render directly
2050 ProcessChildren(node);
2051 }
2052
2053 canvas_->RestoreToCount(saveCount);
2054 #endif
2055 }
2056 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_GL)
2057 if ((isParallel_ && !isUIFirst_ && ((rects.size() > 0) || !isPartialRenderEnabled_)) && isCalcCostEnable_) {
2058 auto parallelRenderManager = RSParallelRenderManager::Instance();
2059 parallelRenderManager->CopyCalcCostVisitorAndPackTask(*this, node, isNeedCalcCost,
2060 doAnimate_, isOpDropped_);
2061 if (parallelRenderManager->IsNeedCalcCost()) {
2062 parallelRenderManager->LoadBalanceAndNotify(TaskType::CALC_COST_TASK);
2063 parallelRenderManager->WaitCalcCostEnd();
2064 parallelRenderManager->UpdateNodeCost(node);
2065 }
2066 }
2067 if (isParallel_ && !isUIFirst_ && ((rects.size() > 0) || !isPartialRenderEnabled_)) {
2068 ClearTransparentBeforeSaveLayer();
2069 auto parallelRenderManager = RSParallelRenderManager::Instance();
2070 parallelRenderManager->SetFrameSize(screenInfo_.width, screenInfo_.height);
2071 parallelRenderManager->CopyVisitorAndPackTask(*this, node);
2072 parallelRenderManager->LoadBalanceAndNotify(TaskType::PROCESS_TASK);
2073 parallelRenderManager->MergeRenderResult(*canvas_);
2074 parallelRenderManager->CommitSurfaceNum(node.GetChildrenCount());
2075 parallelRenderManager->ProcessFilterSurfaceRenderNode();
2076 }
2077 #endif
2078 if (saveLayerCnt > 0) {
2079 #ifndef USE_ROSEN_DRAWING
2080 #ifdef RS_ENABLE_GL
2081 #ifdef NEW_RENDER_CONTEXT
2082 RSTagTracker tagTracker(
2083 renderEngine_->GetDrawingContext()->GetDrawingContext(),
2084 RSTagTracker::TAGTYPE::TAG_RESTORELAYER_DRAW_NODE);
2085 #else
2086 RSTagTracker tagTracker(
2087 renderEngine_->GetRenderContext()->GetGrContext(), RSTagTracker::TAGTYPE::TAG_RESTORELAYER_DRAW_NODE);
2088 #endif
2089 #endif
2090 RS_TRACE_NAME("RSUniRender:RestoreLayer");
2091 canvas_->restoreToCount(saveLayerCnt);
2092 #endif
2093 }
2094
2095 if (overdrawListener != nullptr) {
2096 overdrawListener->Draw();
2097 }
2098 DrawWatermarkIfNeed();
2099 // the following code makes DirtyRegion visible, enable this method by turning on the dirtyregiondebug property
2100 if (isPartialRenderEnabled_) {
2101 if (isDirtyRegionDfxEnabled_) {
2102 DrawAllSurfaceDirtyRegionForDFX(node, dirtyRegionTest);
2103 }
2104 if (isTargetDirtyRegionDfxEnabled_) {
2105 DrawTargetSurfaceDirtyRegionForDFX(node);
2106 }
2107 if (isOpaqueRegionDfxEnabled_) {
2108 DrawAllSurfaceOpaqueRegionForDFX(node);
2109 }
2110 }
2111
2112 if (isDrawingCacheEnabled_ && RSSystemParameters::GetDrawingCacheEnabledDfx()) {
2113 DrawCacheRegionForDFX(cacheRenderNodeMapRects_);
2114 }
2115 #ifdef RS_ENABLE_RECORDING
2116 if (recordingEnabled) {
2117 swap(canvas_, recordingCanvas);
2118 auto drawCmdList = canvas.GetDrawCmdList();
2119 RS_TRACE_BEGIN("RSUniRender:DrawCmdList Playback");
2120 drawCmdList->Playback(*canvas_);
2121 RS_TRACE_END();
2122 RS_TRACE_BEGIN("RSUniRender:RecordingToFile curFrameNum = " +
2123 std::to_string(RSRecordingThread::Instance().GetCurDumpFrame()));
2124 RSRecordingThread::Instance().RecordingToFile(drawCmdList);
2125 RS_TRACE_END();
2126 RS_TRACE_END();
2127 }
2128 #endif
2129 if (!OpItemTasks::Instance().IsEmpty()) {
2130 RSBackgroundThread::Instance().PostTask([]() {
2131 #ifndef USE_ROSEN_DRAWING
2132 RS_TRACE_NAME("RSUniRender:OpItemTasks ProcessTask");
2133 OpItemTasks::Instance().ProcessTask();
2134 #endif
2135 });
2136 }
2137 RS_TRACE_BEGIN("RSUniRender:FlushFrame");
2138 renderFrame_->Flush();
2139 RS_TRACE_END();
2140 RS_OPTIONAL_TRACE_BEGIN("RSUniRender:WaitUtilUniRenderFinished");
2141 RSMainThread::Instance()->WaitUtilUniRenderFinished();
2142 RS_OPTIONAL_TRACE_END();
2143 AssignGlobalZOrderAndCreateLayer();
2144 node.SetGlobalZOrder(globalZOrder_);
2145 processor_->ProcessDisplaySurface(node);
2146 }
2147
2148 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
2149 if (drivenInfo_ && !drivenInfo_->prepareInfo.hasInvalidScene) {
2150 RS_TRACE_NAME("RSUniRender:DrivenRenderProcess");
2151 // process driven render tree
2152 drivenInfo_->processInfo = { processor_, newColorSpace_, node.GetGlobalZOrder() };
2153 RSDrivenRenderManager::GetInstance().DoProcessRenderTask(drivenInfo_->processInfo);
2154 }
2155 #endif
2156 processor_->PostProcess();
2157 if (!unpairedTransitionNodes_.empty()) {
2158 RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode unpairedTransitionNodes_ is not empty.");
2159 // We can't find the paired transition node, so we should clear the transition param.
2160 for (auto& [key, params] : unpairedTransitionNodes_) {
2161 std::get<std::shared_ptr<RSRenderNode>>(params)->SetSharedTransitionParam(std::nullopt);
2162 }
2163 unpairedTransitionNodes_.clear();
2164 }
2165 RS_LOGD("RSUniRenderVisitor::ProcessDisplayRenderNode end");
2166 }
2167
2168 void RSUniRenderVisitor::DrawSurfaceLayer(const std::shared_ptr<RSDisplayRenderNode>& displayNode,
2169 const std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes) const
2170 {
2171 #if defined(RS_ENABLE_GL)
2172 auto subThreadManager = RSSubThreadManager::Instance();
2173 subThreadManager->Start(renderEngine_->GetRenderContext().get());
2174 subThreadManager->SubmitSubThreadTask(displayNode, subThreadNodes);
2175 #endif
2176 }
2177
2178 void RSUniRenderVisitor::AssignGlobalZOrderAndCreateLayer()
2179 {
2180 if (!IsHardwareComposerEnabled()) {
2181 return;
2182 }
2183 if (hardwareEnabledNodes_.empty()) {
2184 return;
2185 }
2186 if (isParallel_ && !isUIFirst_) {
2187 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined(RS_ENABLE_GL)
2188 std::vector<std::shared_ptr<RSSurfaceRenderNode>>().swap(appWindowNodesInZOrder_);
2189 auto subThreadNum = RSParallelRenderManager::Instance()->GetParallelThreadNumber();
2190 auto appWindowNodesMap = RSParallelRenderManager::Instance()->GetAppWindowNodes();
2191 std::vector<std::shared_ptr<RSSurfaceRenderNode>> appWindowNodes;
2192 for (uint32_t i = 0; i < subThreadNum; i++) {
2193 appWindowNodes = appWindowNodesMap[i];
2194 appWindowNodesInZOrder_.insert(appWindowNodesInZOrder_.end(), appWindowNodes.begin(), appWindowNodes.end());
2195 }
2196 #endif
2197 }
2198 globalZOrder_ = 0.0f;
2199 for (auto& appWindowNode : appWindowNodesInZOrder_) {
2200 // first, sort app window node's child surfaceView by local zOrder
2201 auto childHardwareEnabledNodes = appWindowNode->GetChildHardwareEnabledNodes();
2202 std::stable_sort(childHardwareEnabledNodes.begin(), childHardwareEnabledNodes.end(),
2203 [](const auto& first, const auto& second) {
2204 auto node1 = first.lock();
2205 auto node2 = second.lock();
2206 return node1 && node2 && node1->GetLocalZOrder() < node2->GetLocalZOrder();
2207 });
2208 localZOrder_ = 0.0f;
2209 for (auto& child : childHardwareEnabledNodes) {
2210 auto childNode = child.lock();
2211 if (childNode && childNode->GetBuffer() != nullptr && !childNode->IsHardwareForcedDisabled()) {
2212 // assign local zOrder here to ensure it range from 0 to childHardwareEnabledNodes.size()
2213 // for each app window node
2214 childNode->SetLocalZOrder(localZOrder_++);
2215 // SetGlobalZOrder here to ensure zOrder committed to composer is continuous
2216 childNode->SetGlobalZOrder(globalZOrder_++);
2217 RS_LOGD("createLayer: %" PRIu64 "", childNode->GetId());
2218 processor_->ProcessSurface(*childNode);
2219 }
2220 }
2221 }
2222 }
2223
2224 void RSUniRenderVisitor::AddOverDrawListener(std::unique_ptr<RSRenderFrame>& renderFrame,
2225 std::shared_ptr<RSCanvasListener>& overdrawListener)
2226 {
2227 #if defined(NEW_RENDER_CONTEXT)
2228 if (renderFrame == nullptr) {
2229 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: renderFrame is nullptr");
2230 return;
2231 }
2232 auto renderSurface = renderFrame->GetSurface();
2233 if (renderSurface == nullptr) {
2234 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: renderSurface is nullptr");
2235 return;
2236 }
2237 #if !defined(USE_ROSEN_DRAWING)
2238 RS_OPTIONAL_TRACE_BEGIN("RSUniRender::GetSurface");
2239 auto skSurface = renderSurface->GetSurface();
2240 RS_OPTIONAL_TRACE_END();
2241 if (skSurface == nullptr) {
2242 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: skSurface is null");
2243 return;
2244 }
2245 if (skSurface->getCanvas() == nullptr) {
2246 ROSEN_LOGE("skSurface.getCanvas is null.");
2247 return;
2248 }
2249 #else
2250 RS_OPTIONAL_TRACE_BEGIN("RSUniRender::GetSurface");
2251 auto drSurface = renderSurface->GetSurface();
2252 RS_OPTIONAL_TRACE_END();
2253 if (drSurface == nullptr) {
2254 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: drSurface is null");
2255 return;
2256 }
2257 if (drSurface->GetCanvas() == nullptr) {
2258 ROSEN_LOGE("drSurface.getCanvas is null.");
2259 return;
2260 }
2261 #endif
2262 #else
2263 if (renderFrame->GetFrame() == nullptr) {
2264 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: RSSurfaceFrame is nullptr");
2265 return;
2266 }
2267 #if !defined(USE_ROSEN_DRAWING)
2268 RS_TRACE_BEGIN("RSUniRender::GetSurface");
2269 auto skSurface = renderFrame->GetFrame()->GetSurface();
2270 RS_TRACE_END();
2271 if (skSurface == nullptr) {
2272 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: skSurface is null");
2273 return;
2274 }
2275 if (skSurface->getCanvas() == nullptr) {
2276 ROSEN_LOGE("skSurface.getCanvas is null.");
2277 return;
2278 }
2279 #else
2280 RS_OPTIONAL_TRACE_BEGIN("RSUniRender::GetSurface");
2281 auto drSurface = renderFrame->GetFrame()->GetSurface();
2282 RS_OPTIONAL_TRACE_END();
2283 if (drSurface == nullptr) {
2284 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: drSurface is null");
2285 return;
2286 }
2287 if (drSurface->GetCanvas() == nullptr) {
2288 ROSEN_LOGE("drSurface.getCanvas is null.");
2289 return;
2290 }
2291 #endif
2292 #endif
2293 // if listenedCanvas is nullptr, that means disabled or listen failed
2294 std::shared_ptr<RSListenedCanvas> listenedCanvas = nullptr;
2295
2296 if (RSOverdrawController::GetInstance().IsEnabled()) {
2297 auto &oc = RSOverdrawController::GetInstance();
2298 #ifndef USE_ROSEN_DRAWING
2299 listenedCanvas = std::make_shared<RSListenedCanvas>(skSurface.get());
2300 #else
2301 listenedCanvas = std::make_shared<RSListenedCanvas>(*drSurface.get());
2302 #endif
2303 overdrawListener = oc.CreateListener<RSGPUOverdrawCanvasListener>(listenedCanvas.get());
2304 if (overdrawListener == nullptr) {
2305 overdrawListener = oc.CreateListener<RSCPUOverdrawCanvasListener>(listenedCanvas.get());
2306 }
2307
2308 if (overdrawListener != nullptr) {
2309 listenedCanvas->SetListener(overdrawListener);
2310 } else {
2311 // create listener failed
2312 listenedCanvas = nullptr;
2313 }
2314 }
2315
2316 if (listenedCanvas != nullptr) {
2317 canvas_ = listenedCanvas;
2318 } else {
2319 #ifndef USE_ROSEN_DRAWING
2320 canvas_ = std::make_shared<RSPaintFilterCanvas>(skSurface.get());
2321 #else
2322 canvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
2323 #endif
2324 }
2325 }
2326
2327 void RSUniRenderVisitor::CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode>& node)
2328 {
2329 RS_OPTIONAL_TRACE_FUNC_BEGIN();
2330 auto displayDirtyManager = node->GetDirtyManager();
2331 for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
2332 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2333 if (surfaceNode == nullptr) {
2334 continue;
2335 }
2336 auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
2337 if (isUIFirst_ && surfaceDirtyManager->IsCurrentFrameDirty()) {
2338 dirtySurfaceNodeMap_.emplace(surfaceNode->GetId(), surfaceNode->ReinterpretCastTo<RSSurfaceRenderNode>());
2339 }
2340 RectI surfaceDirtyRect = surfaceDirtyManager->GetCurrentFrameDirtyRegion();
2341 if (surfaceNode->IsTransparent()) {
2342 // Handles the case of transparent surface, merge transparent dirty rect
2343 RectI transparentDirtyRect = surfaceNode->GetDstRect().IntersectRect(surfaceDirtyRect);
2344 if (!transparentDirtyRect.IsEmpty()) {
2345 RS_OPTIONAL_TRACE_NAME_FMT("CalcDirtyDisplayRegion merge transparent dirty rect %s rect %s",
2346 surfaceNode->GetName().c_str(), transparentDirtyRect.ToString().c_str());
2347 displayDirtyManager->MergeDirtyRect(transparentDirtyRect);
2348 }
2349 }
2350
2351 if (surfaceNode->GetZorderChanged()) {
2352 // Zorder changed case, merge surface dest Rect
2353 RS_LOGD("CalcDirtyDisplayRegion merge GetZorderChanged %s rect %s", surfaceNode->GetName().c_str(),
2354 surfaceNode->GetDstRect().ToString().c_str());
2355 displayDirtyManager->MergeDirtyRect(surfaceNode->GetDstRect());
2356 }
2357
2358 RectI lastFrameSurfacePos = node->GetLastFrameSurfacePos(surfaceNode->GetId());
2359 RectI currentFrameSurfacePos = node->GetCurrentFrameSurfacePos(surfaceNode->GetId());
2360 if (lastFrameSurfacePos != currentFrameSurfacePos) {
2361 RS_LOGD("CalcDirtyDisplayRegion merge surface pos changed %s lastFrameRect %s currentFrameRect %s",
2362 surfaceNode->GetName().c_str(), lastFrameSurfacePos.ToString().c_str(),
2363 currentFrameSurfacePos.ToString().c_str());
2364 if (!lastFrameSurfacePos.IsEmpty()) {
2365 displayDirtyManager->MergeDirtyRect(lastFrameSurfacePos);
2366 }
2367 if (!currentFrameSurfacePos.IsEmpty()) {
2368 displayDirtyManager->MergeDirtyRect(currentFrameSurfacePos);
2369 }
2370 }
2371
2372 bool isShadowDisappear = !surfaceNode->GetRenderProperties().IsShadowValid() && surfaceNode->IsShadowValidLastFrame();
2373 if (surfaceNode->GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2374 RectI shadowDirtyRect = surfaceNode->GetOldDirtyInSurface().IntersectRect(surfaceDirtyRect);
2375 // There are two situation here:
2376 // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2377 // surfaceDirtyRect == surfaceNode->GetOldDirtyInSurface()
2378 // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2379 // surfaceDirtyRect > surfaceNode->GetOldDirtyInSurface()
2380 // So we should always merge surfaceDirtyRect here.
2381 if (!shadowDirtyRect.IsEmpty()) {
2382 displayDirtyManager->MergeDirtyRect(surfaceDirtyRect);
2383 RS_LOGD("CalcDirtyDisplayRegion merge ShadowValid %s rect %s",
2384 surfaceNode->GetName().c_str(), surfaceDirtyRect.ToString().c_str());
2385 }
2386 if (isShadowDisappear) {
2387 surfaceNode->SetShadowValidLastFrame(false);
2388 }
2389 }
2390 }
2391 std::vector<RectI> surfaceChangedRects = node->GetSurfaceChangedRects();
2392 for (auto& surfaceChangedRect : surfaceChangedRects) {
2393 RS_LOGD("CalcDirtyDisplayRegion merge Surface closed %s", surfaceChangedRect.ToString().c_str());
2394 if (!surfaceChangedRect.IsEmpty()) {
2395 displayDirtyManager->MergeDirtyRect(surfaceChangedRect);
2396 }
2397 }
2398 RS_OPTIONAL_TRACE_FUNC_END();
2399 }
2400
2401 void RSUniRenderVisitor::MergeDirtyRectIfNeed(std::shared_ptr<RSSurfaceRenderNode> appNode,
2402 std::shared_ptr<RSSurfaceRenderNode> hwcNode)
2403 {
2404 if ((hwcNode->IsLastFrameHardwareEnabled() || hwcNode->IsCurrentFrameBufferConsumed()) &&
2405 appNode && appNode->GetDirtyManager()) {
2406 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
2407 dirtySurfaceNodeMap_.emplace(appNode->GetId(), appNode);
2408 }
2409 }
2410
2411 RectI RSUniRenderVisitor::UpdateHardwareEnableList(std::vector<RectI>& filterRects,
2412 std::vector<SurfaceDirtyMgrPair>& validHwcNodes)
2413 {
2414 if (validHwcNodes.empty() || filterRects.empty()) {
2415 return RectI();
2416 }
2417 // remove invisible surface since occlusion
2418 // check intersected parts
2419 RectI filterDirty;
2420 for (auto iter = validHwcNodes.begin(); iter != validHwcNodes.end(); ++iter) {
2421 auto childNode = iter->first;
2422 auto childDirtyRect = childNode->GetDstRect();
2423 bool isIntersected = false;
2424 // remove invisible surface since occlusion
2425 for (auto filterRect : filterRects) {
2426 if (!childDirtyRect.IntersectRect(filterRect).IsEmpty()) {
2427 filterDirty = filterDirty.JoinRect(filterRect);
2428 isIntersected = true;
2429 }
2430 }
2431 if (isIntersected) {
2432 childNode->SetHardwareForcedDisabledStateByFilter(true);
2433 auto node = iter->second;
2434 MergeDirtyRectIfNeed(iter->second, childNode);
2435 iter = validHwcNodes.erase(iter);
2436 iter--;
2437 }
2438 }
2439 return filterDirty;
2440 }
2441
2442 void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode>& node,
2443 std::vector<SurfaceDirtyMgrPair>& prevHwcEnabledNodes,
2444 std::shared_ptr<RSDirtyRegionManager>& displayDirtyManager)
2445 {
2446 if (!IsHardwareComposerEnabled()) {
2447 return;
2448 }
2449 if (node == nullptr || !node->IsAppWindow() || node->GetDirtyManager() == nullptr ||
2450 displayDirtyManager == nullptr) {
2451 return;
2452 }
2453 auto dirtyManager = node->GetDirtyManager();
2454 auto filterRects = node->GetChildrenNeedFilterRects();
2455 // collect valid hwc surface which is not intersected with filterRects
2456 std::vector<SurfaceDirtyMgrPair> curHwcEnabledNodes;
2457 // remove invisible surface since occlusion
2458 auto visibleRegion = node->GetVisibleRegion();
2459 for (auto subNode : node->GetChildHardwareEnabledNodes()) {
2460 if (auto childNode = subNode.lock()) {
2461 // recover disabled state before update
2462 childNode->SetHardwareForcedDisabledStateByFilter(false);
2463 if (visibleRegion.IsIntersectWith(Occlusion::Rect(childNode->GetOldDirtyInSurface()))) {
2464 curHwcEnabledNodes.emplace_back(std::make_pair(subNode, node));
2465 }
2466 }
2467 }
2468 // Within App: disable hwc if intersect with filterRects
2469 dirtyManager->MergeDirtyRect(UpdateHardwareEnableList(filterRects, curHwcEnabledNodes));
2470 // Among App: disable lower hwc layers if intersect with upper transparent appWindow
2471 if (node->IsTransparent()) {
2472 if (node->GetRenderProperties().NeedFilter()) {
2473 // Attention: if transparent appwindow needs filter, only need to check itself
2474 filterRects = {node->GetDstRect()};
2475 }
2476 // In case of transparent window, filterRects need hwc surface's content
2477 RectI globalTransDirty = UpdateHardwareEnableList(filterRects, prevHwcEnabledNodes);
2478 displayDirtyManager->MergeDirtyRect(globalTransDirty);
2479 dirtyManager->MergeDirtyRect(globalTransDirty);
2480 }
2481 // erase from curHwcEnabledNodes if app node has no container window and its hwc node intersects with hwc below
2482 if (!node->HasContainerWindow() && !curHwcEnabledNodes.empty() && !prevHwcEnabledNodes.empty()) {
2483 for (auto iter = curHwcEnabledNodes.begin(); iter != curHwcEnabledNodes.end(); ++iter) {
2484 for (auto& prevNode : prevHwcEnabledNodes) {
2485 if (!iter->first->GetDstRect().IntersectRect(prevNode.first->GetDstRect()).IsEmpty()) {
2486 iter->first->SetHardwareForcedDisabledStateByFilter(true);
2487 MergeDirtyRectIfNeed(iter->second, iter->first);
2488 iter = curHwcEnabledNodes.erase(iter);
2489 iter--;
2490 break;
2491 }
2492 }
2493 }
2494 }
2495 if (!curHwcEnabledNodes.empty()) {
2496 prevHwcEnabledNodes.insert(prevHwcEnabledNodes.end(), curHwcEnabledNodes.begin(), curHwcEnabledNodes.end());
2497 }
2498 }
2499
2500 void RSUniRenderVisitor::CalcDirtyRegionForFilterNode(const RectI filterRect,
2501 std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode,
2502 std::shared_ptr<RSDisplayRenderNode>& displayNode)
2503 {
2504 auto displayDirtyManager = displayNode->GetDirtyManager();
2505 auto currentSurfaceDirtyManager = currentSurfaceNode->GetDirtyManager();
2506 if (displayDirtyManager == nullptr || currentSurfaceDirtyManager == nullptr) {
2507 return;
2508 }
2509
2510 RectI displayDirtyRect = displayDirtyManager->GetCurrentFrameDirtyRegion();
2511 RectI currentSurfaceDirtyRect = currentSurfaceDirtyManager->GetCurrentFrameDirtyRegion();
2512
2513 if (!displayDirtyRect.IntersectRect(filterRect).IsEmpty() ||
2514 !currentSurfaceDirtyRect.IntersectRect(filterRect).IsEmpty()) {
2515 currentSurfaceDirtyManager->MergeDirtyRect(filterRect);
2516 }
2517
2518 if (currentSurfaceNode->IsTransparent()) {
2519 if (!displayDirtyRect.IntersectRect(filterRect).IsEmpty()) {
2520 displayDirtyManager->MergeDirtyRect(filterRect);
2521 return;
2522 }
2523 // If currentSurfaceNode is transparent and displayDirtyRect is not intersect with filterRect,
2524 // We should check whether window below currentSurfaceNode has dirtyRect intersect with filterRect.
2525 for (auto belowSurface = displayNode->GetCurAllSurfaces().begin();
2526 belowSurface != displayNode->GetCurAllSurfaces().end(); ++belowSurface) {
2527 auto belowSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*belowSurface);
2528 if (belowSurfaceNode == currentSurfaceNode) {
2529 break;
2530 }
2531 if (belowSurfaceNode == nullptr || !belowSurfaceNode->IsAppWindow()) {
2532 continue;
2533 }
2534 auto belowSurfaceDirtyManager = belowSurfaceNode->GetDirtyManager();
2535 RectI belowDirtyRect =
2536 belowSurfaceDirtyManager ? belowSurfaceDirtyManager->GetCurrentFrameDirtyRegion() : RectI{0, 0, 0, 0};
2537 if (belowDirtyRect.IsEmpty()) {
2538 continue;
2539 }
2540 // To minimize dirtyRect, only filterRect has intersect with both visibleRegion and dirtyRect
2541 // of window below, we add filterRect to displayDirtyRect and currentSurfaceDirtyRect.
2542 if (belowSurfaceNode->GetVisibleRegion().IsIntersectWith(filterRect) &&
2543 !belowDirtyRect.IntersectRect(filterRect).IsEmpty()) {
2544 displayDirtyManager->MergeDirtyRect(filterRect);
2545 currentSurfaceDirtyManager->MergeDirtyRect(filterRect);
2546 break;
2547 }
2548 }
2549 }
2550 }
2551
2552 void RSUniRenderVisitor::CalcDirtyFilterRegion(std::shared_ptr<RSDisplayRenderNode>& displayNode)
2553 {
2554 if (displayNode == nullptr || displayNode->GetDirtyManager() == nullptr) {
2555 return;
2556 }
2557 auto displayDirtyManager = displayNode->GetDirtyManager();
2558 std::vector<SurfaceDirtyMgrPair> prevHwcEnabledNodes;
2559 for (auto it = displayNode->GetCurAllSurfaces().begin(); it != displayNode->GetCurAllSurfaces().end(); ++it) {
2560 auto currentSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2561 if (currentSurfaceNode == nullptr) {
2562 continue;
2563 }
2564 auto currentSurfaceDirtyManager = currentSurfaceNode->GetDirtyManager();
2565 // [planning] Update hwc surface dirty status at the same time
2566 UpdateHardwareNodeStatusBasedOnFilter(currentSurfaceNode, prevHwcEnabledNodes, displayDirtyManager);
2567
2568 // child node (component) has filter
2569 auto filterRects = currentSurfaceNode->GetChildrenNeedFilterRects();
2570 if (currentSurfaceNode->IsAppWindow() && !filterRects.empty()) {
2571 needFilter_ = needFilter_ || !currentSurfaceNode->IsStaticCached();
2572 for (auto filterRect : filterRects) {
2573 CalcDirtyRegionForFilterNode(
2574 filterRect, currentSurfaceNode, displayNode);
2575 }
2576 }
2577 // surfaceNode self has filter
2578 if (currentSurfaceNode->GetRenderProperties().NeedFilter()) {
2579 needFilter_ = needFilter_ || !currentSurfaceNode->IsStaticCached();
2580 CalcDirtyRegionForFilterNode(
2581 currentSurfaceNode->GetOldDirtyInSurface(), currentSurfaceNode, displayNode);
2582 }
2583 }
2584 for (auto& [childNode, node] : prevHwcEnabledNodes) {
2585 if (!childNode->IsLastFrameHardwareEnabled() && node && node->GetDirtyManager()) {
2586 node->GetDirtyManager()->MergeDirtyRect(childNode->GetDstRect());
2587 dirtySurfaceNodeMap_.emplace(node->GetId(), node);
2588 }
2589 }
2590 }
2591
2592 void RSUniRenderVisitor::AddContainerDirtyToGlobalDirty(std::shared_ptr<RSDisplayRenderNode>& node) const
2593 {
2594 RS_OPTIONAL_TRACE_FUNC_BEGIN();
2595 auto displayDirtyManager = node->GetDirtyManager();
2596 for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
2597 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2598 if (surfaceNode == nullptr) {
2599 continue;
2600 }
2601 auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
2602 if (surfaceDirtyManager == nullptr) {
2603 continue;
2604 }
2605 RectI surfaceDirtyRect = surfaceDirtyManager->GetCurrentFrameDirtyRegion();
2606
2607 if (surfaceNode->HasContainerWindow()) {
2608 // If a surface's dirty is intersect with container region (which can be considered transparent)
2609 // should be added to display dirty region.
2610 // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2611 auto containerRegion = surfaceNode->GetContainerRegion();
2612 auto surfaceDirtyRegion = Occlusion::Region{Occlusion::Rect{surfaceDirtyRect}};
2613 auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2614 if (!containerDirtyRegion.IsEmpty()) {
2615 RS_LOGD("CalcDirtyDisplayRegion merge containerDirtyRegion %s region %s",
2616 surfaceNode->GetName().c_str(), containerDirtyRegion.GetRegionInfo().c_str());
2617 // plan: we can use surfacenode's absrect as containerRegion's bound
2618 const auto& rect = containerRegion.GetBoundRef();
2619 displayDirtyManager->MergeDirtyRect(
2620 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2621 }
2622 } else {
2623 // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2624 // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
2625 // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2626 // which include transparent region but not counted in display dirtyregion)
2627 auto transparentRegion = surfaceNode->GetTransparentRegion();
2628 Occlusion::Rect tmpRect = Occlusion::Rect { surfaceDirtyRect.left_, surfaceDirtyRect.top_,
2629 surfaceDirtyRect.GetRight(), surfaceDirtyRect.GetBottom() };
2630 Occlusion::Region surfaceDirtyRegion { tmpRect };
2631 Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
2632 if (!transparentDirtyRegion.IsEmpty()) {
2633 RS_LOGD("CalcDirtyDisplayRegion merge TransparentDirtyRegion %s region %s",
2634 surfaceNode->GetName().c_str(), transparentDirtyRegion.GetRegionInfo().c_str());
2635 const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
2636 for (const auto& rect : rects) {
2637 displayDirtyManager->MergeDirtyRect(
2638 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2639 }
2640 }
2641 }
2642 }
2643 RS_OPTIONAL_TRACE_FUNC_END();
2644 }
2645
2646 void RSUniRenderVisitor::SetSurfaceGlobalDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node)
2647 {
2648 RS_OPTIONAL_TRACE_FUNC_BEGIN();
2649 for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
2650 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2651 if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
2652 continue;
2653 }
2654 // set display dirty region to surfaceNode
2655 surfaceNode->SetGlobalDirtyRegion(node->GetDirtyManager()->GetDirtyRegion());
2656 surfaceNode->SetDirtyRegionAlignedEnable(false);
2657 }
2658 Occlusion::Region curVisibleDirtyRegion;
2659 for (auto& it : node->GetCurAllSurfaces()) {
2660 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(it);
2661 if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
2662 continue;
2663 }
2664 // set display dirty region to surfaceNode
2665 surfaceNode->SetDirtyRegionBelowCurrentLayer(curVisibleDirtyRegion);
2666 auto visibleDirtyRegion = surfaceNode->GetVisibleDirtyRegion();
2667 curVisibleDirtyRegion = curVisibleDirtyRegion.Or(visibleDirtyRegion);
2668 }
2669 RS_OPTIONAL_TRACE_FUNC_END();
2670 }
2671
2672 void RSUniRenderVisitor::SetSurfaceGlobalAlignedDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node,
2673 const Occlusion::Region alignedDirtyRegion)
2674 {
2675 RS_TRACE_FUNC();
2676 if (!isDirtyRegionAlignedEnable_) {
2677 return;
2678 }
2679 // calculate extra dirty region after 32 bits alignment
2680 Occlusion::Region dirtyRegion = alignedDirtyRegion;
2681 auto globalRectI = node->GetDirtyManager()->GetDirtyRegion();
2682 Occlusion::Rect globalRect {globalRectI.left_, globalRectI.top_, globalRectI.GetRight(), globalRectI.GetBottom()};
2683 Occlusion::Region globalRegion{globalRect};
2684 dirtyRegion.SubSelf(globalRegion);
2685 for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
2686 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2687 if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
2688 continue;
2689 }
2690 surfaceNode->SetGlobalDirtyRegion(node->GetDirtyManager()->GetDirtyRegion());
2691 Occlusion::Region visibleRegion = surfaceNode->GetVisibleRegion();
2692 Occlusion::Region surfaceAlignedDirtyRegion = surfaceNode->GetAlignedVisibleDirtyRegion();
2693 if (dirtyRegion.IsEmpty()) {
2694 surfaceNode->SetExtraDirtyRegionAfterAlignment(dirtyRegion);
2695 } else {
2696 auto extraDirtyRegion = (dirtyRegion.Sub(surfaceAlignedDirtyRegion)).And(visibleRegion);
2697 surfaceNode->SetExtraDirtyRegionAfterAlignment(extraDirtyRegion);
2698 }
2699 surfaceNode->SetDirtyRegionAlignedEnable(true);
2700 }
2701 Occlusion::Region curVisibleDirtyRegion;
2702 for (auto& it : node->GetCurAllSurfaces()) {
2703 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(it);
2704 if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
2705 continue;
2706 }
2707 surfaceNode->SetDirtyRegionBelowCurrentLayer(curVisibleDirtyRegion);
2708 auto alignedVisibleDirtyRegion = surfaceNode->GetAlignedVisibleDirtyRegion();
2709 curVisibleDirtyRegion.OrSelf(alignedVisibleDirtyRegion);
2710 }
2711 }
2712
2713 void RSUniRenderVisitor::AlignGlobalAndSurfaceDirtyRegions(std::shared_ptr<RSDisplayRenderNode>& node)
2714 {
2715 node->GetDirtyManager()->UpdateDirtyByAligned();
2716 for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
2717 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2718 if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
2719 continue;
2720 }
2721 surfaceNode->GetDirtyManager()->UpdateDirtyByAligned();
2722 }
2723 }
2724
2725 #ifdef RS_ENABLE_EGLQUERYSURFACE
2726 std::vector<RectI> RSUniRenderVisitor::GetDirtyRects(const Occlusion::Region ®ion)
2727 {
2728 const std::vector<Occlusion::Rect>& rects = region.GetRegionRects();
2729 std::vector<RectI> retRects;
2730 for (const Occlusion::Rect& rect : rects) {
2731 // origin transformation
2732 retRects.emplace_back(RectI(rect.left_, screenInfo_.GetRotatedHeight() - rect.bottom_,
2733 rect.right_ - rect.left_, rect.bottom_ - rect.top_));
2734 }
2735 RS_LOGD("GetDirtyRects size %d %s", region.GetSize(), region.GetRegionInfo().c_str());
2736 return retRects;
2737 }
2738 #endif
2739
2740 void RSUniRenderVisitor::CheckAndSetNodeCacheType(RSRenderNode& node)
2741 {
2742 if (node.IsStaticCached()) {
2743 if (node.GetCacheType() != CacheType::CONTENT) {
2744 node.SetCacheType(CacheType::CONTENT);
2745 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
2746 }
2747
2748 if (!node.GetCompletedCacheSurface(threadIndex_, true) && UpdateCacheSurface(node)) {
2749 node.UpdateCompletedCacheSurface();
2750 }
2751 } else if (isDrawingCacheEnabled_ && GenerateNodeContentCache(node)) {
2752 UpdateCacheRenderNodeMapWithBlur(node);
2753 } else {
2754 node.SetCacheType(CacheType::NONE);
2755 if (node.GetCompletedCacheSurface(threadIndex_, false)) {
2756 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
2757 }
2758 }
2759 }
2760
2761 bool RSUniRenderVisitor::UpdateCacheSurface(RSRenderNode& node)
2762 {
2763 RS_TRACE_NAME_FMT("UpdateCacheSurface: [%llu]", node.GetId());
2764 CacheType cacheType = node.GetCacheType();
2765 if (cacheType == CacheType::NONE) {
2766 return false;
2767 }
2768
2769 if (!node.GetCacheSurface(threadIndex_, true)) {
2770 RSRenderNode::ClearCacheSurfaceFunc func = std::bind(&RSUniRenderUtil::ClearNodeCacheSurface,
2771 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
2772 #ifndef USE_ROSEN_DRAWING
2773 #ifdef NEW_SKIA
2774 node.InitCacheSurface(canvas_ ? canvas_->recordingContext() : nullptr, func, threadIndex_);
2775 #else
2776 node.InitCacheSurface(canvas_ ? canvas_->getGrContext() : nullptr, func, threadIndex_);
2777 #endif
2778 #else
2779 node.InitCacheSurface(canvas_ ? canvas_->GetGPUContext().get() : nullptr, func, threadIndex_);
2780 #endif
2781 }
2782
2783 if (node.GetCacheSurface(threadIndex_, true) == nullptr) {
2784 RS_LOGE("Get CacheSurface failed");
2785 return false;
2786 }
2787 auto cacheCanvas = std::make_shared<RSPaintFilterCanvas>(node.GetCacheSurface(threadIndex_, true).get());
2788 if (!cacheCanvas) {
2789 return false;
2790 }
2791
2792 // copy current canvas properties into cacheCanvas
2793 if (renderEngine_) {
2794 cacheCanvas->SetHighContrast(renderEngine_->IsHighContrastEnabled());
2795 }
2796 if (canvas_) {
2797 cacheCanvas->CopyConfiguration(*canvas_);
2798 }
2799
2800 // When drawing CacheSurface, all child node should be drawn.
2801 // So set isOpDropped_ = false here.
2802 bool isOpDropped = isOpDropped_;
2803 isOpDropped_ = false;
2804 isUpdateCachedSurface_ = true;
2805
2806 #ifndef USE_ROSEN_DRAWING
2807 cacheCanvas->clear(SK_ColorTRANSPARENT);
2808 #else
2809 cacheCanvas->DrawBackground(Drawing::Color::COLOR_TRANSPARENT);
2810 #endif
2811
2812 swap(cacheCanvas, canvas_);
2813 // When cacheType == CacheType::ANIMATE_PROPERTY,
2814 // we should draw AnimateProperty on cacheCanvas
2815 if (cacheType == CacheType::ANIMATE_PROPERTY) {
2816 if (node.GetRenderProperties().IsShadowValid()
2817 && !node.GetRenderProperties().IsSpherizeValid()) {
2818 #ifndef USE_ROSEN_DRAWING
2819 canvas_->save();
2820 canvas_->translate(node.GetShadowRectOffsetX(), node.GetShadowRectOffsetY());
2821 #else
2822 canvas_->Save();
2823 canvas_->Translate(node.GetShadowRectOffsetX(), node.GetShadowRectOffsetY());
2824 #endif
2825 }
2826 node.ProcessAnimatePropertyBeforeChildren(*canvas_);
2827 }
2828
2829 node.ProcessRenderContents(*canvas_);
2830 ProcessChildren(node);
2831
2832 if (cacheType == CacheType::ANIMATE_PROPERTY) {
2833 if (node.GetRenderProperties().IsShadowValid()
2834 && !node.GetRenderProperties().IsSpherizeValid()) {
2835 #ifndef USE_ROSEN_DRAWING
2836 canvas_->restore();
2837 #else
2838 canvas_->Restore();
2839 #endif
2840 }
2841 node.ProcessAnimatePropertyAfterChildren(*canvas_);
2842 }
2843 swap(cacheCanvas, canvas_);
2844
2845 isUpdateCachedSurface_ = false;
2846 isOpDropped_ = isOpDropped;
2847
2848 // To get all FreezeNode
2849 // execute: "param set rosen.dumpsurfacetype.enabled 2 && setenforce 0"
2850 // To get specific FreezeNode
2851 // execute: "param set rosen.dumpsurfacetype.enabled 1 && setenforce 0 && "
2852 // "param set rosen.dumpsurfaceid "NodeId" "
2853 // Png file could be found in /data
2854 RSBaseRenderUtil::WriteCacheRenderNodeToPng(node);
2855 return true;
2856 }
2857
2858 void RSUniRenderVisitor::DrawSpherize(RSRenderNode& node)
2859 {
2860 if (node.GetCacheType() != CacheType::ANIMATE_PROPERTY) {
2861 node.SetCacheType(CacheType::ANIMATE_PROPERTY);
2862 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
2863 }
2864 if (!node.GetCompletedCacheSurface(threadIndex_, true) && UpdateCacheSurface(node)) {
2865 node.UpdateCompletedCacheSurface();
2866 }
2867 node.ProcessTransitionBeforeChildren(*canvas_);
2868 RSPropertiesPainter::DrawSpherize(
2869 node.GetRenderProperties(), *canvas_, node.GetCompletedCacheSurface(threadIndex_, true));
2870 node.ProcessTransitionAfterChildren(*canvas_);
2871 }
2872
2873 bool RSUniRenderVisitor::DrawBlurInCache(RSRenderNode& node) {
2874 if (!curCacheFilterRects_.empty()) {
2875 if (curCacheFilterRects_.top().count(node.GetId())) {
2876 if (curGroupedNodes_.empty()) {
2877 // draw filter before drawing cached surface
2878 curCacheFilterRects_.top().erase(node.GetId());
2879 if (curCacheFilterRects_.empty() || !node.ChildHasFilter()) {
2880 // no filter to draw, return
2881 return true;
2882 }
2883 } else if (node.GetRenderProperties().GetBackgroundFilter() || node.GetRenderProperties().GetUseEffect()) {
2884 // clear hole while generating cache surface
2885 SkAutoCanvasRestore arc(canvas_.get(), true);
2886 canvas_->clipRect(RSPropertiesPainter::Rect2SkRect(node.GetRenderProperties().GetBoundsRect()));
2887 canvas_->clear(SK_ColorTRANSPARENT);
2888 }
2889 } else if (curGroupedNodes_.empty() && !node.ChildHasFilter()) {
2890 // no filter to draw, return
2891 return true;
2892 }
2893 }
2894 return false;
2895 }
2896
2897 void RSUniRenderVisitor::DrawChildCanvasRenderNode(RSRenderNode& node)
2898 {
2899 if (node.IsPureContainer() && node.GetCacheType() == CacheType::NONE) {
2900 processedPureContainerNode_++;
2901 node.ApplyBoundsGeometry(*canvas_);
2902 ProcessChildren(node);
2903 node.RSRenderNode::ProcessTransitionAfterChildren(*canvas_);
2904 return;
2905 }
2906 DrawChildRenderNode(node);
2907 }
2908
2909 void RSUniRenderVisitor::DrawChildRenderNode(RSRenderNode& node)
2910 {
2911 CacheType cacheType = node.GetCacheType();
2912 node.ProcessTransitionBeforeChildren(*canvas_);
2913 switch (cacheType) {
2914 case CacheType::NONE: {
2915 auto preCache = canvas_->GetCacheType();
2916 if (node.HasCacheableAnim() && isDrawingCacheEnabled_) {
2917 canvas_->SetCacheType(RSPaintFilterCanvas::CacheType::ENABLED);
2918 }
2919 node.ProcessAnimatePropertyBeforeChildren(*canvas_);
2920 node.ProcessRenderContents(*canvas_);
2921 if (!DrawBlurInCache(node)) {
2922 ProcessChildren(node);
2923 }
2924 node.ProcessAnimatePropertyAfterChildren(*canvas_);
2925 if (node.HasCacheableAnim() && isDrawingCacheEnabled_) {
2926 canvas_->SetCacheType(preCache);
2927 }
2928 break;
2929 }
2930 case CacheType::CONTENT: {
2931 node.ProcessAnimatePropertyBeforeChildren(*canvas_);
2932 node.DrawCacheSurface(*canvas_, threadIndex_, false);
2933 node.ProcessAnimatePropertyAfterChildren(*canvas_);
2934 cacheRenderNodeMapRects_.push_back(node.GetOldDirtyInSurface());
2935 break;
2936 }
2937 case CacheType::ANIMATE_PROPERTY: {
2938 node.DrawCacheSurface(*canvas_, threadIndex_, false);
2939 break;
2940 }
2941 default:
2942 break;
2943 }
2944 node.ProcessTransitionAfterChildren(*canvas_);
2945 }
2946
2947 bool RSUniRenderVisitor::CheckIfSurfaceRenderNodeNeedProcess(RSSurfaceRenderNode& node)
2948 {
2949 if (isSubThread_) {
2950 return true;
2951 }
2952 if (isSecurityDisplay_ && node.GetSecurityLayer()) {
2953 RS_OPTIONAL_TRACE_NAME(node.GetName() + " SecurityLayer Skip");
2954 return false;
2955 }
2956 if (!node.ShouldPaint()) {
2957 MarkSubHardwareEnableNodeState(node);
2958 RS_LOGD("RSUniRenderVisitor::IfSurfaceRenderNodeNeedProcess node: %" PRIu64 " invisible", node.GetId());
2959 return false;
2960 }
2961 if (!node.GetOcclusionVisible() && !doAnimate_ && isOcclusionEnabled_ && !isSecurityDisplay_) {
2962 MarkSubHardwareEnableNodeState(node);
2963 RS_OPTIONAL_TRACE_NAME(node.GetName() + " Occlusion Skip");
2964 return false;
2965 }
2966 if (node.IsAbilityComponent() && node.GetDstRect().IsEmpty()) {
2967 RS_OPTIONAL_TRACE_NAME(node.GetName() + " Empty AbilityComponent Skip");
2968 return false;
2969 }
2970 std::shared_ptr<RSSurfaceRenderNode> appNode;
2971 if (node.LeashWindowRelatedAppWindowOccluded(appNode)) {
2972 if (appNode != nullptr) {
2973 MarkSubHardwareEnableNodeState(*appNode);
2974 }
2975 RS_OPTIONAL_TRACE_NAME(node.GetName() + " App Occluded Leashwindow Skip");
2976 return false;
2977 }
2978 return true;
2979 }
2980
2981 void RSUniRenderVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
2982 {
2983 if (isUIFirst_ && isSubThread_) {
2984 if (auto parentNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(node.GetParent().lock()) ||
2985 (Rosen::SceneBoardJudgement::IsSceneBoardEnabled() && node.IsLeashWindow())) {
2986 UpdateCacheSurface(node);
2987 return;
2988 }
2989 }
2990 if (RSSystemProperties::GetProxyNodeDebugEnabled() && node.contextClipRect_.has_value() && canvas_ != nullptr) {
2991 // draw transparent red rect to indicate valid clip area
2992 {
2993 RSAutoCanvasRestore acr(canvas_);
2994 #ifndef USE_ROSEN_DRAWING
2995 canvas_->concat(node.contextMatrix_.value_or(SkMatrix::I()));
2996 SkPaint paint;
2997 paint.setARGB(0x80, 0xFF, 0, 0); // transparent red
2998 canvas_->drawRect(node.contextClipRect_.value(), paint);
2999 #else
3000 canvas_->ConcatMatrix(node.contextMatrix_.value_or(Drawing::Matrix()));
3001 Drawing::Brush brush;
3002 brush.SetARGB(0xFF, 0, 0, 0x80); // transparent red
3003 canvas_->AttachBrush(brush);
3004 canvas_->DrawRect(node.contextClipRect_.value());
3005 canvas_->DetachBrush();
3006 #endif
3007 }
3008 // make this node context transparent
3009 canvas_->MultiplyAlpha(0.5);
3010 }
3011 RS_TRACE_NAME("RSUniRender::Process:[" + node.GetName() + "]" + " " + node.GetDstRect().ToString()
3012 + " Alpha: " + std::to_string(node.GetGlobalAlpha()).substr(0, 4));
3013 RS_LOGD("RSUniRenderVisitor::ProcessSurfaceRenderNode node:%" PRIu64 ",child size:%u,name:%s,OcclusionVisible:%d",
3014 node.GetId(), node.GetChildrenCount(), node.GetName().c_str(), node.GetOcclusionVisible());
3015 #ifdef RS_ENABLE_GL
3016 #ifndef USE_ROSEN_DRAWING
3017 #ifdef NEW_RENDER_CONTEXT
3018 auto grContext = renderEngine_->GetDrawingContext()->GetDrawingContext();
3019 #else
3020 auto grContext = canvas_ != nullptr ? static_cast<GrDirectContext*>(canvas_->recordingContext()) : nullptr;
3021 #endif
3022 RSTagTracker tagTracker(grContext, node.GetId(), RSTagTracker::TAGTYPE::TAG_DRAW_SURFACENODE);
3023 node.SetGrContext(grContext);
3024 #else
3025 Drawing::GPUContext* gpuContext = renderEngine_->GetRenderContext()->GetDrGPUContext();
3026 node.SetDrawingGPUContext(gpuContext);
3027 #endif
3028 #endif
3029 if (!CheckIfSurfaceRenderNodeNeedProcess(node)) {
3030 return;
3031 }
3032 if (node.IsAppWindow()) {
3033 curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
3034 AdjustLocalZOrder(curSurfaceNode_);
3035 }
3036 #ifdef RS_ENABLE_EGLQUERYSURFACE
3037 // skip clean surface node
3038 if (isOpDropped_ && node.IsAppWindow() &&
3039 !node.SubNodeNeedDraw(node.GetOldDirtyInSurface(), partialRenderType_)) {
3040 RS_OPTIONAL_TRACE_NAME(node.GetName() + " QuickReject Skip");
3041 RS_LOGD("RSUniRenderVisitor::ProcessSurfaceRenderNode skip: %s", node.GetName().c_str());
3042 return;
3043 }
3044 #endif
3045 if (!canvas_) {
3046 RS_LOGE("RSUniRenderVisitor::ProcessSurfaceRenderNode, canvas is nullptr");
3047 return;
3048 }
3049 const auto& property = node.GetRenderProperties();
3050 auto geoPtr = (property.GetBoundsGeometry());
3051 if (!geoPtr) {
3052 RS_LOGE("RSUniRenderVisitor::ProcessSurfaceRenderNode node:%" PRIu64 ", get geoPtr failed", node.GetId());
3053 return;
3054 }
3055
3056 #ifdef RS_ENABLE_EGLQUERYSURFACE
3057 // when display is in rotation state, occlusion relationship will be ruined,
3058 // hence visibleRegions cannot be used.
3059 if (isOpDropped_ && node.IsAppWindow()) {
3060 const auto& visibleRegions = node.GetVisibleRegion().GetRegionRects();
3061 if (visibleRegions.size() == 1) {
3062 #ifndef USE_ROSEN_DRAWING
3063 canvas_->SetVisibleRect(SkRect::MakeLTRB(
3064 visibleRegions[0].left_, visibleRegions[0].top_, visibleRegions[0].right_, visibleRegions[0].bottom_));
3065 #else
3066 canvas_->SetVisibleRect(Drawing::Rect(
3067 visibleRegions[0].left_, visibleRegions[0].top_, visibleRegions[0].right_, visibleRegions[0].bottom_));
3068 #endif
3069 }
3070 }
3071 #endif
3072
3073 // when surfacenode named "CapsuleWindow", cache the current canvas as SkImage for screen recording
3074 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos &&
3075 canvas_->GetSurface() != nullptr && needCacheImg_) {
3076 #ifndef USE_ROSEN_DRAWING
3077 int angle = RSUniRenderUtil::GetRotationFromMatrix(canvas_->getTotalMatrix());
3078 resetRotate_ = angle != 0 && angle % 90 == 0;
3079 cacheImgForCapture_ = canvas_->GetSurface()->makeImageSnapshot();
3080 #else
3081 int angle = RSUniRenderUtil::GetRotationFromMatrix(canvas_->GetTotalMatrix());
3082 resetRotate_ = angle != 0 && angle % 90 == 0;
3083 cacheImgForCapture_ = canvas_->GetSurface()->GetImageSnapshot();
3084 #endif
3085 }
3086
3087 if (node.GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
3088 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
3089 auto screenNum = screenManager->GetAllScreenIds().size();
3090 needColdStartThread_ = RSSystemProperties::GetColdStartThreadEnabled() &&
3091 !node.IsStartAnimationFinished() && doAnimate_ && screenNum <= 1;
3092 }
3093
3094 if (node.IsAppWindow() && needColdStartThread_ &&
3095 !RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId())) {
3096 if (!IsFirstFrameReadyToDraw(node)) {
3097 return;
3098 }
3099 auto nodePtr = node.shared_from_this();
3100 RSColdStartManager::Instance().StartColdStartThreadIfNeed(nodePtr->ReinterpretCastTo<RSSurfaceRenderNode>());
3101 RecordAppWindowNodeAndPostTask(node, property.GetBoundsWidth(), property.GetBoundsHeight());
3102 return;
3103 }
3104
3105 RSAutoCanvasRestore acr(canvas_);
3106 auto bgAntiAliasState = RSPropertiesPainter::GetBgAntiAlias();
3107 if (doAnimate_ && (!ROSEN_EQ(geoPtr->GetScaleX(), 1.f) || !ROSEN_EQ(geoPtr->GetScaleY(), 1.f))) {
3108 // disable background antialias when surfacenode has scale animation
3109 RSPropertiesPainter::SetBgAntiAlias(false);
3110 }
3111
3112 canvas_->MultiplyAlpha(property.GetAlpha());
3113
3114 bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
3115 // [planning] surfaceNode use frame instead
3116 // This is for SELF_DRAWING_NODE like RosenRenderTexture
3117 // BoundsRect of RosenRenderTexture is the size of video, not the size of the component.
3118 // The size of RosenRenderTexture is the paintRect (always be set to FrameRect) which is not passed to RenderNode
3119 // because RSSurfaceRenderNode is designed only affected by BoundsRect.
3120 // When RosenRenderTexture has child node, child node is layouted
3121 // according to paintRect of RosenRenderTexture, not the BoundsRect.
3122 // So when draw SELF_DRAWING_NODE, we should save canvas
3123 // to avoid child node being layout according to the BoundsRect of RosenRenderTexture.
3124 // Temporarily, we use parent of SELF_DRAWING_NODE which has the same paintRect with its child instead.
3125 // to draw child node of SELF_DRAWING_NODE
3126 #ifndef USE_ROSEN_DRAWING
3127 if (isSelfDrawingSurface && !property.IsSpherizeValid()) {
3128 canvas_->save();
3129 }
3130
3131 canvas_->concat(geoPtr->GetMatrix());
3132 #else
3133 if (isSelfDrawingSurface && !property.IsSpherizeValid()) {
3134 canvas_->Save();
3135 }
3136
3137 canvas_->ConcatMatrix(geoPtr->GetMatrix());
3138 #endif
3139 bool isSubNodeOfSurfaceInProcess = isSubNodeOfSurfaceInProcess_;
3140 if (node.IsMainWindowType() || node.IsLeashWindow()) {
3141 isSubNodeOfSurfaceInProcess_ = true;
3142 }
3143 if (property.IsSpherizeValid()) {
3144 DrawSpherize(node);
3145 } else {
3146 if (isSelfDrawingSurface) {
3147 RSUniRenderUtil::FloorTransXYInCanvasMatrix(*canvas_);
3148 }
3149 if (isUIFirst_ && node.GetCacheType() == CacheType::ANIMATE_PROPERTY) {
3150 RSUniRenderUtil::HandleSubThreadNode(node, *canvas_);
3151 if (node.IsMainWindowType() || node.IsLeashWindow()) {
3152 isSubNodeOfSurfaceInProcess_ = isSubNodeOfSurfaceInProcess;
3153 }
3154 return;
3155 }
3156 node.ProcessRenderBeforeChildren(*canvas_);
3157 if (isUIFirst_ && RSUniRenderUtil::HandleSubThreadNode(node, *canvas_)) {
3158 node.ProcessRenderAfterChildren(*canvas_);
3159 if (node.IsMainWindowType() || node.IsLeashWindow()) {
3160 isSubNodeOfSurfaceInProcess_ = isSubNodeOfSurfaceInProcess;
3161 }
3162 return;
3163 }
3164 if (node.GetBuffer() != nullptr) {
3165 if (node.IsHardwareEnabledType()) {
3166 // since node has buffer, hwc disabledState could be reset by filter or surface cached
3167 node.SetHardwareForcedDisabledState(
3168 node.IsHardwareForcedDisabledByFilter() || canvas_->GetAlpha() < 1.f);
3169 node.SetHardwareDisabledByCache(isUpdateCachedSurface_);
3170 }
3171 // if this window is in freeze state, disable hardware composer for its child surfaceView
3172 if (IsHardwareComposerEnabled() && !node.IsHardwareForcedDisabled() && node.IsHardwareEnabledType()) {
3173 #ifndef USE_ROSEN_DRAWING
3174 canvas_->clear(SK_ColorTRANSPARENT);
3175 #else
3176 canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
3177 #endif
3178 node.SetGlobalAlpha(canvas_->GetAlpha());
3179 ParallelRenderEnableHardwareComposer(node);
3180
3181 {
3182 #ifndef USE_ROSEN_DRAWING
3183 SkAutoCanvasRestore acr(canvas_.get(), true);
3184
3185 if (displayNodeMatrix_.has_value()) {
3186 auto& displayNodeMatrix = displayNodeMatrix_.value();
3187 canvas_->concat(displayNodeMatrix);
3188 }
3189 node.SetTotalMatrix(canvas_->getTotalMatrix());
3190
3191 auto dstRect = node.GetDstRect();
3192 SkIRect dst = { dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetRight(), dstRect.GetBottom() };
3193 #else
3194 Drawing::AutoCanvasRestore acr(*canvas_.get(), true);
3195
3196 if (displayNodeMatrix_.has_value()) {
3197 auto& displayNodeMatrix = displayNodeMatrix_.value();
3198 displayNodeMatrix.PreConcat(canvas_->GetTotalMatrix());
3199 canvas_->SetMatrix(displayNodeMatrix);
3200 }
3201 node.SetTotalMatrix(canvas_->GetTotalMatrix());
3202
3203 auto dstRect = node.GetDstRect();
3204 Drawing::RectI dst = { dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetRight(),
3205 dstRect.GetBottom() };
3206 #endif
3207 node.UpdateSrcRect(*canvas_, dst);
3208 }
3209 RS_LOGD("RSUniRenderVisitor::ProcessSurfaceRenderNode src:%s, dst:%s name:%s id:%" PRIu64 "",
3210 node.GetSrcRect().ToString().c_str(), node.GetDstRect().ToString().c_str(),
3211 node.GetName().c_str(), node.GetId());
3212 } else {
3213 node.SetGlobalAlpha(1.0f);
3214 auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false, threadIndex_);
3215 renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
3216 }
3217 }
3218
3219 if (isSelfDrawingSurface) {
3220 #ifndef USE_ROSEN_DRAWING
3221 canvas_->restore();
3222 #else
3223 canvas_->Restore();
3224 #endif
3225 }
3226
3227 if (node.IsAppWindow() &&
3228 (!needColdStartThread_ || !RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId()))) {
3229 bool needDrawCachedImage = false;
3230 if (RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId())) {
3231 if (RSColdStartManager::Instance().IsColdStartThreadIdle(node.GetId())) {
3232 node.ClearCachedImage();
3233 RSColdStartManager::Instance().StopColdStartThread(node.GetId());
3234 } else {
3235 needDrawCachedImage = true;
3236 }
3237 }
3238 if (!node.IsNotifyUIBufferAvailable() && IsFirstFrameReadyToDraw(node)) {
3239 node.NotifyUIBufferAvailable();
3240 }
3241 if (!needDrawCachedImage || node.GetCachedImage() == nullptr) {
3242 CheckAndSetNodeCacheType(node);
3243 DrawChildRenderNode(node);
3244 } else {
3245 RS_LOGD("RSUniRenderVisitor cold start thread not idle, don't stop it, still use cached image");
3246 RSUniRenderUtil::DrawCachedImage(node, *canvas_, node.GetCachedImage());
3247 }
3248 } else if (node.IsAppWindow()) { // use skSurface drawn by cold start thread
3249 if (node.GetCachedImage() != nullptr) {
3250 RSUniRenderUtil::DrawCachedImage(node, *canvas_, node.GetCachedImage());
3251 }
3252 if (RSColdStartManager::Instance().IsColdStartThreadIdle(node.GetId())) {
3253 RecordAppWindowNodeAndPostTask(node, property.GetBoundsWidth(), property.GetBoundsHeight());
3254 } else {
3255 RS_LOGD("RSUniRenderVisitor cold start thread not idle, don't record this frame");
3256 }
3257 } else {
3258 ProcessChildren(node);
3259 }
3260
3261 if (node.GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
3262 // reset to default value
3263 needColdStartThread_ = false;
3264 }
3265
3266 node.ProcessRenderAfterChildren(*canvas_);
3267 }
3268
3269 RSPropertiesPainter::SetBgAntiAlias(bgAntiAliasState);
3270 if (node.IsAppWindow()) {
3271 #ifndef USE_ROSEN_DRAWING
3272 canvas_->SetVisibleRect(SkRect::MakeLTRB(0, 0, 0, 0));
3273 #else
3274 canvas_->SetVisibleRect(Drawing::Rect(0, 0, 0, 0));
3275 #endif
3276
3277 // count processed canvas node
3278 RS_OPTIONAL_TRACE_NAME_FMT("%s PureContainerNode/ProcessedNodes: %u/%u", node.GetName().c_str(),
3279 processedPureContainerNode_, processedCanvasNodeInCurrentSurface_);
3280 processedCanvasNodeInCurrentSurface_ = 0; // reset
3281 processedPureContainerNode_ = 0;
3282 }
3283 if (node.IsMainWindowType() || node.IsLeashWindow()) {
3284 isSubNodeOfSurfaceInProcess_ = isSubNodeOfSurfaceInProcess;
3285 }
3286 }
3287
3288 void RSUniRenderVisitor::ProcessProxyRenderNode(RSProxyRenderNode& node)
3289 {
3290 if (RSSystemProperties::GetProxyNodeDebugEnabled() && node.contextClipRect_.has_value() &&
3291 node.target_.lock() != nullptr) {
3292 // draw transparent green rect to indicate clip area of proxy node
3293 #ifndef USE_ROSEN_DRAWING
3294 SkPaint paint;
3295 paint.setARGB(0x80, 0, 0xFF, 0); // transparent green
3296 canvas_->drawRect(node.contextClipRect_.value(), paint);
3297 #else
3298 Drawing::Brush brush;
3299 brush.SetARGB(0, 0xFF, 0, 0x80); // transparent green
3300 canvas_->AttachBrush(brush);
3301 canvas_->DrawRect(node.contextClipRect_.value());
3302 canvas_->DetachBrush();
3303 #endif
3304 }
3305 ProcessChildren(node);
3306 }
3307
3308 void RSUniRenderVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
3309 {
3310 RS_LOGD("RSUniRenderVisitor::ProcessRootRenderNode node: %" PRIu64 ", child size:%u", node.GetId(),
3311 node.GetChildrenCount());
3312 if (!node.ShouldPaint()) {
3313 RS_LOGD("RSUniRenderVisitor::ProcessRootRenderNode, no need process");
3314 return;
3315 }
3316 if (!canvas_) {
3317 RS_LOGE("RSUniRenderVisitor::ProcessRootRenderNode, canvas is nullptr");
3318 return;
3319 }
3320
3321 ColorFilterMode colorFilterMode = renderEngine_->GetColorFilterMode();
3322 int saveCount;
3323 if (colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
3324 colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE) {
3325 RS_LOGD("RsDebug RSBaseRenderEngine::SetColorFilterModeToPaint mode:%d", static_cast<int32_t>(colorFilterMode));
3326 #ifndef USE_ROSEN_DRAWING
3327 SkPaint paint;
3328 RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, paint);
3329 #ifdef RS_ENABLE_GL
3330 #ifdef NEW_RENDER_CONTEXT
3331 RSTagTracker tagTracker(
3332 renderEngine_->GetDrawingContext()->GetDrawingContext(),
3333 RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
3334 #else
3335 RSTagTracker tagTracker(
3336 renderEngine_->GetRenderContext()->GetGrContext(), RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
3337 #endif
3338 #endif
3339 saveCount = canvas_->saveLayer(nullptr, &paint);
3340 } else {
3341 saveCount = canvas_->save();
3342 }
3343 ProcessCanvasRenderNode(node);
3344 canvas_->restoreToCount(saveCount);
3345 #else
3346 Drawing::Brush brush;
3347 RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, brush);
3348 Drawing::SaveLayerOps saveLayerOps(nullptr, &brush);
3349 saveCount = canvas_->GetSaveCount();
3350 canvas_->SaveLayer(saveLayerOps);
3351 } else {
3352 saveCount = canvas_->GetSaveCount();
3353 canvas_->Save();
3354 }
3355 ProcessCanvasRenderNode(node);
3356 canvas_->RestoreToCount(saveCount);
3357 #endif
3358 }
3359
GenerateNodeContentCache(RSRenderNode & node)3360 bool RSUniRenderVisitor::GenerateNodeContentCache(RSRenderNode& node)
3361 {
3362 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
3363 // Node cannot have cache.
3364 if (node.GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE) {
3365 if (cacheRenderNodeMap.count(node.GetId()) > 0) {
3366 node.SetCacheType(CacheType::NONE);
3367 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
3368 cacheRenderNodeMap.erase(node.GetId());
3369 groupedTransitionNodes.erase(node.GetId());
3370 }
3371 return false;
3372 }
3373
3374 // The node goes down the tree to clear the cache.
3375 if (!node.IsOnTheTree() && cacheRenderNodeMap.count(node.GetId()) > 0) {
3376 node.SetCacheType(CacheType::NONE);
3377 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
3378 cacheRenderNodeMap.erase(node.GetId());
3379 groupedTransitionNodes.erase(node.GetId());
3380 return false;
3381 }
3382 return true;
3383 }
3384
InitNodeCache(RSRenderNode & node)3385 bool RSUniRenderVisitor::InitNodeCache(RSRenderNode& node)
3386 {
3387 if (node.GetDrawingCacheType() == RSDrawingCacheType::FORCED_CACHE ||
3388 node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
3389 uint32_t cacheRenderNodeMapCnt = CACHE_RENDER_NODE_MAP_COUNT;
3390 {
3391 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
3392 cacheRenderNodeMapCnt = cacheRenderNodeMap.count(node.GetId());
3393 }
3394 if (cacheRenderNodeMapCnt == 0) {
3395 #ifndef USE_ROSEN_DRAWING
3396 RenderParam val { node.shared_from_this(), canvas_->GetAlpha(), canvas_->getTotalMatrix() };
3397 #else
3398 RenderParam val { node.shared_from_this(), canvas_->GetAlpha(), canvas_->GetTotalMatrix() };
3399 #endif
3400 curGroupedNodes_.push(val);
3401 groupedTransitionNodes[node.GetId()] = { val, {} };
3402 node.SetCacheType(CacheType::CONTENT);
3403 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
3404 if (UpdateCacheSurface(node)) {
3405 node.UpdateCompletedCacheSurface();
3406 ChangeCacheRenderNodeMap(node);
3407 cacheReuseTimes = 0;
3408 }
3409 curGroupedNodes_.pop();
3410 return true;
3411 }
3412 }
3413 return false;
3414 }
3415
ChangeCacheRenderNodeMap(RSRenderNode & node,const uint32_t count)3416 void RSUniRenderVisitor::ChangeCacheRenderNodeMap(RSRenderNode& node, const uint32_t count)
3417 {
3418 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
3419 cacheRenderNodeMap[node.GetId()] = count;
3420 }
3421
UpdateCacheRenderNodeMapWithBlur(RSRenderNode & node)3422 void RSUniRenderVisitor::UpdateCacheRenderNodeMapWithBlur(RSRenderNode& node)
3423 {
3424 curCacheFilterRects_.push(allCacheFilterRects_[node.GetId()]);
3425 auto canvasType = canvas_->GetCacheType();
3426 canvas_->SetCacheType(RSPaintFilterCanvas::CacheType::OFFSCREEN);
3427 UpdateCacheRenderNodeMap(node);
3428 canvas_->SetCacheType(canvasType);
3429 RS_TRACE_NAME_FMT("Draw cache with blur [%llu]", node.GetId());
3430 SkAutoCanvasRestore arc(canvas_.get(), true);
3431 auto nodeType = node.GetCacheType();
3432 node.SetCacheType(CacheType::NONE);
3433 DrawChildRenderNode(node);
3434 node.SetCacheType(nodeType);
3435 curCacheFilterRects_.pop();
3436 }
3437
UpdateCacheRenderNodeMap(RSRenderNode & node)3438 void RSUniRenderVisitor::UpdateCacheRenderNodeMap(RSRenderNode& node)
3439 {
3440 if (InitNodeCache(node)) {
3441 RS_LOGD("RSUniRenderVisitor::UpdateCacheRenderNodeMap, generate the node cache for the first time.");
3442 return;
3443 }
3444 uint32_t updateTimes = 0;
3445 if (node.GetDrawingCacheType() == RSDrawingCacheType::FORCED_CACHE) {
3446 // Regardless of the number of consecutive refreshes, the current cache is forced to be updated.
3447 if (node.GetDrawingCacheChanged()) {
3448 #ifndef USE_ROSEN_DRAWING
3449 RenderParam val { node.shared_from_this(), canvas_->GetAlpha(), canvas_->getTotalMatrix() };
3450 #else
3451 RenderParam val { node.shared_from_this(), canvas_->GetAlpha(), canvas_->GetTotalMatrix() };
3452 #endif
3453 curGroupedNodes_.push(val);
3454 groupedTransitionNodes[node.GetId()] = { val, {} };
3455 {
3456 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
3457 updateTimes = cacheRenderNodeMap[node.GetId()] + 1;
3458 }
3459 node.SetCacheType(CacheType::CONTENT);
3460 if (UpdateCacheSurface(node)) {
3461 node.UpdateCompletedCacheSurface();
3462 ChangeCacheRenderNodeMap(node, updateTimes);
3463 cacheReuseTimes = 0;
3464 }
3465 curGroupedNodes_.pop();
3466 return;
3467 }
3468 }
3469 if (node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
3470 // If the number of consecutive refreshes exceeds CACHE_MAX_UPDATE_TIME times, the cache is cleaned,
3471 // otherwise the cache is updated.
3472 if (node.GetDrawingCacheChanged()) {
3473 {
3474 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
3475 updateTimes = cacheRenderNodeMap[node.GetId()] + 1;
3476 }
3477 if (updateTimes >= CACHE_MAX_UPDATE_TIME) {
3478 node.SetCacheType(CacheType::NONE);
3479 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
3480 ChangeCacheRenderNodeMap(node, updateTimes);
3481 cacheReuseTimes = 0;
3482 return;
3483 }
3484 #ifndef USE_ROSEN_DRAWING
3485 RenderParam val { node.shared_from_this(), canvas_->GetAlpha(), canvas_->getTotalMatrix() };
3486 #else
3487 RenderParam val { node.shared_from_this(), canvas_->GetAlpha(), canvas_->GetTotalMatrix() };
3488 #endif
3489 curGroupedNodes_.push(val);
3490 groupedTransitionNodes[node.GetId()] = { val, {} };
3491 node.SetCacheType(CacheType::CONTENT);
3492 UpdateCacheSurface(node);
3493 node.UpdateCompletedCacheSurface();
3494 ChangeCacheRenderNodeMap(node, updateTimes);
3495 cacheReuseTimes = 0;
3496 curGroupedNodes_.pop();
3497 return;
3498 }
3499 }
3500 // The cache is not refreshed continuously.
3501 ChangeCacheRenderNodeMap(node);
3502 cacheReuseTimes++;
3503 RS_TRACE_NAME("RSUniRenderVisitor::UpdateCacheRenderNodeMap ,NodeId: " + std::to_string(node.GetId()) +
3504 " ,CacheRenderNodeMapCnt: " + std::to_string(cacheReuseTimes));
3505 }
3506
ProcessCanvasRenderNode(RSCanvasRenderNode & node)3507 void RSUniRenderVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
3508 {
3509 processedCanvasNodeInCurrentSurface_++;
3510 if (!node.ShouldPaint()) {
3511 return;
3512 }
3513 #ifdef RS_ENABLE_EGLQUERYSURFACE
3514 if (isOpDropped_ && (curSurfaceNode_ != nullptr)) {
3515 // If all the child nodes have drawing areas that do not exceed the current node, then current node
3516 // can be directly skipped if not intersect with any dirtyregion.
3517 // Otherwise, its childrenRect_ should be considered.
3518 RectI dirtyRect = node.HasChildrenOutOfRect() ?
3519 node.GetOldDirtyInSurface().JoinRect(node.GetChildrenRect()) : node.GetOldDirtyInSurface();
3520 if (isSubNodeOfSurfaceInProcess_ && !dirtyRect.IsEmpty() && !node.IsAncestorDirty() &&
3521 !curSurfaceNode_->SubNodeNeedDraw(dirtyRect, partialRenderType_)) {
3522 auto parent = node.GetParent().lock();
3523 bool isParentLeashWindow = parent && parent->ReinterpretCastTo<RSSurfaceRenderNode>() &&
3524 parent->ReinterpretCastTo<RSSurfaceRenderNode>()->IsLeashWindow();
3525 if (!isParentLeashWindow) {
3526 return;
3527 }
3528 }
3529 }
3530 #endif
3531 if (!canvas_) {
3532 RS_LOGE("RSUniRenderVisitor::ProcessCanvasRenderNode, canvas is nullptr");
3533 return;
3534 }
3535 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
3536 // clip hole for driven render
3537 if (drivenInfo_ && !drivenInfo_->prepareInfo.hasInvalidScene &&
3538 drivenInfo_->currDrivenRenderMode != DrivenUniRenderMode::RENDER_WITH_NORMAL) {
3539 // skip render driven node sub tree
3540 if (RSDrivenRenderManager::GetInstance().ClipHoleForDrivenNode(*canvas_, node)) {
3541 return;
3542 }
3543 }
3544 #endif
3545 // in case preparation'update is skipped
3546 #ifndef USE_ROSEN_DRAWING
3547 canvas_->save();
3548 #else
3549 canvas_->Save();
3550 #endif
3551 if (node.GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) {
3552 RSUniRenderUtil::FloorTransXYInCanvasMatrix(*canvas_);
3553 }
3554 // draw self and children in sandbox which will not be affected by parent's transition
3555 const auto& sandboxMatrix = node.GetRenderProperties().GetSandBoxMatrix();
3556 if (sandboxMatrix) {
3557 #ifndef USE_ROSEN_DRAWING
3558 canvas_->setMatrix(*sandboxMatrix);
3559 #else
3560 canvas_->SetMatrix(*sandboxMatrix);
3561 #endif
3562 }
3563 const auto& property = node.GetRenderProperties();
3564 if (property.IsSpherizeValid()) {
3565 DrawSpherize(node);
3566 return;
3567 }
3568 if (auto drawingNode = node.ReinterpretCastTo<RSCanvasDrawingRenderNode>()) {
3569 #ifndef USE_ROSEN_DRAWING
3570 auto clearFunc = [id = threadIndex_](sk_sp<SkSurface> surface) {
3571 // The second param is null, 0 is an invalid value.
3572 sk_sp<SkSurface> tmpSurface = nullptr;
3573 RSUniRenderUtil::ClearNodeCacheSurface(surface, tmpSurface, id, 0);
3574 };
3575 #else
3576 auto clearFunc = [id = threadIndex_](std::shared_ptr<Drawing::Surface> surface) {
3577 // The second param is null, 0 is an invalid value.
3578 sk_sp<SkSurface> tmpSurface = nullptr;
3579 RSUniRenderUtil::ClearNodeCacheSurface(surface, tmpSurface, id, 0);
3580 };
3581 #endif
3582 drawingNode->SetSurfaceClearFunc({ threadIndex_, clearFunc });
3583 }
3584 CheckAndSetNodeCacheType(node);
3585 DrawChildCanvasRenderNode(node);
3586 #ifndef USE_ROSEN_DRAWING
3587 canvas_->restore();
3588 #else
3589 canvas_->Restore();
3590 #endif
3591 }
3592
ProcessEffectRenderNode(RSEffectRenderNode & node)3593 void RSUniRenderVisitor::ProcessEffectRenderNode(RSEffectRenderNode& node)
3594 {
3595 if (!node.ShouldPaint()) {
3596 RS_LOGD("RSUniRenderVisitor::ProcessEffectRenderNode, no need process");
3597 return;
3598 }
3599 if (!canvas_) {
3600 RS_LOGE("RSUniRenderVisitor::ProcessEffectRenderNode, canvas is nullptr");
3601 return;
3602 }
3603 #ifndef USE_ROSEN_DRAWING
3604 int saveCount = canvas_->save();
3605 #else
3606 int saveCount = canvas_->GetSaveCount();
3607 canvas_->Save();
3608 #endif
3609 node.ProcessRenderBeforeChildren(*canvas_);
3610 if (!DrawBlurInCache(node)) {
3611 ProcessChildren(node);
3612 }
3613 node.ProcessRenderAfterChildren(*canvas_);
3614 #ifndef USE_ROSEN_DRAWING
3615 canvas_->restoreToCount(saveCount);
3616 #else
3617 canvas_->RestoreToCount(saveCount);
3618 #endif
3619 }
3620
RecordAppWindowNodeAndPostTask(RSSurfaceRenderNode & node,float width,float height)3621 void RSUniRenderVisitor::RecordAppWindowNodeAndPostTask(RSSurfaceRenderNode& node, float width, float height)
3622 {
3623 #ifndef USE_ROSEN_DRAWING
3624 RSRecordingCanvas canvas(width, height);
3625 #if (defined RS_ENABLE_GL)
3626 #ifdef NEW_SKIA
3627 canvas.SetGrRecordingContext(canvas_->recordingContext());
3628 #else
3629 canvas.SetGrContext(canvas_->getGrContext()); // SkImage::MakeFromCompressed need GrContext
3630 #endif
3631 #endif
3632 auto recordingCanvas = std::make_shared<RSPaintFilterCanvas>(&canvas);
3633 #else // USE_ROSEN_DRAWING
3634 Drawing::RecordingCanvas canvas(width, height);
3635 auto recordingCanvas = std::make_shared<RSPaintFilterCanvas>(&canvas);
3636 #endif
3637 swap(canvas_, recordingCanvas);
3638 ProcessChildren(node);
3639 swap(canvas_, recordingCanvas);
3640 RSColdStartManager::Instance().PostPlayBackTask(node.GetId(), canvas.GetDrawCmdList(), width, height);
3641 }
3642
PrepareOffscreenRender(RSRenderNode & node)3643 void RSUniRenderVisitor::PrepareOffscreenRender(RSRenderNode& node)
3644 {
3645 RS_TRACE_NAME("PrepareOffscreenRender");
3646 // cleanup
3647 canvasBackup_ = nullptr;
3648 offscreenSurface_ = nullptr;
3649 // check offscreen size and hardware renderer
3650 int32_t offscreenWidth = node.GetRenderProperties().GetFrameWidth();
3651 int32_t offscreenHeight = node.GetRenderProperties().GetFrameHeight();
3652 if (offscreenWidth <= 0 || offscreenHeight <= 0) {
3653 RS_LOGD("RSUniRenderVisitor::PrepareOffscreenRender, offscreenWidth or offscreenHeight is invalid");
3654 return;
3655 }
3656 #ifndef USE_ROSEN_DRAWING
3657 if (canvas_->GetSurface() == nullptr) {
3658 canvas_->clipRect(SkRect::MakeWH(offscreenWidth, offscreenHeight));
3659 RS_LOGD("RSUniRenderVisitor::PrepareOffscreenRender, current surface is nullptr (software renderer?)");
3660 return;
3661 }
3662 // create offscreen surface and canvas
3663 offscreenSurface_ = canvas_->GetSurface()->makeSurface(offscreenWidth, offscreenHeight);
3664 if (offscreenSurface_ == nullptr) {
3665 RS_LOGD("RSUniRenderVisitor::PrepareOffscreenRender, offscreenSurface is nullptr");
3666 canvas_->clipRect(SkRect::MakeWH(offscreenWidth, offscreenHeight));
3667 return;
3668 }
3669 auto offscreenCanvas = std::make_shared<RSPaintFilterCanvas>(offscreenSurface_.get());
3670
3671 // copy current canvas properties into offscreen canvas
3672 offscreenCanvas->CopyConfiguration(*canvas_);
3673
3674 // backup current canvas and replace with offscreen canvas
3675 canvasBackup_ = std::exchange(canvas_, offscreenCanvas);
3676 #else
3677 if (canvas_->GetSurface() == nullptr) {
3678 canvas_->ClipRect(Drawing::Rect(0, 0, offscreenWidth, offscreenHeight), Drawing::ClipOp::INTERSECT, false);
3679 RS_LOGD("RSUniRenderVisitor::PrepareOffscreenRender, current surface is nullptr (software renderer?)");
3680 return;
3681 }
3682 #endif
3683 }
3684
FinishOffscreenRender()3685 void RSUniRenderVisitor::FinishOffscreenRender()
3686 {
3687 if (canvasBackup_ == nullptr) {
3688 RS_LOGD("RSUniRenderVisitor::FinishOffscreenRender, canvasBackup_ is nullptr");
3689 return;
3690 }
3691 RS_TRACE_NAME("RSUniRenderVisitor::OffscreenRender finish");
3692 // flush offscreen canvas, maybe unnecessary
3693 #ifndef USE_ROSEN_DRAWING
3694 canvas_->flush();
3695 // draw offscreen surface to current canvas
3696 SkPaint paint;
3697 paint.setAntiAlias(true);
3698 #ifdef NEW_SKIA
3699 canvasBackup_->drawImage(offscreenSurface_->makeImageSnapshot(), 0, 0, SkSamplingOptions(), &paint);
3700 #else
3701 canvasBackup_->drawImage(offscreenSurface_->makeImageSnapshot(), 0, 0, &paint);
3702 #endif
3703 #else
3704 canvas_->Flush();
3705 // draw offscreen surface to current canvas
3706 Drawing::Brush paint;
3707 paint.SetAntiAlias(true);
3708 canvasBackup_->AttachBrush(paint);
3709 Drawing::SamplingOptions sampling =
3710 Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NEAREST);
3711 canvasBackup_->DrawImage(*offscreenSurface_->GetImageSnapshot().get(), 0, 0, sampling);
3712 canvasBackup_->DetachBrush();
3713 #endif
3714 // restore current canvas and cleanup
3715 offscreenSurface_ = nullptr;
3716 canvas_ = std::move(canvasBackup_);
3717 }
3718
AdaptiveSubRenderThreadMode(bool doParallel)3719 bool RSUniRenderVisitor::AdaptiveSubRenderThreadMode(bool doParallel)
3720 {
3721 #if defined(RS_ENABLE_PARALLEL_RENDER) && (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK))
3722 doParallel = (doParallel && (parallelRenderType_ != ParallelRenderingType::DISABLE));
3723 if (!doParallel) {
3724 return doParallel;
3725 }
3726 auto parallelRenderManager = RSParallelRenderManager::Instance();
3727 switch (parallelRenderType_) {
3728 case ParallelRenderingType::AUTO:
3729 parallelRenderManager->SetParallelMode(doParallel);
3730 break;
3731 case ParallelRenderingType::DISABLE:
3732 parallelRenderManager->SetParallelMode(false);
3733 break;
3734 case ParallelRenderingType::ENABLE:
3735 parallelRenderManager->SetParallelMode(true);
3736 break;
3737 }
3738 return doParallel;
3739 #else
3740 return false;
3741 #endif
3742 }
ParallelRenderEnableHardwareComposer(RSSurfaceRenderNode & node)3743 void RSUniRenderVisitor::ParallelRenderEnableHardwareComposer(RSSurfaceRenderNode& node)
3744 {
3745 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined (RS_ENABLE_GL)
3746 if (isParallel_ && !isUIFirst_) {
3747 const auto& property = node.GetRenderProperties();
3748 auto dstRect = node.GetDstRect();
3749 RectF clipRect = {dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetWidth(), dstRect.GetHeight()};
3750 RSParallelRenderManager::Instance()->AddSelfDrawingSurface(parallelRenderVisitorIndex_,
3751 property.GetCornerRadius().IsZero(), clipRect, property.GetCornerRadius());
3752 }
3753 #endif
3754 }
3755
ClosePartialRenderWhenAnimatingWindows(std::shared_ptr<RSDisplayRenderNode> & node)3756 void RSUniRenderVisitor::ClosePartialRenderWhenAnimatingWindows(std::shared_ptr<RSDisplayRenderNode>& node)
3757 {
3758 if (!doAnimate_) {
3759 return;
3760 }
3761 if (appWindowNum_ > PHONE_MAX_APP_WINDOW_NUM) {
3762 node->GetDirtyManager()->MergeSurfaceRect();
3763 } else {
3764 isPartialRenderEnabled_ = false;
3765 isOpDropped_ = false;
3766 RS_TRACE_NAME("ClosePartialRender 0 Window Animation");
3767 }
3768 }
3769
SetHardwareEnabledNodes(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & hardwareEnabledNodes)3770 void RSUniRenderVisitor::SetHardwareEnabledNodes(
3771 const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& hardwareEnabledNodes)
3772 {
3773 hardwareEnabledNodes_ = hardwareEnabledNodes;
3774 }
3775
DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode)3776 bool RSUniRenderVisitor::DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
3777 {
3778 if (!IsHardwareComposerEnabled()) {
3779 RS_LOGD("RSUniRenderVisitor::DoDirectComposition HardwareComposer disabled");
3780 return false;
3781 }
3782 RS_TRACE_NAME("DoDirectComposition");
3783 auto child = rootNode->GetSortedChildren().front();
3784 if (child == nullptr || !child->IsInstanceOf<RSDisplayRenderNode>()) {
3785 RS_LOGE("RSUniRenderVisitor::DoDirectComposition child type not match");
3786 return false;
3787 }
3788 auto displayNode = child->ReinterpretCastTo<RSDisplayRenderNode>();
3789 if (!displayNode ||
3790 displayNode->GetCompositeType() != RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE) {
3791 RS_LOGE("RSUniRenderVisitor::DoDirectComposition displayNode state error");
3792 return false;
3793 }
3794 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
3795 screenInfo_ = screenManager->QueryScreenInfo(displayNode->GetScreenId());
3796 if (screenInfo_.state != ScreenState::HDI_OUTPUT_ENABLE) {
3797 RS_LOGE("RSUniRenderVisitor::DoDirectComposition: ScreenState error!");
3798 return false;
3799 }
3800 processor_ = RSProcessorFactory::CreateProcessor(displayNode->GetCompositeType());
3801 if (processor_ == nullptr) {
3802 RS_LOGE("RSUniRenderVisitor::DoDirectComposition: RSProcessor is null!");
3803 return false;
3804 }
3805
3806 if (renderEngine_ == nullptr) {
3807 RS_LOGE("RSUniRenderVisitor::DoDirectComposition: renderEngine is null!");
3808 return false;
3809 }
3810 if (!processor_->Init(*displayNode, displayNode->GetDisplayOffsetX(), displayNode->GetDisplayOffsetY(),
3811 INVALID_SCREEN_ID, renderEngine_)) {
3812 RS_LOGE("RSUniRenderVisitor::DoDirectComposition: processor init failed!");
3813 return false;
3814 }
3815 processor_->ProcessDisplaySurface(*displayNode);
3816 for (auto& node: hardwareEnabledNodes_) {
3817 if (!node->IsHardwareForcedDisabled()) {
3818 processor_->ProcessSurface(*node);
3819 }
3820 }
3821 processor_->PostProcess();
3822 RS_LOGD("RSUniRenderVisitor::DoDirectComposition end");
3823 return true;
3824 }
3825
DrawWatermarkIfNeed()3826 void RSUniRenderVisitor::DrawWatermarkIfNeed()
3827 {
3828 if (RSMainThread::Instance()->GetWatermarkFlag()) {
3829 #ifndef USE_ROSEN_DRAWING
3830 sk_sp<SkImage> skImage = RSMainThread::Instance()->GetWatermarkImg();
3831 SkPaint rectPaint;
3832 auto skSrcRect = SkRect::MakeWH(skImage->width(), skImage->height());
3833 auto skDstRect = SkRect::MakeWH(screenInfo_.width, screenInfo_.height);
3834 #ifdef NEW_SKIA
3835 canvas_->drawImageRect(
3836 skImage, skSrcRect, skDstRect, SkSamplingOptions(), &rectPaint, SkCanvas::kStrict_SrcRectConstraint);
3837 #else
3838 canvas_->drawImageRect(skImage, skSrcRect, skDstRect, &rectPaint);
3839 #endif
3840 #else
3841 std::shared_ptr<Drawing::Image> drImage = RSMainThread::Instance()->GetWatermarkImg();
3842 if (drImage == nullptr) {
3843 return;
3844 }
3845 Drawing::Brush rectPaint;
3846 canvas_->AttachBrush(rectPaint);
3847 auto srcRect = Drawing::Rect(0, 0, drImage->GetWidth(), drImage->GetHeight());
3848 auto dstRect = Drawing::Rect(0, 0, screenInfo_.width, screenInfo_.height);
3849 canvas_->DrawImageRect(*drImage, srcRect, dstRect, Drawing::SamplingOptions(),
3850 Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
3851 canvas_->DetachBrush();
3852 #endif
3853 }
3854 }
3855
3856
SetAppWindowNum(uint32_t num)3857 void RSUniRenderVisitor::SetAppWindowNum(uint32_t num)
3858 {
3859 appWindowNum_ = num;
3860 }
3861
ParallelComposition(const std::shared_ptr<RSBaseRenderNode> rootNode)3862 bool RSUniRenderVisitor::ParallelComposition(const std::shared_ptr<RSBaseRenderNode> rootNode)
3863 {
3864 #if defined(RS_ENABLE_PARALLEL_RENDER) && defined (RS_ENABLE_GL)
3865 auto parallelRenderManager = RSParallelRenderManager::Instance();
3866 doParallelComposition_ = true;
3867 doParallelComposition_ = AdaptiveSubRenderThreadMode(doParallelComposition_) &&
3868 parallelRenderManager->GetParallelMode();
3869 if (doParallelComposition_) {
3870 parallelRenderManager->PackParallelCompositionTask(shared_from_this(), rootNode);
3871 parallelRenderManager->LoadBalanceAndNotify(TaskType::COMPOSITION_TASK);
3872 parallelRenderManager->WaitCompositionEnd();
3873 } else {
3874 return false;
3875 }
3876 return true;
3877 #else
3878 return false;
3879 #endif
3880 }
3881
PrepareSharedTransitionNode(RSBaseRenderNode & node)3882 bool RSUniRenderVisitor::PrepareSharedTransitionNode(RSBaseRenderNode& node)
3883 {
3884 auto transitionParam = node.GetSharedTransitionParam();
3885 if (!transitionParam.has_value()) {
3886 // non-transition node, prepare directly
3887 return true;
3888 }
3889
3890 // use transition key (aka in node id) as map index.
3891 auto key = transitionParam->first;
3892 // If the paired node has already been visited (this means all sanity checks passed), process both nodes in order.
3893 if (auto existingNodeIter = unpairedTransitionNodes_.find(key);
3894 existingNodeIter != unpairedTransitionNodes_.end()) {
3895 // backup environment variables
3896 auto curAlpha = curAlpha_;
3897 auto clipRect = prepareClipRect_;
3898
3899 // hack to ensure that dirty region will include the shared-transition nodes
3900 prepareClipRect_.SetAll(0, 0, INT_MAX, INT_MAX);
3901
3902 // set curAlpha_ and prepare paired node
3903 [[maybe_unused]] auto& [node, alpha, unused_matrix] = existingNodeIter->second;
3904 curAlpha_ = alpha;
3905 node->Prepare(shared_from_this());
3906 unpairedTransitionNodes_.erase(existingNodeIter);
3907
3908 // restore environment variables and continue prepare node
3909 curAlpha_ = curAlpha;
3910 prepareClipRect_ = clipRect;
3911 return true;
3912 }
3913
3914 auto pairedNode = transitionParam->second.lock();
3915 if (pairedNode == nullptr) {
3916 // paired node is already destroyed, clear transition param and prepare directly
3917 node.SetSharedTransitionParam(std::nullopt);
3918 return true;
3919 }
3920
3921 auto& pairedParam = pairedNode->GetSharedTransitionParam();
3922 if (!pairedParam.has_value() || pairedParam->first != transitionParam->first) {
3923 // if 1. paired node is not a transition node or 2. paired node is not paired with this node, then clear
3924 // transition param and prepare directly
3925 node.SetSharedTransitionParam(std::nullopt);
3926 return true;
3927 }
3928
3929 // all sanity checks passed, add this node and render params (only alpha for prepare phase) into
3930 // unpairedTransitionNodes_.
3931 RenderParam value { node.shared_from_this(), curAlpha_, std::nullopt };
3932 unpairedTransitionNodes_.emplace(key, std::move(value));
3933
3934 // skip prepare for shared transition node and its children
3935 return false;
3936 }
3937
ProcessSharedTransitionNode(RSBaseRenderNode & node)3938 bool RSUniRenderVisitor::ProcessSharedTransitionNode(RSBaseRenderNode& node)
3939 {
3940 auto& transitionParam = node.GetSharedTransitionParam();
3941 if (!transitionParam.has_value()) {
3942 // non-transition node, process directly
3943 return true;
3944 }
3945
3946 // Note: Sanity checks for shared transition nodes are already done in prepare phase, no need to do it again.
3947 // use transition key (in node id) as map index.
3948 auto key = transitionParam->first;
3949 // paired node is already visited, process both nodes in order.
3950 if (auto existingNodeIter = unpairedTransitionNodes_.find(key);
3951 existingNodeIter != unpairedTransitionNodes_.end()) {
3952 RSAutoCanvasRestore acr(canvas_);
3953 // restore render context and process the paired node.
3954 auto& [node, alpha, matrix] = existingNodeIter->second;
3955 canvas_->SetAlpha(alpha);
3956 #ifndef USE_ROSEN_DRAWING
3957 canvas_->setMatrix(matrix.value());
3958 #else
3959 canvas_->SetMatrix(matrix.value());
3960 #endif
3961 node->Process(shared_from_this());
3962 unpairedTransitionNodes_.erase(existingNodeIter);
3963 return true;
3964 }
3965
3966 for (auto& [_, pair] : groupedTransitionNodes) {
3967 if (auto existingNodeIter = pair.second.find(key); existingNodeIter != pair.second.end()) {
3968 RSAutoCanvasRestore acr(canvas_);
3969 // restore render context and process the paired node.
3970 auto& [_, preAlpha, preMatrix] = pair.first;
3971 auto& [child, alpha, matrix] = existingNodeIter->second;
3972 canvas_->SetAlpha(alpha * preAlpha);
3973 #ifndef USE_ROSEN_DRAWING
3974 canvas_->setMatrix(SkMatrix::Concat(preMatrix.value(), matrix.value()));
3975 #else
3976 canvas_->SetMatrix(matrix.value());
3977 #endif
3978 child->Process(shared_from_this());
3979 return true;
3980 }
3981 }
3982
3983 auto pairedNode = transitionParam->second.lock();
3984 if (pairedNode->GetGlobalAlpha() <= 0.0f) {
3985 // visitor may never visit the paired node, ignore the transition logic and process directly.
3986 return true;
3987 }
3988
3989 if (!curGroupedNodes_.empty()) {
3990 // if in node group cache, add this node and render params (alpha and matrix) into groupedTransitionNodes.
3991 auto& [child, alpha, matrix] = curGroupedNodes_.top();
3992 #ifndef USE_ROSEN_DRAWING
3993 RenderParam value { node.shared_from_this(), canvas_->GetAlpha() / alpha, canvas_->getTotalMatrix() };
3994 if (!matrix->invert(&std::get<2>(value).value())) { // 2 means to get the second element from the tuple
3995 RS_LOGE("RSUniRenderVisitor::ProcessSharedTransitionNode invert failed");
3996 }
3997 #else
3998 RenderParam value { std::move(renderChild), canvas_->GetAlpha(), canvas_->GetTotalMatrix() };
3999 #endif
4000 groupedTransitionNodes[child->GetId()].second.emplace(key, std::move(value));
4001 return false;
4002 }
4003
4004 // all sanity checks passed, add this node and render params (alpha and matrix) into unpairedTransitionNodes_.
4005 #ifndef USE_ROSEN_DRAWING
4006 RenderParam value { node.shared_from_this(), canvas_->GetAlpha(), canvas_->getTotalMatrix() };
4007 #else
4008 RenderParam value { node.shared_from_this(), canvas_->GetAlpha(), canvas_->GetTotalMatrix() };
4009 #endif
4010 unpairedTransitionNodes_.emplace(key, std::move(value));
4011
4012 // skip processing the current node and all its children.
4013 return false;
4014 }
4015 } // namespace Rosen
4016 } // namespace OHOS
4017