• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &region)
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