• 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/main_thread/rs_uni_render_visitor.h"
17 #include <memory>
18 #include "rs_trace.h"
19 #include "screen_manager/rs_screen_manager.h"
20 
21 #ifdef RS_ENABLE_OLD_VK
22 #include <vulkan_window.h>
23 #endif
24 
25 #include "common/rs_common_def.h"
26 #include "common/rs_common_hook.h"
27 #include "common/rs_obj_abs_geometry.h"
28 #include "common/rs_optional_trace.h"
29 #include "common/rs_singleton.h"
30 #include "common/rs_special_layer_manager.h"
31 #include "feature/opinc/rs_opinc_manager.h"
32 #include "feature/hdr/rs_hdr_util.h"
33 #include "feature/uifirst/rs_sub_thread_manager.h"
34 #include "feature/uifirst/rs_uifirst_manager.h"
35 #include "monitor/self_drawing_node_monitor.h"
36 #ifdef RS_ENABLE_OVERLAY_DISPLAY
37 #include "feature/overlay_display/rs_overlay_display_manager.h"
38 #endif
39 #include "display_engine/rs_luminance_control.h"
40 #include "memory/rs_tag_tracker.h"
41 #include "params/rs_display_render_params.h"
42 #include "params/rs_rcd_render_params.h"
43 #include "pipeline/render_thread/rs_base_render_util.h"
44 #include "pipeline/render_thread/rs_uni_render_util.h"
45 #include "pipeline/render_thread/rs_uni_render_virtual_processor.h"
46 #include "pipeline/rs_base_render_node.h"
47 #include "pipeline/rs_display_render_node.h"
48 #include "pipeline/rs_effect_render_node.h"
49 #include "pipeline/rs_paint_filter_canvas.h"
50 #include "pipeline/rs_pointer_window_manager.h"
51 #include "pipeline/hardware_thread/rs_realtime_refresh_rate_manager.h"
52 #include "pipeline/rs_root_render_node.h"
53 #include "pipeline/rs_surface_render_node.h"
54 #include "platform/common/rs_log.h"
55 #include "platform/common/rs_system_properties.h"
56 #include "property/rs_properties_painter.h"
57 #include "system/rs_system_parameters.h"
58 #include "hgm_core.h"
59 #include "metadata_helper.h"
60 #include <v1_0/buffer_handle_meta_key_type.h>
61 #include <v1_0/cm_color_space.h>
62 
63 #include "feature_cfg/graphic_feature_param_manager.h"
64 #include "feature/round_corner_display/rs_rcd_surface_render_node.h"
65 #include "feature/round_corner_display/rs_round_corner_display_manager.h"
66 #include "feature/round_corner_display/rs_message_bus.h"
67 
68 #include "rs_profiler.h"
69 #ifdef RS_PROFILER_ENABLED
70 #include "rs_profiler_capture_recorder.h"
71 #endif
72 
73 // blur predict
74 #include "rs_frame_blur_predict.h"
75 
76 namespace OHOS {
77 namespace Rosen {
78 namespace {
79 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
80 constexpr int MAX_ALPHA = 255;
81 constexpr int TRACE_LEVEL_THREE = 3;
82 constexpr float EPSILON_SCALE = 0.00001f;
83 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
84 constexpr const char* RELIABLE_GESTURE_BACK_SURFACE_NAME = "SCBGestureBack";
85 constexpr int MIN_OVERLAP = 2;
86 constexpr uint32_t API18 = 18;
87 constexpr uint32_t INVALID_API_COMPATIBLE_VERSION = 0;
88 
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)89 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
90 {
91     if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
92         auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
93         const auto& property = rootNode->GetRenderProperties();
94         if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
95             return true;
96         }
97     }
98     return false;
99 }
100 
CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)101 bool CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
102 {
103     if (child != nullptr && child->IsInstanceOf<RSCanvasRenderNode>()) {
104         auto canvasRenderNode = child->ReinterpretCastTo<RSCanvasRenderNode>();
105         const auto& property = canvasRenderNode->GetRenderProperties();
106         if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0) {
107             return true;
108         }
109     }
110     return false;
111 }
112 
IsFirstFrameReadyToDraw(const RSSurfaceRenderNode & node)113 bool IsFirstFrameReadyToDraw(const RSSurfaceRenderNode& node)
114 {
115     bool result = false;
116     auto sortedChildren = node.GetSortedChildren();
117     if (node.IsScbScreen() || node.IsSCBNode()) {
118         for (const auto& child : *sortedChildren) {
119             result = CheckScbReadyToDraw(child);
120         }
121         return result;
122     }
123     for (auto& child : *sortedChildren) {
124         result = CheckRootNodeReadyToDraw(child);
125         // when appWindow has abilityComponent node
126         if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
127             for (const auto& surfaceNodeChild : *child->GetSortedChildren()) {
128                 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
129             }
130         }
131     }
132     return result;
133 }
134 
VisibleDataToString(const VisibleData & val)135 std::string VisibleDataToString(const VisibleData& val)
136 {
137     std::stringstream ss;
138     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
139     for (const auto& v : val) {
140         auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(v.first);
141         auto name = surfaceNode ? surfaceNode->GetName() : "";
142         ss << "[" << name << ", " << v.first << ", " << v.second << "], ";
143     }
144     return ss.str();
145 }
146 } // namespace
147 
RSUniRenderVisitor()148 RSUniRenderVisitor::RSUniRenderVisitor()
149     : rsUniHwcVisitor_(std::make_unique<RSUniHwcVisitor>(*this)),
150       curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
151 {
152     PartialRenderOptionInit();
153     auto mainThread = RSMainThread::Instance();
154     renderEngine_ = mainThread->GetRenderEngine();
155     hasMirrorDisplay_ = mainThread->HasMirrorDisplay();
156     // when occlusion enabled is false, subTree do not skip, but not influence visible region
157     isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
158     isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
159 #ifdef DDGR_ENABLE_FEATURE_OPINC
160     autoCacheEnable_ = RSOpincManager::Instance().GetOPIncSwitch();
161 #endif
162     RSTagTracker::UpdateReleaseResourceEnabled(RSSystemProperties::GetReleaseResourceEnabled());
163     isScreenRotationAnimating_ = RSSystemProperties::GetCacheEnabledForRotation();
164 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
165     if (renderEngine_ && renderEngine_->GetRenderContext()) {
166         auto subThreadManager = RSSubThreadManager::Instance();
167         subThreadManager->Start(renderEngine_->GetRenderContext().get());
168     }
169 #endif
170     isUIFirstDebugEnable_ = RSSystemProperties::GetUIFirstDebugEnabled();
171     isCrossNodeOffscreenOn_ = RSSystemProperties::GetCrossNodeOffScreenStatus();
172     isDumpRsTreeDetailEnabled_ = RSSystemProperties::GetDumpRsTreeDetailEnabled();
173 }
174 
PartialRenderOptionInit()175 void RSUniRenderVisitor::PartialRenderOptionInit()
176 {
177     if (auto dirtyRegionParam = std::static_pointer_cast<DirtyRegionParam>(
178         GraphicFeatureParamManager::GetInstance().GetFeatureParam("DirtyRegionConfig"))) {
179         isPartialRenderEnabled_ = dirtyRegionParam->IsDirtyRegionEnable();
180         isAdvancedDirtyRegionEnabled_ = dirtyRegionParam->IsAdvancedDirtyRegionEnable();
181         isDirtyAlignEnabled_ = dirtyRegionParam->IsTileBasedAlignEnable();
182     }
183     if (RSSystemProperties::GetStencilPixelOcclusionCullingEnabled() == StencilPixelOcclusionCullingType::DEFAULT) {
184         if (auto spocParam = std::static_pointer_cast<StencilPixelOcclusionCullingParam>(
185             GraphicFeatureParamManager::GetInstance().GetFeatureParam("SpocConfig"))) {
186                 isStencilPixelOcclusionCullingEnabled_ = spocParam->IsStencilPixelOcclusionCullingEnable();
187         }
188     } else {
189         isStencilPixelOcclusionCullingEnabled_ =
190             RSSystemProperties::GetStencilPixelOcclusionCullingEnabled() != StencilPixelOcclusionCullingType::DISABLED;
191     }
192 
193     partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
194     isPartialRenderEnabled_ &= (partialRenderType_ > PartialRenderType::DISABLED);
195 
196     isCompleteRenderEnabled_ = (partialRenderType_ == PartialRenderType::SET_DAMAGE_BUT_COMPLETE_RENDER);
197     dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
198     surfaceRegionDebugType_ = RSSystemProperties::GetSurfaceRegionDfxType();
199     isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_) &&
200         (surfaceRegionDebugType_ == SurfaceRegionDebugType::DISABLED);
201     isTargetUIFirstDfxEnabled_ = RSSystemProperties::GetTargetUIFirstDfxEnabled(dfxUIFirstSurfaceNames_);
202     isRegionDebugEnabled_ = (dirtyRegionDebugType_ != DirtyRegionDebugType::DISABLED) ||
203         (surfaceRegionDebugType_ != SurfaceRegionDebugType::DISABLED) || (dfxTargetSurfaceNames_.size() > 0);
204     isVisibleRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::VISIBLE_REGION);
205     isOpaqueRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::OPAQUE_REGION);
206     isAllSurfaceVisibleDebugEnabled_ = RSSystemProperties::GetAllSurfaceVisibleDebugEnabled();
207     isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
208         (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
209     isDisplayDirtyDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
210         (dirtyRegionDebugType_ == DirtyRegionDebugType::DISPLAY_DIRTY);
211     isOpDropped_ = isPartialRenderEnabled_ &&
212         (partialRenderType_ != PartialRenderType::SET_DAMAGE) && !isRegionDebugEnabled_;
213     isVirtualDirtyDfxEnabled_ = RSSystemProperties::GetVirtualDirtyDebugEnabled();
214     isVirtualDirtyEnabled_ = RSSystemProperties::GetVirtualDirtyEnabled() &&
215         (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) && !isRegionDebugEnabled_;
216     isExpandScreenDirtyEnabled_ = RSSystemProperties::GetExpandScreenDirtyEnabled();
217     advancedDirtyType_ = isAdvancedDirtyRegionEnabled_ ?
218         RSSystemProperties::GetAdvancedDirtyRegionEnabled() : AdvancedDirtyRegionType::DISABLED;
219     isDirtyAlignEnabled_ &= RSSystemProperties::GetDirtyAlignEnabled() != DirtyAlignType::DISABLED;
220     if (isStencilPixelOcclusionCullingEnabled_) {
221         // SPOC relies on dirty region alignment; when SPOC is enabled, dirty region alignment must also be enabled
222         isDirtyAlignEnabled_ = true;
223     }
224 }
225 
RSUniRenderVisitor(const RSUniRenderVisitor & visitor)226 RSUniRenderVisitor::RSUniRenderVisitor(const RSUniRenderVisitor& visitor) : RSUniRenderVisitor()
227 {
228     currentVisitDisplay_ = visitor.currentVisitDisplay_;
229     screenInfo_ = visitor.screenInfo_;
230     specialLayerManager_ = visitor.specialLayerManager_;
231     displaySpecailSurfaceChanged_ = visitor.displaySpecailSurfaceChanged_;
232     hasCaptureWindow_ = visitor.hasCaptureWindow_;
233     hasFingerprint_ = visitor.hasFingerprint_;
234     parentSurfaceNodeMatrix_ = visitor.parentSurfaceNodeMatrix_;
235     curAlpha_ = visitor.curAlpha_;
236     dirtyFlag_ = visitor.dirtyFlag_;
237     curDisplayNode_ = visitor.curDisplayNode_;
238     currentFocusedNodeId_ = visitor.currentFocusedNodeId_;
239     prepareClipRect_ = visitor.prepareClipRect_;
240     isOpDropped_ = visitor.isOpDropped_;
241     isDirtyAlignEnabled_ = visitor.isDirtyAlignEnabled_;
242     isStencilPixelOcclusionCullingEnabled_ = visitor.isStencilPixelOcclusionCullingEnabled_;
243     isPartialRenderEnabled_ = visitor.isPartialRenderEnabled_;
244     isAllSurfaceVisibleDebugEnabled_ = visitor.isAllSurfaceVisibleDebugEnabled_;
245     isHardwareForcedDisabled_ = visitor.isHardwareForcedDisabled_;
246     advancedDirtyType_ = visitor.advancedDirtyType_;
247     doAnimate_ = visitor.doAnimate_;
248     isDirty_ = visitor.isDirty_;
249     layerNum_ = visitor.layerNum_;
250     isDumpRsTreeDetailEnabled_ = visitor.isDumpRsTreeDetailEnabled_;
251 }
252 
~RSUniRenderVisitor()253 RSUniRenderVisitor::~RSUniRenderVisitor() {}
254 
MergeRemovedChildDirtyRegion(RSRenderNode & node,bool needMap)255 void RSUniRenderVisitor::MergeRemovedChildDirtyRegion(RSRenderNode& node, bool needMap)
256 {
257     if (!node.HasRemovedChild()) {
258         return;
259     }
260     RectI dirtyRect = RSSystemProperties::GetOptimizeParentNodeRegionEnabled() ?
261         node.GetRemovedChildrenRect() : node.GetChildrenRect();
262     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
263     if (dirtyManager == nullptr || dirtyRect.IsEmpty()) {
264         node.ResetHasRemovedChild();
265         return;
266     }
267 
268     // [planning] merge removed child's rect instead
269     if (needMap) {
270         if (auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry()) {
271             dirtyRect = geoPtr->MapAbsRect(dirtyRect.ConvertTo<float>());
272         }
273         if (!node.HasChildrenOutOfRect()) {
274             dirtyRect = dirtyRect.IntersectRect(node.GetOldClipRect());
275         }
276     } else {
277         dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
278     }
279     dirtyManager->MergeDirtyRect(dirtyRect);
280     RS_OPTIONAL_TRACE_NAME_FMT("MergeRemovedChildDirtyRegion NodeId:%" PRIu64 ", dirty rect:%s",
281         node.GetId(), dirtyRect.ToString().c_str());
282     if (dirtyManager->IsTargetForDfx()) {
283         // since childRect includes multiple rects, defaultly marked as canvas_node
284         dirtyManager->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
285             DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
286     }
287     node.ResetHasRemovedChild();
288 }
289 
CheckColorSpace(RSSurfaceRenderNode & node)290 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
291 {
292     // currently, P3 is the only supported wide color gamut, this may be modified later.
293     if (node.IsAppWindow() && node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
294         if (!curDisplayNode_) {
295             RS_LOGD("RSUniRenderVisitor::CheckColorSpace: curDisplayNode_ is nullptr");
296             return;
297         }
298         curDisplayNode_->SetColorSpace(GRAPHIC_COLOR_GAMUT_DISPLAY_P3);
299         RS_LOGD("RSUniRenderVisitor::CheckColorSpace: node(%{public}s) set new colorgamut %{public}d",
300             node.GetName().c_str(), static_cast<int>(GRAPHIC_COLOR_GAMUT_DISPLAY_P3));
301     }
302 }
303 
CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode & node,GraphicColorGamut & newColorSpace)304 void RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode& node, GraphicColorGamut& newColorSpace)
305 {
306     if (!node.IsOnTheTree()) {
307         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is not on the tree",
308             node.GetName().c_str());
309         return;
310     }
311     if (!node.IsHardwareForcedDisabled()) {
312         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is hardware-enabled",
313             node.GetName().c_str());
314         return;
315     }
316     // currently, P3 is the only supported wide color gamut, this may be modified later.
317     node.UpdateColorSpaceWithMetadata();
318     auto appSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetInstanceRootNode());
319     auto colorGamutFeature = GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[COLOR_GAMUT]);
320     auto colorGamutParam = std::static_pointer_cast<ColorGamutParam>(colorGamutFeature);
321     if (colorGamutParam != nullptr && colorGamutParam->IsCoveredSurfaceCloseP3() && appSurfaceNode
322         && appSurfaceNode->IsMainWindowType() && appSurfaceNode->GetVisibleRegion().IsEmpty() && GetIsOpDropped()) {
323         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) failed to set new color "
324                 "gamut %{public}d because the window is blocked", node.GetName().c_str(), newColorSpace);
325         return;
326     }
327 
328     if (node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
329         newColorSpace = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
330         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) set new colorgamut %{public}d",
331             node.GetName().c_str(), newColorSpace);
332     }
333 }
334 
UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode & node)335 void RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode& node)
336 {
337     auto colorSpace = node.GetColorSpace();
338     if (colorSpace == GRAPHIC_COLOR_GAMUT_DISPLAY_P3) {
339         RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc: newColorSpace is already DISPLAY_P3.");
340         return;
341     }
342     const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
343     for (const auto& selfDrawingNode : selfDrawingNodes) {
344         if (!selfDrawingNode) {
345             RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc selfDrawingNode is nullptr");
346             continue;
347         }
348         auto ancestorNode = selfDrawingNode->GetAncestorDisplayNode().lock();
349         if (!ancestorNode) {
350             RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc ancestorNode is nullptr");
351             continue;
352         }
353         auto ancestorDisplayNode = ancestorNode->ReinterpretCastTo<RSDisplayRenderNode>();
354         if (ancestorDisplayNode != nullptr && node.GetId() == ancestorDisplayNode->GetId()) {
355             CheckColorSpaceWithSelfDrawingNode(*selfDrawingNode, colorSpace);
356         }
357     }
358     node.SetColorSpace(colorSpace);
359 }
360 
IsScreenSupportedWideColorGamut(ScreenId id,const sptr<RSScreenManager> & screenManager)361 bool IsScreenSupportedWideColorGamut(ScreenId id, const sptr<RSScreenManager>& screenManager)
362 {
363     std::vector<ScreenColorGamut> supportedColorGamut;
364     if (screenManager->GetScreenSupportedColorGamuts(id, supportedColorGamut) != SUCCESS) {
365         return false;
366     }
367     for (auto item : supportedColorGamut) {
368         if (item == ScreenColorGamut::COLOR_GAMUT_DCI_P3 || item == ScreenColorGamut::COLOR_GAMUT_DISPLAY_P3) {
369             return true;
370         }
371     }
372     return false;
373 }
374 
HandleColorGamuts(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)375 void RSUniRenderVisitor::HandleColorGamuts(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
376 {
377     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
378     if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
379         RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen type failed.");
380         return;
381     }
382 
383     if (screenType == VIRTUAL_TYPE_SCREEN) {
384         ScreenColorGamut screenColorGamut;
385         if (screenManager->GetScreenColorGamut(node.GetScreenId(), screenColorGamut) != SUCCESS) {
386             RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen color gamut failed.");
387             return;
388         }
389         node.SetColorSpace(static_cast<GraphicColorGamut>(screenColorGamut));
390     }
391     auto colorGamutFeature = GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[COLOR_GAMUT]);
392     auto colorGamutParam = std::static_pointer_cast<ColorGamutParam>(colorGamutFeature);
393     if (colorGamutParam != nullptr && colorGamutParam->IsSLRCloseP3() &&
394         (RSMainThread::Instance()->HasWiredMirrorDisplay() || RSMainThread::Instance()->HasVirtualMirrorDisplay() ||
395         (node.GetScreenId() != 0 && screenType != VIRTUAL_TYPE_SCREEN))) {
396         RS_LOGD("RSUniRenderVisitor::HandleColorGamuts close multi-screen P3.");
397         // wired screen and virtual mirror screen close P3
398         node.SetColorSpace(GRAPHIC_COLOR_GAMUT_SRGB);
399     }
400 }
401 
CheckPixelFormat(RSSurfaceRenderNode & node)402 void RSUniRenderVisitor::CheckPixelFormat(RSSurfaceRenderNode& node)
403 {
404     if (hasFingerprint_[currentVisitDisplay_]) {
405         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat hasFingerprint is true.");
406         return;
407     }
408     if (!curDisplayNode_) {
409         RS_LOGE("RSUniRenderVisitor::CheckPixelFormat curDisplayNode is null");
410         return;
411     }
412     if (node.GetFingerprint()) {
413         hasFingerprint_[currentVisitDisplay_] = true;
414         curDisplayNode_->SetPixelFormat(GRAPHIC_PIXEL_FMT_RGBA_1010102);
415         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat pixelFormate is set 1010102 for fingerprint.");
416         return;
417     }
418     if (!RSSystemProperties::GetHdrImageEnabled()) {
419         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat HdrImageEnabled false");
420         return;
421     }
422     if (node.GetHDRPresent()) {
423         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat HDRService SetHDRPresent true, surfaceNode: %{public}" PRIu64 "",
424             node.GetId());
425         curDisplayNode_->SetHasUniRenderHdrSurface(true);
426         curDisplayNode_->CollectHdrStatus(HdrStatus::HDR_PHOTO);
427         RSHdrUtil::SetHDRParam(node, true);
428         if (curDisplayNode_->GetIsLuminanceStatusChange()) {
429             node.SetContentDirty();
430         }
431     }
432 }
433 
HandlePixelFormat(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)434 void RSUniRenderVisitor::HandlePixelFormat(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
435 {
436     if (!curDisplayNode_) {
437         RS_LOGE("RSUniRenderVisitor::HandlePixelFormat curDisplayNode is null");
438         return;
439     }
440     SetHdrWhenMultiDisplayChange();
441     RS_LOGD("HDRSwitch isHdrImageEnabled: %{public}d, isHdrVideoEnabled: %{public}d",
442         RSSystemProperties::GetHdrImageEnabled(), RSSystemProperties::GetHdrVideoEnabled());
443     ScreenId screenId = node.GetScreenId();
444     bool hasUniRenderHdrSurface = node.GetHasUniRenderHdrSurface();
445     if (RSLuminanceControl::Get().IsCloseHardwareHdr() && !drmNodes_.empty()) {
446         // Disable hdr when drm videos exist to avoid flicker
447         RSLuminanceControl::Get().SetHdrStatus(screenId, HdrStatus::NO_HDR);
448     } else {
449         RSLuminanceControl::Get().SetHdrStatus(screenId, node.GetDisplayHdrStatus());
450     }
451     bool isHdrOn = RSLuminanceControl::Get().IsHdrOn(screenId);
452     rsHdrCollection_->HandleHdrState(isHdrOn);
453     float brightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
454     RS_TRACE_NAME_FMT("HDR:%d, in Unirender:%d brightnessRatio:%f", isHdrOn, hasUniRenderHdrSurface, brightnessRatio);
455     RS_LOGD("RSUniRenderVisitor::HandlePixelFormat HDRService isHdrOn:%{public}d hasUniRenderHdrSurface:%{public}d "
456         "brightnessRatio:%{public}f screenId: %{public}" PRIu64 "", isHdrOn, hasUniRenderHdrSurface,
457         brightnessRatio, screenId);
458     if (!hasUniRenderHdrSurface && !RSLuminanceControl::Get().IsCloseHardwareHdr()) {
459         isHdrOn = false;
460     }
461     node.SetHDRPresent(isHdrOn);
462     hasDisplayHdrOn_ |= isHdrOn;
463     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
464     if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
465         RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen type failed.");
466         return;
467     }
468 
469     if (screenType == VIRTUAL_TYPE_SCREEN) {
470         auto pixelFormat = node.GetPixelFormat();
471         if (screenManager->GetPixelFormat(node.GetScreenId(), pixelFormat) != SUCCESS) {
472             RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen color gamut failed.");
473         } else {
474             node.SetPixelFormat(pixelFormat);
475         }
476     }
477 }
478 
ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode & node)479 void RSUniRenderVisitor::ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode& node)
480 {
481     // record current frame mainwindow or leashwindow node
482     if (node.IsMainWindowType() || node.IsLeashWindow()) {
483         curMainAndLeashWindowNodesIds_.push(node.GetId());
484         RSMainThread::Instance()->GetRSVsyncRateReduceManager().PushWindowNodeId(node.GetId());
485         curDisplayNode_->RecordMainAndLeashSurfaces(node.shared_from_this());
486     }
487     // only reset for instance node
488     if (curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetId()) {
489         return;
490     }
491     if (auto directParent = node.GetParent().lock()) {
492         if (auto parentInstance = directParent->GetInstanceRootNode()) {
493             // in case leashwindow is not directParent
494             auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
495             if (surfaceParent && (surfaceParent->IsLeashWindow() || surfaceParent->IsMainWindowType())) {
496                 curSurfaceNode_ = surfaceParent;
497                 curSurfaceDirtyManager_ = surfaceParent->GetDirtyManager();
498                 filterInGlobal_ = surfaceParent->IsTransparent();
499                 return;
500             }
501             curSurfaceNode_ = nullptr;
502             curSurfaceDirtyManager_ = nullptr;
503             filterInGlobal_ = true;
504         }
505     }
506 }
507 
IsHardwareComposerEnabled()508 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
509 {
510     return !isHardwareForcedDisabled_;
511 }
512 
UpdateSpecialLayersRecord(RSSurfaceRenderNode & node)513 void RSUniRenderVisitor::UpdateSpecialLayersRecord(RSSurfaceRenderNode& node)
514 {
515     if (node.ShouldPaint() == false) {
516         return;
517     }
518     auto specialLayerMgr = node.GetMultableSpecialLayerMgr();
519     if (specialLayerMgr.Find(SpecialLayerType::HAS_SECURITY)) {
520         curDisplayNode_->AddSecurityLayer(node.IsLeashWindow() ? node.GetLeashPersistentId() : node.GetId());
521         curDisplayNode_->AddSecurityVisibleLayer(node.GetId());
522     }
523     if (specialLayerMgr.Find(SpecialLayerType::HAS_PROTECTED)) {
524         screenManager_->SetScreenHasProtectedLayer(currentVisitDisplay_, true);
525         RS_TRACE_NAME_FMT("SetScreenHasProtectedLayer: %d", currentVisitDisplay_);
526     }
527     auto specialLayerType = specialLayerMgr.Get();
528     if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
529         specialLayerType &= ~SpecialLayerType::HAS_SKIP;
530     }
531     curDisplayNode_->GetMultableSpecialLayerMgr().AddIds((specialLayerType >> SPECIAL_TYPE_NUM), node.GetId());
532     if (node.IsSpecialLayerChanged()) {
533         displaySpecailSurfaceChanged_[currentVisitDisplay_] = true;
534     }
535 }
536 
UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode & node)537 void RSUniRenderVisitor::UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode& node)
538 {
539     if (!node.IsMainWindowType()) {
540         return;
541     }
542     auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
543     if (!geoPtr) {
544         return;
545     }
546     if (RSUniRenderUtil::GetRotationDegreeFromMatrix(geoPtr->GetAbsMatrix()) % RS_ROTATION_90 != 0) {
547         node.SetIsRotating(true);
548     }
549 }
550 
IsSubTreeOccluded(RSRenderNode & node) const551 bool RSUniRenderVisitor::IsSubTreeOccluded(RSRenderNode& node) const
552 {
553     if (!isOcclusionEnabled_) {
554         return false;
555     }
556     // step1. apply occlusion info for surfacenode and skip fully covered subtree
557     if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
558         auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
559         if (surfaceNode.IsMainWindowType()) {
560             RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::IsSubTreeOccluded node[%s]"
561                 "name:[%s] visibleRegionIsEmpty[%d]",
562                 std::to_string(node.GetId()).c_str(), surfaceNode.GetName().c_str(),
563                 surfaceNode.GetVisibleRegion().IsEmpty());
564             auto isOccluded = hasMirrorDisplay_ ?
565                 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
566             isOccluded = isOccluded && (!RSUifirstManager::Instance().IsSubTreeNeedPrepareForSnapshot(surfaceNode));
567             if (isOccluded && curSurfaceDirtyManager_) {
568                 curSurfaceDirtyManager_->Clear();
569             }
570             surfaceNode.AccmulateDirtyInOcclusion(isOccluded);
571             return isOccluded;
572         }
573     }
574     // step2.1 For partial visible surface, intersected region->rects in surface
575     // step2.2 check if clean subtree in occlusion rects
576     return false;
577 }
578 
ResetDisplayDirtyRegion()579 void RSUniRenderVisitor::ResetDisplayDirtyRegion()
580 {
581     if (!curDisplayDirtyManager_) {
582         return;
583     }
584     if (curDisplayNode_ == nullptr) {
585         return;
586     }
587     bool ret = CheckScreenPowerChange() ||
588         CheckCurtainScreenUsingStatusChange() ||
589         IsFirstFrameOfPartialRender() ||
590         IsWatermarkFlagChanged() ||
591         zoomStateChange_ ||
592         isCompleteRenderEnabled_ ||
593         curDisplayNode_->GetIsLuminanceStatusChange() ||
594         IsFirstFrameOfOverdrawSwitch() ||
595         IsFirstFrameOfDrawingCacheDfxSwitch() ||
596         IsAccessibilityConfigChanged() ||
597         curDisplayNode_->HasMirroredDisplayChanged();
598 
599 #ifdef RS_ENABLE_OVERLAY_DISPLAY
600     ret = ret || RSOverlayDisplayManager::Instance().CheckStatusChanged();
601 #endif
602     if (ret) {
603         curDisplayDirtyManager_->ResetDirtyAsSurfaceSize();
604         RS_LOGD("RSUniRenderVisitor::ResetDisplayDirtyRegion on");
605     }
606 }
607 
IsAccessibilityConfigChanged() const608 bool RSUniRenderVisitor::IsAccessibilityConfigChanged() const
609 {
610     return RSMainThread::Instance()->IsAccessibilityConfigChanged();
611 }
612 
CheckScreenPowerChange() const613 bool RSUniRenderVisitor::CheckScreenPowerChange() const
614 {
615     if (!RSMainThread::Instance()->GetScreenPowerOnChanged()) {
616         return false;
617     }
618     RS_LOGD("RSUniRenderVisitor::CheckScreenPowerChange changed");
619     return true;
620 }
621 
CheckCurtainScreenUsingStatusChange() const622 bool RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange() const
623 {
624     if (!RSMainThread::Instance()->IsCurtainScreenUsingStatusChanged()) {
625         return false;
626     }
627     RS_LOGD("RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange changed");
628     return true;
629 }
630 
CheckLuminanceStatusChange(ScreenId id)631 bool RSUniRenderVisitor::CheckLuminanceStatusChange(ScreenId id)
632 {
633     // ExchangeLuminanceChangingStatus will be reset false after called in one frame
634     // Use isLuminanceStatusChange_ if need call this function multiple times in one frame
635     if (!RSMainThread::Instance()->ExchangeLuminanceChangingStatus(id)) {
636         return false;
637     }
638     curDisplayNode_->SetIsLuminanceStatusChange(true);
639     RS_LOGD("RSUniRenderVisitor::CheckLuminanceStatusChange changed");
640     return true;
641 }
642 
IsFirstFrameOfPartialRender() const643 bool RSUniRenderVisitor::IsFirstFrameOfPartialRender() const
644 {
645     if (!RSMainThread::Instance()->IsFirstFrameOfPartialRender()) {
646         return false;
647     }
648     RS_LOGD("FirstFrameOfPartialRender");
649     return true;
650 }
651 
IsFirstFrameOfDrawingCacheDfxSwitch() const652 bool RSUniRenderVisitor::IsFirstFrameOfDrawingCacheDfxSwitch() const
653 {
654     return RSMainThread::Instance()->IsFirstFrameOfDrawingCacheDFXSwitch();
655 }
656 
IsFirstFrameOfOverdrawSwitch() const657 bool RSUniRenderVisitor::IsFirstFrameOfOverdrawSwitch() const
658 {
659     if (!RSMainThread::Instance()->IsFirstFrameOfOverdrawSwitch()) {
660         return false;
661     }
662     RS_LOGD("IsFirstFrameOfOverdrawSwitch");
663     return true;
664 }
665 
IsWatermarkFlagChanged() const666 bool RSUniRenderVisitor::IsWatermarkFlagChanged() const
667 {
668     if (RSMainThread::Instance()->IsWatermarkFlagChanged()) {
669         RS_LOGD("FirstOrLastFrameOfWatermark");
670         return true;
671     } else {
672         return false;
673     }
674 }
675 
UpdateDisplayZoomState()676 void RSUniRenderVisitor::UpdateDisplayZoomState()
677 {
678     if (!curDisplayNode_) {
679         return;
680     }
681     auto scale = curDisplayNode_->GetRenderProperties().GetScale();
682     bool curZoomState = scale.x_ > 1.f || scale.y_ > 1.f;
683     curDisplayNode_->UpdateZoomState(curZoomState);
684     zoomStateChange_ = curZoomState || curDisplayNode_->IsZoomStateChange();
685 }
686 
UpdateVirtualScreenInfo(RSDisplayRenderNode & node)687 void RSUniRenderVisitor::UpdateVirtualScreenInfo(RSDisplayRenderNode& node)
688 {
689     // only for virtual screen
690     if (!(node.IsMirrorDisplay())) {
691         node.ClearSecurityLayerList();
692         node.ClearSecurityVisibleLayerList();
693         return;
694     }
695     auto mirrorNode = node.GetMirrorSource().lock();
696     if (mirrorNode == nullptr || screenManager_ == nullptr) {
697         return;
698     }
699 
700     UpdateVirtualScreenSecurityExemption(node, *mirrorNode);
701     UpdateVirtualScreenVisibleRectSecurity(node, *mirrorNode);
702 }
703 
UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode & node,RSDisplayRenderNode & mirrorNode)704 void RSUniRenderVisitor::UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode& node,
705     RSDisplayRenderNode& mirrorNode)
706 {
707     auto securityExemptionList = screenManager_->GetVirtualScreenSecurityExemptionList(node.GetScreenId());
708     if (securityExemptionList.size() == 0) {
709         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:false",
710             node.GetId());
711         node.SetSecurityExemption(false);
712         return;
713     }
714     auto securityLayerList = mirrorNode.GetSecurityLayerList();
715     for (const auto& exemptionLayer : securityExemptionList) {
716         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
717             "securityExemption nodeId %{public}" PRIu64 ".", node.GetId(), exemptionLayer);
718     }
719     for (const auto& secLayer : securityLayerList) {
720         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
721             "securityLayer nodeId %{public}" PRIu64 ".", mirrorNode.GetId(), secLayer);
722     }
723     bool isSecurityExemption = false;
724     if (securityExemptionList.size() >= securityLayerList.size()) {
725         isSecurityExemption = true;
726         for (const auto& secLayer : securityLayerList) {
727             if (std::find(securityExemptionList.begin(), securityExemptionList.end(), secLayer) ==
728                 securityExemptionList.end()) {
729                 isSecurityExemption = false;
730                 break;
731             }
732         }
733     }
734     RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:%{public}d",
735         node.GetId(), isSecurityExemption);
736     node.SetSecurityExemption(isSecurityExemption);
737 }
738 
UpdateVirtualScreenVisibleRectSecurity(RSDisplayRenderNode & node,RSDisplayRenderNode & mirrorNode)739 void RSUniRenderVisitor::UpdateVirtualScreenVisibleRectSecurity(RSDisplayRenderNode& node,
740     RSDisplayRenderNode& mirrorNode)
741 {
742     if (!screenManager_->QueryScreenInfo(node.GetScreenId()).enableVisibleRect) {
743         return;
744     }
745     auto rect = screenManager_->GetMirrorScreenVisibleRect(node.GetScreenId());
746     RectI visibleRect(rect.x, rect.y, rect.w, rect.h);
747     auto securityVisibleLayerList = mirrorNode.GetSecurityVisibleLayerList();
748     bool hasSecLayerInVisibleRect = false;
749     for (const auto& secLayerId : securityVisibleLayerList) {
750         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
751             RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode(secLayerId));
752         if (surfaceNode == nullptr) {
753             continue;
754         }
755         const auto& dstRect = surfaceNode->GetDstRect();
756         if (dstRect.Intersect(visibleRect)) {
757             hasSecLayerInVisibleRect = true;
758             break;
759         }
760     }
761     RS_LOGD("%{public}s: hasSecLayerInVisibleRect:%{public}d.", __func__, hasSecLayerInVisibleRect);
762     node.SetHasSecLayerInVisibleRect(hasSecLayerInVisibleRect);
763 }
764 
UpdateCurFrameInfoDetail(RSRenderNode & node,bool subTreeSkipped,bool isPostPrepare)765 void RSUniRenderVisitor::UpdateCurFrameInfoDetail(RSRenderNode& node, bool subTreeSkipped, bool isPostPrepare)
766 {
767     if (GetDumpRsTreeDetailEnabled()) {
768         auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
769         curFrameInfoDetail.curFrameVsyncId = HgmCore::Instance().GetVsyncId();
770         curFrameInfoDetail.curFrameSubTreeSkipped = subTreeSkipped;
771         if (isPostPrepare) {
772             curFrameInfoDetail.curFramePostPrepareSeqNum = IncreasePostPrepareSeq();
773         } else {
774             curFrameInfoDetail.curFramePrepareSeqNum = IncreasePrepareSeq();
775         }
776     }
777 }
778 
QuickPrepareDisplayRenderNode(RSDisplayRenderNode & node)779 void RSUniRenderVisitor::QuickPrepareDisplayRenderNode(RSDisplayRenderNode& node)
780 {
781     UpdateCurFrameInfoDetail(node);
782     // 0. init display info
783     RS_TRACE_NAME("RSUniRender:QuickPrepareDisplayRenderNode " + std::to_string(node.GetScreenId()));
784     if (!InitDisplayInfo(node)) {
785         return;
786     }
787     UpdateDisplayZoomState();
788     SendRcdMessage(node);
789     UpdateVirtualScreenInfo(node);
790     ancestorNodeHasAnimation_ = false;
791     displayNodeRotationChanged_ = node.IsRotationChanged();
792     dirtyFlag_ = isDirty_ || displayNodeRotationChanged_ || zoomStateChange_ ||
793         curDisplayDirtyManager_->IsActiveSurfaceRectChanged();
794     prepareClipRect_ = screenRect_;
795     hasAccumulatedClip_ = false;
796 
797     globalShouldPaint_ = true;
798     curAlpha_ = 1.0f;
799     globalZOrder_ = 0.0f;
800     appWindowZOrder_ = 0;
801     hasSkipLayer_ = false;
802     curZorderForCalcHwcNodeEnableByFilter_ = 0;
803     node.zOrderForCalcHwcNodeEnableByFilter_ = curZorderForCalcHwcNodeEnableByFilter_++;
804     node.UpdateRotation();
805     if (!(RSMainThread::Instance()->IsRequestedNextVSync() || RSMainThread::Instance()->GetNextDVsyncAnimateFlag())) {
806         RS_OPTIONAL_TRACE_NAME_FMT("do not request next vsync");
807         needRequestNextVsync_ = false;
808     }
809     RSUifirstManager::Instance().SetRotationChanged(displayNodeRotationChanged_ || isScreenRotationAnimating_);
810     if (node.IsSubTreeDirty() || node.IsRotationChanged()) {
811         QuickPrepareChildren(node);
812         TryNotifyUIBufferAvailable();
813     }
814     PostPrepare(node);
815     UpdateHwcNodeEnable();
816     UpdateDisplayRcdRenderNode();
817     UpdateSurfaceDirtyAndGlobalDirty();
818     UpdateSurfaceOcclusionInfo();
819     if (needRecalculateOcclusion_) {
820         // Callback for registered self drawing surfacenode
821         RSMainThread::Instance()->SurfaceOcclusionCallback();
822     }
823     curDisplayNode_->UpdatePartialRenderParams();
824     RSDisplayRenderNode::ScreenRenderParams screenRenderParams;
825     screenRenderParams.screenInfo = std::move(screenInfo_);
826     screenRenderParams.displaySpecailSurfaceChanged = std::move(displaySpecailSurfaceChanged_);
827     screenRenderParams.hasCaptureWindow = std::move(hasCaptureWindow_);
828     curDisplayNode_->SetFingerprint(hasFingerprint_[currentVisitDisplay_]);
829     curDisplayNode_->UpdateScreenRenderParams(screenRenderParams);
830     curDisplayNode_->UpdateOffscreenRenderParams(curDisplayNode_->IsRotationChanged());
831     UpdateColorSpaceAfterHwcCalc(node);
832     RSHdrUtil::UpdatePixelFormatAfterHwcCalc(node);
833     HandleColorGamuts(node, screenManager_);
834     HandlePixelFormat(node, screenManager_);
835     if (UNLIKELY(!SharedTransitionParam::unpairedShareTransitions_.empty())) {
836         ProcessUnpairedSharedTransitionNode();
837     }
838     node.HandleCurMainAndLeashSurfaceNodes();
839     layerNum_ += node.GetSurfaceCountForMultiLayersPerf();
840     node.RenderTraceDebug();
841     containerFilter_.clear();
842     globalFilter_.clear();
843     curSurfaceNoBelowDirtyFilter_.clear();
844     curDisplayNode_->ResetMirroredDisplayChangedFlag();
845     PrepareForMultiScreenViewDisplayNode(node);
846 }
847 
CheckFilterCacheNeedForceClearOrSave(RSRenderNode & node)848 void RSUniRenderVisitor::CheckFilterCacheNeedForceClearOrSave(RSRenderNode& node)
849 {
850     if (!node.HasBlurFilter()) {
851         return;
852     }
853     bool rotationChanged = curDisplayNode_ ?
854         curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
855     bool rotationStatusChanged = curDisplayNode_ ?
856         curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
857     node.CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
858 }
859 
860 // private method, curDisplayNode_ or curSurfaceNode_ will not be nullptr
CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet & filterSet,bool isGlobalDirty)861 void RSUniRenderVisitor::CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet& filterSet, bool isGlobalDirty)
862 {
863     if (curDisplayNode_ == nullptr) {
864         RS_LOGE("RSUniRenderVisitor::CheckMergeFilterDirtyByIntersectWithDirty: curDisplayNode_ is nullptr");
865         return;
866     }
867     // Recursively traverses until the globalDirty do not change
868     auto dirtyManager = isGlobalDirty ? curDisplayNode_->GetDirtyManager() : curSurfaceNode_->GetDirtyManager();
869     if (dirtyManager == nullptr) {
870         return;
871     }
872     for (auto it = filterSet.begin(); it != filterSet.end();) {
873         auto dirtyRect = dirtyManager->GetCurrentFrameDirtyRegion();
874         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
875         auto dirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
876         auto filterDirtyRegion = filterRegion.And(dirtyRegion);
877         if (!filterDirtyRegion.IsEmpty()) {
878             if (isGlobalDirty) {
879                 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
880                     "global dirty %{public}s, add filterRegion %{public}s",
881                     dirtyRect.ToString().c_str(), (it->second).ToString().c_str());
882             }
883             dirtyManager->MergeDirtyRect(it->second);
884             it = filterSet.erase(it);
885             if (dirtyRect != dirtyManager->GetCurrentFrameDirtyRegion()) {
886                 // When dirtyRegion is changed, collect dirty filter region from begin.
887                 // After all filter region is added, the cycle will definitely stop.
888                 it = filterSet.begin();
889             }
890         } else {
891             ++it;
892         }
893     }
894     filterSet.clear();
895 }
896 
PrepareForSkippedCrossNode(RSSurfaceRenderNode & surfaceNode)897 void RSUniRenderVisitor::PrepareForSkippedCrossNode(RSSurfaceRenderNode& surfaceNode)
898 {
899     // 1. Find the actual surface node of which the coordinates must be recalculated.
900     auto sourceNode = surfaceNode.GetSourceCrossNode().lock();
901     auto sourceSurface = sourceNode ? sourceNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
902     RSSurfaceRenderNode& nodeRef = sourceSurface ? *sourceSurface : surfaceNode;
903     auto geoPtr = nodeRef.GetRenderProperties().GetBoundsGeometry();
904     if (!geoPtr) {
905         return;
906     }
907     // 2. Get the AbsMatrix under current display node. Concatenate current parent matrix and nodeRef relative matrix.
908     Drawing::Matrix nodeAbsMatrix = geoPtr->GetMatrix();
909     if (nodeRef.GetGlobalPositionEnabled()) {
910         nodeAbsMatrix.PostTranslate(-curDisplayNode_->GetDisplayOffsetX(), -curDisplayNode_->GetDisplayOffsetY());
911     }
912     if (auto parent = surfaceNode.GetParent().lock()) {
913         auto parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
914         nodeAbsMatrix.PostConcat(parentGeoPtr ? parentGeoPtr->GetAbsMatrix() : Drawing::Matrix());
915     }
916     // 3. Get the conversion matrix from first display coordinate system to current display coordinate system.
917     // 3.1 Invert AbsMatrix under first display.
918     // 3.2 Apply AbsMatrix under second display.
919     Drawing::Matrix conversionMatrix;
920     if (!geoPtr->GetAbsMatrix().Invert(conversionMatrix)) {
921         curDisplayDirtyManager_->ResetDirtyAsSurfaceSize();
922         RS_LOGW("Cross-Node matrix inverting for %{public}s failed, set full screen dirty.", nodeRef.GetName().c_str());
923         return;
924     }
925     conversionMatrix.PostConcat(nodeAbsMatrix);
926 
927     // 4. record this surface node and its position on second display, for global dirty region conversion.
928     curDisplayNode_->RecordMainAndLeashSurfaces(nodeRef.shared_from_this());
929     nodeRef.UpdateCrossNodeSkipDisplayConversionMatrices(curDisplayNode_->GetId(), conversionMatrix);
930     RectI surfaceRect =
931         geoPtr->MapRect(nodeRef.GetOldDirty().ConvertTo<float>(), conversionMatrix).IntersectRect(screenRect_);
932     curDisplayNode_->UpdateSurfaceNodePos(nodeRef.GetId(), surfaceRect);
933     curDisplayNode_->AddSurfaceNodePosByDescZOrder(nodeRef.GetId(), surfaceRect);
934     // 5. record all children surface nodes and their position on second display, for global dirty region conversion.
935     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
936     nodeRef.GetAllSubSurfaceNodes(allSubSurfaceNodes);
937     for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
938         if (auto childPtr = subSurfaceNode.lock()) {
939             curDisplayNode_->RecordMainAndLeashSurfaces(childPtr);
940             childPtr->SetFirstLevelCrossNode(nodeRef.IsFirstLevelCrossNode());
941             childPtr->UpdateCrossNodeSkipDisplayConversionMatrices(curDisplayNode_->GetId(), conversionMatrix);
942             RectI childSurfaceRect = geoPtr->MapRect(
943                 childPtr->GetOldDirty().ConvertTo<float>(), conversionMatrix).IntersectRect(screenRect_);
944             curDisplayNode_->UpdateSurfaceNodePos(childPtr->GetId(), childSurfaceRect);
945             curDisplayNode_->AddSurfaceNodePosByDescZOrder(childPtr->GetId(), childSurfaceRect);
946         }
947     }
948 }
949 
CheckSkipAndPrepareForCrossNode(RSSurfaceRenderNode & node)950 bool RSUniRenderVisitor::CheckSkipAndPrepareForCrossNode(RSSurfaceRenderNode& node)
951 {
952     auto sourceRenderNode = node.GetSourceCrossNode().lock();
953     RSSurfaceRenderNode::SharedPtr sourceNode = sourceRenderNode ?
954         sourceRenderNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
955     // CloneCrossNode must have a source node.
956     if (node.IsCloneCrossNode() && sourceNode == nullptr) {
957         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode source node of clone node %{public}"
958             PRIu64 " is null", node.GetId());
959         return true;
960     }
961 
962     // skip CrossNode not on first display
963     if (CheckSkipCrossNode(node)) {
964         // when skip cloneCrossNode prepare, we need switch to record sourceNode dirty info
965         PrepareForSkippedCrossNode(node);
966         return true;
967     }
968 
969     // when prepare CloneCrossNode on first display, we need switch to prepare sourceNode.
970     if (node.IsCloneCrossNode()) {
971         isSwitchToSourceCrossNodePrepare_ = true;
972         sourceNode->SetCurCloneNodeParent(node.GetParent().lock());
973         sourceNode->QuickPrepare(shared_from_this());
974         sourceNode->SetCurCloneNodeParent(nullptr);
975         isSwitchToSourceCrossNodePrepare_ = false;
976         return true;
977     }
978     return false;
979 }
980 
QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode & node)981 void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
982 {
983     UpdateCurFrameInfoDetail(node);
984     RS_TRACE_NAME_FMT("RSUniRender::QuickPrepare:[%s] nodeId[%" PRIu64 "] pid[%d] nodeType[%u]"
985         " subTreeDirty[%d], crossDisplay:[%d]", node.GetName().c_str(), node.GetId(), ExtractPid(node.GetId()),
986         static_cast<uint>(node.GetSurfaceNodeType()), node.IsSubTreeDirty(), node.IsFirstLevelCrossNode());
987     RS_LOGD("RSUniRender::QuickPrepareSurfaceRenderNode:[%{public}s] nodeid:[%{public}" PRIu64 "] pid:[%{public}d] "
988         "nodeType:[%{public}d] subTreeDirty[%{public}d] crossDisplay[%{public}d]", node.GetName().c_str(), node.GetId(),
989         ExtractPid(node.GetId()), static_cast<int>(node.GetSurfaceNodeType()), node.IsSubTreeDirty(),
990         node.IsFirstLevelCrossNode());
991 
992     if (PrepareForCloneNode(node)) {
993         return;
994     }
995 
996     // AppWindow is traversed in reverse order
997     // Prepare operation will be executed first when the node is at the top level
998     // The value of appWindowZOrder_ decreases from 0 to negative
999     if (node.IsAppWindow()) {
1000         node.SetAppWindowZOrder(appWindowZOrder_--);
1001     }
1002 
1003     // avoid cross node subtree visited twice or more
1004     UpdateSpecialLayersRecord(node);
1005     if (CheckSkipAndPrepareForCrossNode(node)) {
1006         return;
1007     }
1008     // 0. init curSurface info and check node info
1009     auto curCornerRadius = curCornerRadius_;
1010     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
1011     if (!BeforeUpdateSurfaceDirtyCalc(node)) {
1012         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode BeforeUpdateSurfaceDirtyCalc fail");
1013         RSUifirstManager::Instance().DisableUifirstNode(node);
1014         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1015         return;
1016     }
1017 
1018     if (curSurfaceDirtyManager_ == nullptr) {
1019         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
1020             node.GetName().c_str());
1021         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1022         return;
1023     }
1024     curSurfaceDirtyManager_->SetAdvancedDirtyRegionType(advancedDirtyType_);
1025 
1026     // 1. Update matrix and collect dirty region
1027     auto dirtyFlag = dirtyFlag_;
1028     auto prepareClipRect = prepareClipRect_;
1029     bool hasAccumulatedClip = hasAccumulatedClip_;
1030     auto prevAlpha = curAlpha_;
1031     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1032     node.SetGlobalAlpha(curAlpha_);
1033     auto preGlobalShouldPaint = globalShouldPaint_;
1034     globalShouldPaint_ &= node.ShouldPaint();
1035     node.SetSelfAndParentShouldPaint(globalShouldPaint_);
1036     CheckFilterCacheNeedForceClearOrSave(node);
1037     node.CheckContainerDirtyStatusAndUpdateDirty(curContainerDirty_);
1038     node.ClearCrossNodeSkipDisplayConversionMatrices();
1039     node.SetPreparedDisplayOffsetX(curDisplayNode_->GetDisplayOffsetX());
1040     node.SetPreparedDisplayOffsetY(curDisplayNode_->GetDisplayOffsetY());
1041     if (node.GetGlobalPositionEnabled()) {
1042         parentSurfaceNodeMatrix_.Translate(
1043             -curDisplayNode_->GetDisplayOffsetX(), -curDisplayNode_->GetDisplayOffsetY());
1044     }
1045 
1046     dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
1047         *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix);
1048     auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
1049     if (!geoPtr) {
1050         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1051         globalShouldPaint_ = preGlobalShouldPaint;
1052         return;
1053     }
1054     parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
1055     if (!AfterUpdateSurfaceDirtyCalc(node)) {
1056         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode AfterUpdateSurfaceDirtyCalc fail");
1057         RSUifirstManager::Instance().DisableUifirstNode(node);
1058         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1059         globalShouldPaint_ = preGlobalShouldPaint;
1060         return;
1061     }
1062     bool isDimmingOn = RSLuminanceControl::Get().IsDimmingOn(curDisplayNode_->GetScreenId());
1063     if (isDimmingOn) {
1064         bool hasHdrPresent = node.GetHDRPresent();
1065         bool hasHdrVideo = node.GetVideoHdrStatus() != HdrStatus::NO_HDR;
1066         RS_LOGD("HDRDiming IsDimmingOn: %{public}d, GetHDRPresent: %{public}d, GetHdrVideo: %{public}d",
1067             isDimmingOn, hasHdrPresent, hasHdrVideo);
1068         if (hasHdrPresent || hasHdrVideo) {
1069             node.SetContentDirty(); // HDR content is dirty on Dimming status.
1070         }
1071     }
1072     CollectSelfDrawingNodeRectInfo(node);
1073     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1074     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_, IsSubTreeOccluded(node)) ||
1075         ForcePrepareSubTree();
1076     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1077         node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
1078     if (curSurfaceDirtyManager_ == nullptr) {
1079         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager "
1080             "is set to nullptr by QuickPrepareChildren", node.GetName().c_str());
1081         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1082         globalShouldPaint_ = preGlobalShouldPaint;
1083         return;
1084     }
1085     if (!node.IsFirstLevelCrossNode()) {
1086         curSurfaceDirtyManager_->ClipDirtyRectWithinSurface();
1087     }
1088     auto dirtyRect = node.GetDirtyManager()->GetCurrentFrameDirtyRegion();
1089     RS_LOGD("QuickPrepare [%{public}s, %{public}" PRIu64 "] DirtyRect[%{public}d, %{public}d, %{public}d, %{public}d]",
1090         node.GetName().c_str(), node.GetId(), dirtyRect.GetLeft(), dirtyRect.GetTop(), dirtyRect.GetWidth(),
1091         dirtyRect.GetHeight());
1092 
1093     // Update whether leash window's visible region is empty after prepare children
1094     UpdateLeashWindowVisibleRegionEmpty(node);
1095 
1096     if (node.IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()) {
1097         CheckIsGpuOverDrawBufferOptimizeNode(node);
1098     }
1099     PostPrepare(node, !isSubTreeNeedPrepare);
1100     if (node.IsHardwareEnabledTopSurface() && node.shared_from_this()) {
1101         RSUniRenderUtil::UpdateHwcNodeProperty(node.shared_from_this()->ReinterpretCastTo<RSSurfaceRenderNode>());
1102     }
1103     CalculateOpaqueAndTransparentRegion(node);
1104     CheckMergeFilterDirtyByIntersectWithDirty(curSurfaceNoBelowDirtyFilter_, false);
1105     curAlpha_ = prevAlpha;
1106     globalShouldPaint_ = preGlobalShouldPaint;
1107     prepareClipRect_ = prepareClipRect;
1108     hasAccumulatedClip_ = hasAccumulatedClip;
1109     dirtyFlag_ = dirtyFlag;
1110     PrepareForUIFirstNode(node);
1111     PrepareForCrossNode(node);
1112     node.UpdateInfoForClonedNode(clonedSourceNodeId_);
1113     node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1114     ResetCurSurfaceInfoAsUpperSurfaceParent(node);
1115     curCornerRadius_ = curCornerRadius;
1116     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
1117 
1118     // [Attention] Only used in PC window resize scene now
1119     windowKeyFrameNodeInf_.PrepareRootNodeOffscreen(node);
1120 
1121     node.RenderTraceDebug();
1122     node.SetNeedOffscreen(isScreenRotationAnimating_);
1123     if (node.NeedUpdateDrawableBehindWindow()) {
1124         node.UpdateDrawableBehindWindow();
1125         node.SetOldNeedDrawBehindWindow(node.NeedDrawBehindWindow());
1126     }
1127     if (node.IsUIBufferAvailable()) {
1128         uiBufferAvailableId_.emplace_back(node.GetId());
1129     }
1130     PrepareForMultiScreenViewSurfaceNode(node);
1131 }
1132 
PrepareForMultiScreenViewSurfaceNode(RSSurfaceRenderNode & node)1133 void RSUniRenderVisitor::PrepareForMultiScreenViewSurfaceNode(RSSurfaceRenderNode& node)
1134 {
1135     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1136     auto sourceNode = nodeMap.GetRenderNode<RSDisplayRenderNode>(node.GetSourceDisplayRenderNodeId());
1137     if (!sourceNode) {
1138         return;
1139     }
1140     node.SetContentDirty();
1141     sourceNode->SetTargetSurfaceRenderNodeId(node.GetId());
1142     auto sourceNodeDrawable = sourceNode->GetRenderDrawable();
1143     if (!sourceNodeDrawable) {
1144         return;
1145     }
1146     RS_TRACE_NAME_FMT("PrepareForMultiScreenViewSurfaceNode surfaceNodeId: %llu sourceVirtualDisplayId: %llu",
1147         node.GetId(), node.GetSourceDisplayRenderNodeId());
1148     node.SetSourceDisplayRenderNodeDrawable(sourceNodeDrawable);
1149 }
1150 
PrepareForMultiScreenViewDisplayNode(RSDisplayRenderNode & node)1151 void RSUniRenderVisitor::PrepareForMultiScreenViewDisplayNode(RSDisplayRenderNode& node)
1152 {
1153     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1154     auto targetNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(node.GetTargetSurfaceRenderNodeId());
1155     if (!targetNode) {
1156         return;
1157     }
1158     auto targetRenderNodeDrawable = targetNode->GetRenderDrawable();
1159     if (!targetRenderNodeDrawable) {
1160         return;
1161     }
1162     RS_TRACE_NAME_FMT("PrepareForMultiScreenViewDisplayNode displayNodeId: %llu targetSurfaceRenderNodeId: %llu",
1163         node.GetId(), node.GetTargetSurfaceRenderNodeId());
1164     node.SetTargetSurfaceRenderNodeDrawable(targetRenderNodeDrawable);
1165 }
1166 
PrepareForCloneNode(RSSurfaceRenderNode & node)1167 bool RSUniRenderVisitor::PrepareForCloneNode(RSSurfaceRenderNode& node)
1168 {
1169     if (!node.IsCloneNode() || !node.IsLeashOrMainWindow()) {
1170         return false;
1171     }
1172     RS_LOGD("RSUniRenderVisitor::PrepareForCloneNode %{public}s is cloneNode", node.GetName().c_str());
1173     node.SetIsClonedNodeOnTheTree(false);
1174     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1175     auto clonedNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(node.GetClonedNodeId());
1176     if (clonedNode == nullptr) {
1177         RS_LOGE("RSUniRenderVisitor::PrepareForCloneNode clonedNode is nullptr");
1178         return false;
1179     }
1180     if (!clonedNode->IsMainWindowType()) {
1181         return false;
1182     }
1183     auto clonedNodeRenderDrawable = clonedNode->GetRenderDrawable();
1184     if (clonedNodeRenderDrawable == nullptr) {
1185         RS_LOGE("RSUniRenderVisitor::PrepareForCloneNode clonedNodeRenderDrawable is nullptr");
1186         return false;
1187     }
1188     node.SetIsClonedNodeOnTheTree(clonedNode->IsOnTheTree());
1189     clonedSourceNodeId_ = node.GetClonedNodeId();
1190     node.SetClonedNodeRenderDrawable(clonedNodeRenderDrawable);
1191     node.UpdateRenderParams();
1192     node.AddToPendingSyncList();
1193     return true;
1194 }
1195 
PrepareForCrossNode(RSSurfaceRenderNode & node)1196 void RSUniRenderVisitor::PrepareForCrossNode(RSSurfaceRenderNode& node)
1197 {
1198     if (isCrossNodeOffscreenOn_ == CrossNodeOffScreenRenderDebugType::DISABLED) {
1199         return;
1200     }
1201     if (curDisplayNode_ == nullptr) {
1202         RS_LOGE("%{public}s curDisplayNode_ is nullptr", __func__);
1203         return;
1204     }
1205     if (curDisplayNode_->IsFirstVisitCrossNodeDisplay() && node.IsCrossNode()) {
1206         // check surface cache condition, not support ratation, transparent filter situation.
1207         bool needCacheSurface = node.QuerySubAssignable(curDisplayNode_->IsRotationChanged());
1208         if (needCacheSurface) {
1209             node.SetHwcChildrenDisabledState();
1210             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " children disabled by crossNode",
1211                 node.GetName().c_str(), node.GetId());
1212         }
1213         node.SetNeedCacheSurface(needCacheSurface);
1214     }
1215 }
1216 
CheckSkipCrossNode(RSSurfaceRenderNode & node)1217 bool RSUniRenderVisitor::CheckSkipCrossNode(RSSurfaceRenderNode& node)
1218 {
1219     if (!node.IsCrossNode() || isSwitchToSourceCrossNodePrepare_) {
1220         return false;
1221     }
1222     if (curDisplayNode_ == nullptr) {
1223         RS_LOGE("%{public}s curDisplayNode_ is nullptr", __func__);
1224         return false;
1225     }
1226     node.SetCrossNodeOffScreenStatus(isCrossNodeOffscreenOn_);
1227     curDisplayNode_->SetHasChildCrossNode(true);
1228     if (hasVisitCrossNode_) {
1229         RS_OPTIONAL_TRACE_NAME_FMT("%s cross node[%s] skip", __func__, node.GetName().c_str());
1230         return true;
1231     }
1232     curDisplayNode_->SetIsFirstVisitCrossNodeDisplay(true);
1233     hasVisitCrossNode_ = true;
1234     return false;
1235 }
1236 
CollectTopOcclusionSurfacesInfo(RSSurfaceRenderNode & node,bool isParticipateInOcclusion)1237 void RSUniRenderVisitor::CollectTopOcclusionSurfacesInfo(RSSurfaceRenderNode& node, bool isParticipateInOcclusion)
1238 {
1239     if (!isStencilPixelOcclusionCullingEnabled_) {
1240         return;
1241     }
1242     auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1243     if (!parent || !parent->IsLeashWindow()) {
1244         return;
1245     }
1246     auto stencilVal = occlusionSurfaceOrder_ * OCCLUSION_ENABLE_SCENE_NUM;
1247     if (!isParticipateInOcclusion) {
1248         if (occlusionSurfaceOrder_ < TOP_OCCLUSION_SURFACES_NUM) {
1249             parent->SetStencilVal(stencilVal);
1250         }
1251         return;
1252     }
1253     parent->SetStencilVal(stencilVal);
1254     if (occlusionSurfaceOrder_ > 0) {
1255         auto opaqueRegionRects = node.GetOpaqueRegion().GetRegionRects();
1256         if (curDisplayNode_ == nullptr) {
1257             RS_LOGE("RSUniRenderVisitor::CollectTopOcclusionSurfacesInfo curDisplayNode_ is nullptr");
1258             return;
1259         }
1260         if (!opaqueRegionRects.empty()) {
1261             auto maxOpaqueRect = std::max_element(opaqueRegionRects.begin(), opaqueRegionRects.end(),
1262                 [](Occlusion::Rect a, Occlusion::Rect b) ->bool { return a.Area() < b.Area(); });
1263             curDisplayNode_->RecordTopSurfaceOpaqueRects(*maxOpaqueRect);
1264             parent->SetStencilVal(stencilVal);
1265             RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::CollectTopOcclusionSurfacesInfo record name[%s] rect[%s]",
1266                 node.GetName().c_str(), (*maxOpaqueRect).GetRectInfo().c_str());
1267             --occlusionSurfaceOrder_;
1268         }
1269     }
1270 }
1271 
PrepareForUIFirstNode(RSSurfaceRenderNode & node)1272 void RSUniRenderVisitor::PrepareForUIFirstNode(RSSurfaceRenderNode& node)
1273 {
1274     RSUifirstManager::Instance().MarkSubHighPriorityType(node);
1275     auto isSurface = CheckIfSurfaceForUIFirstDFX(node.GetName());
1276     if (isTargetUIFirstDfxEnabled_) {
1277         auto isTargetUIFirstDfxSurface = CheckIfSurfaceForUIFirstDFX(node.GetName());
1278         if (!node.isTargetUIFirstDfxEnabled_ && isTargetUIFirstDfxSurface) {
1279             RS_LOGD("UIFirstDFX Name[%{public}s] ID[%{public}" PRIu64 "] OpenDebug",
1280                 node.GetName().c_str(), node.GetId());
1281         }
1282         node.isTargetUIFirstDfxEnabled_ = isTargetUIFirstDfxSurface;
1283     }
1284     RSUifirstManager::Instance().UpdateUifirstNodes(node, ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation());
1285 }
1286 
UpdateNodeVisibleRegion(RSSurfaceRenderNode & node)1287 void RSUniRenderVisitor::UpdateNodeVisibleRegion(RSSurfaceRenderNode& node)
1288 {
1289     if (!curDisplayNode_) {
1290         RS_LOGE("RSUniRenderVisitor::UpdateNodeVisibleRegion curDisplayNode is nullptr");
1291         return;
1292     }
1293     // occlusion - 0. Calculate node visible region considering accumulated opaque region of upper surface nodes.
1294     if (!curDisplayNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) {
1295         RS_LOGD("RSUniRenderVisitor::UpdateNodeVisibleRegion NodeName: %{public}s, NodeId: %{public}" PRIu64 ""
1296             "not paticipate in occlusion when cross node in expand screen", node.GetName().c_str(), node.GetId());
1297         return;
1298     }
1299     Occlusion::Rect selfDrawRect = node.GetSurfaceOcclusionRect(true);
1300     Occlusion::Region selfDrawRegion { selfDrawRect };
1301     needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.CheckIfOcclusionChanged();
1302     if (needRecalculateOcclusion_) {
1303         Occlusion::Region subResult = selfDrawRegion.Sub(accumulatedOcclusionRegion_);
1304         node.SetVisibleRegion(subResult);
1305         Occlusion::Region subResultWithoutSkipLayer = selfDrawRegion.Sub(occlusionRegionWithoutSkipLayer_);
1306         node.SetVisibleRegionInVirtual(subResultWithoutSkipLayer);
1307     }
1308     RS_OPTIONAL_TRACE_NAME_FMT_LEVEL(TRACE_LEVEL_THREE,
1309         "RSUniRenderVisitor::UpdateNodeVisibleRegion name[%s] visibleRegion[%s]",
1310         node.GetName().c_str(), node.GetVisibleRegion().GetRegionInfo().c_str());
1311 }
1312 
CalculateOpaqueAndTransparentRegion(RSSurfaceRenderNode & node)1313 void RSUniRenderVisitor::CalculateOpaqueAndTransparentRegion(RSSurfaceRenderNode& node)
1314 {
1315     if (!curDisplayNode_) {
1316         RS_LOGE("RSUniRenderVisitor::CalculateOpaqueAndTransparentRegion curDisplayNode is nullptr");
1317         return;
1318     }
1319     // occlusion - 1. Only non-cross-screen main window surface node participate in occlusion.
1320     if ((!curDisplayNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) ||
1321         !node.IsMainWindowType()) {
1322         RS_LOGD("RSUniRenderVisitor::CalculateOpaqueAndTransparentRegion Node: %{public}s, NodeId: %{public}" PRIu64 ""
1323             "not paticipate in occlusion", node.GetName().c_str(), node.GetId());
1324         return;
1325     }
1326 
1327     // occlusion - 2. Calculate opaque/transparent region based on round corner, container window, etc.
1328     auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1329     auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
1330         (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
1331     node.CheckAndUpdateOpaqueRegion(screenRect_, curDisplayNode_->GetRotation(), isFocused);
1332     // occlusion - 3. Accumulate opaque region to occlude lower surface nodes (with/without special layer).
1333     hasSkipLayer_ = hasSkipLayer_ || node.GetSpecialLayerMgr().Find(SpecialLayerType::SKIP);
1334     auto mainThread = RSMainThread::Instance();
1335     node.SetOcclusionInSpecificScenes(mainThread->GetIsRegularAnimation());
1336     bool occlusionInAnimation = node.GetOcclusionInSpecificScenes() || !ancestorNodeHasAnimation_;
1337     bool isParticipateInOcclusion = node.CheckParticipateInOcclusion() &&
1338         occlusionInAnimation && !isAllSurfaceVisibleDebugEnabled_;
1339     CollectTopOcclusionSurfacesInfo(node, isParticipateInOcclusion);
1340     if (isParticipateInOcclusion) {
1341         RS_OPTIONAL_TRACE_NAME_FMT("Occlusion: surface node[%s] participate in occlusion with opaque region: [%s]",
1342             node.GetName().c_str(), node.GetOpaqueRegion().GetRegionInfo().c_str());
1343         accumulatedOcclusionRegion_.OrSelf(node.GetOpaqueRegion());
1344         if (IsValidInVirtualScreen(node)) {
1345             occlusionRegionWithoutSkipLayer_.OrSelf(node.GetOpaqueRegion());
1346         }
1347     }
1348     needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.CheckIfOcclusionChanged();
1349     node.SetOcclusionInSpecificScenes(false);
1350     CollectOcclusionInfoForWMS(node);
1351     RSMainThread::Instance()->GetRSVsyncRateReduceManager().CollectSurfaceVsyncInfo(screenInfo_, node);
1352 }
1353 
CollectOcclusionInfoForWMS(RSSurfaceRenderNode & node)1354 void RSUniRenderVisitor::CollectOcclusionInfoForWMS(RSSurfaceRenderNode& node)
1355 {
1356     if (!node.IsMainWindowType()) {
1357         return;
1358     }
1359     // collect mainWindow occlusion visibleLevel
1360     Occlusion::Region selfDrawRegion { node.GetSurfaceOcclusionRect(true) };
1361     auto visibleLevel = GetRegionVisibleLevel(node.GetVisibleRegion(), selfDrawRegion);
1362 
1363     // wms default all visible about sefdrawing node and AbilityComponent node
1364     auto instanceNode = node.GetInstanceRootNode() ?
1365         node.GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1366     if (instanceNode == nullptr) {
1367         return;
1368     }
1369     if ((node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
1370         !instanceNode->GetVisibleRegion().IsEmpty()) || node.IsAbilityComponent()) {
1371         dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1372             WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1373         return;
1374     }
1375     dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1376         node.GetVisibleLevelForWMS(visibleLevel)));
1377 }
1378 
SurfaceOcclusionCallbackToWMS()1379 void RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS()
1380 {
1381     if (RSSystemParameters::GetOcclusionCallBackToWMSDebugType()) {
1382         allDstCurVisVec_.clear();
1383         const auto& curAllSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1384         for (const auto& surfacePtr : curAllSurfaces) {
1385             if (surfacePtr == nullptr) {
1386                 continue;
1387             }
1388             const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*surfacePtr);
1389             if (surfaceNode.IsMainWindowType()) {
1390                 allDstCurVisVec_.emplace_back(std::make_pair(surfacePtr->GetId(),
1391                     WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1392             }
1393         }
1394     }
1395     if (allDstCurVisVec_ != allLastVisVec_) {
1396         RSMainThread::Instance()->SurfaceOcclusionChangeCallback(allDstCurVisVec_);
1397         RS_LOGI("OcclusionInfo %{public}s", VisibleDataToString(allDstCurVisVec_).c_str());
1398         allLastVisVec_ = std::move(allDstCurVisVec_);
1399     }
1400 }
1401 
GetRegionVisibleLevel(const Occlusion::Region & visibleRegion,const Occlusion::Region & selfDrawRegion)1402 RSVisibleLevel RSUniRenderVisitor::GetRegionVisibleLevel(const Occlusion::Region& visibleRegion,
1403     const Occlusion::Region& selfDrawRegion)
1404 {
1405     if (visibleRegion.IsEmpty()) {
1406         return RSVisibleLevel::RS_INVISIBLE;
1407     } else if (visibleRegion.Area() == selfDrawRegion.Area()) {
1408         return RSVisibleLevel::RS_ALL_VISIBLE;
1409     } else if (static_cast<uint>(visibleRegion.Area()) <
1410         (static_cast<uint>(selfDrawRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
1411         return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
1412     }
1413     return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
1414 }
1415 
QuickPrepareEffectRenderNode(RSEffectRenderNode & node)1416 void RSUniRenderVisitor::QuickPrepareEffectRenderNode(RSEffectRenderNode& node)
1417 {
1418     UpdateCurFrameInfoDetail(node);
1419     // 0. check current node need to tranverse
1420     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
1421     if (!dirtyManager) {
1422         RS_LOGE("RSUniRenderVisitor::QuickPrepareEffectRenderNode dirtyManager is nullptr");
1423         return;
1424     }
1425     auto dirtyFlag = dirtyFlag_;
1426     auto prevAlpha = curAlpha_;
1427     auto curCornerRadius = curCornerRadius_;
1428     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1429     UpdateRotationStatusForEffectNode(node);
1430     CheckFilterCacheNeedForceClearOrSave(node);
1431     RectI prepareClipRect = prepareClipRect_;
1432     bool hasAccumulatedClip = hasAccumulatedClip_;
1433     dirtyFlag_ =
1434         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1435     node.UpdateCurCornerRadius(curCornerRadius_);
1436     // 1. Recursively traverse child nodes
1437     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1438     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
1439     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1440         node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1441 
1442     PostPrepare(node, !isSubTreeNeedPrepare);
1443     prepareClipRect_ = prepareClipRect;
1444     hasAccumulatedClip_ = hasAccumulatedClip;
1445     dirtyFlag_ = dirtyFlag;
1446     curAlpha_ = prevAlpha;
1447     curCornerRadius_ = curCornerRadius;
1448     node.RenderTraceDebug();
1449 }
1450 
QuickPrepareCanvasRenderNode(RSCanvasRenderNode & node)1451 void RSUniRenderVisitor::QuickPrepareCanvasRenderNode(RSCanvasRenderNode& node)
1452 {
1453     UpdateCurFrameInfoDetail(node);
1454     // 0. check current node need to traverse
1455     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
1456     auto dirtyFlag = dirtyFlag_;
1457     auto prevAlpha = curAlpha_;
1458     auto curCornerRadius = curCornerRadius_;
1459     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1460     const auto& property = node.GetRenderProperties();
1461     auto preIsOffscreen = isOffscreen_;
1462     isOffscreen_ = isOffscreen_ || (property.IsColorBlendApplyTypeOffscreen() && !property.IsColorBlendModeNone());
1463     auto preGlobalShouldPaint = globalShouldPaint_;
1464     globalShouldPaint_ &= node.ShouldPaint();
1465     CheckFilterCacheNeedForceClearOrSave(node);
1466     if (IsAccessibilityConfigChanged()) {
1467         node.SetIsAccessibilityConfigChanged(true);
1468     }
1469     if (isDrawingCacheEnabled_) {
1470         node.UpdateDrawingCacheInfoBeforeChildren(isScreenRotationAnimating_);
1471     }
1472     node.SetIsAccessibilityConfigChanged(false);
1473     node.OpincQuickMarkStableNode(unchangeMarkInApp_, unchangeMarkEnable_,
1474         IsAccessibilityConfigChanged());
1475     RectI prepareClipRect = prepareClipRect_;
1476     bool hasAccumulatedClip = hasAccumulatedClip_;
1477 
1478     if (!dirtyManager) {
1479         return;
1480     }
1481     dirtyFlag_ =
1482         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1483     // update prepare clip before children
1484     UpdatePrepareClip(node);
1485     node.UpdateCurCornerRadius(curCornerRadius_);
1486     // The meaning of first prepared offscreen node is either its colorBlendApplyType is not FAST or
1487     // its colorBlendMode is None
1488     // Node will classified as blnedWithBackground if it is the first prepared offscreen node and
1489     // its colorBlendMode is neither NONE nor SRC_OVER
1490     node.SetBlendWithBackground(!preIsOffscreen && isOffscreen_ && property.IsColorBlendModeValid());
1491     // 1. Recursively traverse child nodes if above curSurfaceNode and subnode need draw
1492     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1493     bool isSubTreeNeedPrepare = !curSurfaceNode_ || node.IsSubTreeNeedPrepare(filterInGlobal_) ||
1494         ForcePrepareSubTree() || node.OpincForcePrepareSubTree(autoCacheEnable_);
1495     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1496         node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1497 
1498     PostPrepare(node, !isSubTreeNeedPrepare);
1499     prepareClipRect_ = prepareClipRect;
1500     hasAccumulatedClip_ = hasAccumulatedClip;
1501     dirtyFlag_ = dirtyFlag;
1502     curAlpha_ = prevAlpha;
1503     isOffscreen_ = preIsOffscreen;
1504     curCornerRadius_ = curCornerRadius;
1505     node.OpincUpdateRootFlag(unchangeMarkEnable_);
1506     globalShouldPaint_ = preGlobalShouldPaint;
1507 
1508     // [Attention] Only used in PC window resize scene now
1509     NodeId linedRootNodeId = node.GetLinkedRootNodeId();
1510     if (UNLIKELY(linedRootNodeId != INVALID_NODEID)) {
1511         windowKeyFrameNodeInf_.UpdateLinkedNodeId(node.GetId(), linedRootNodeId);
1512     }
1513 
1514     node.RenderTraceDebug();
1515 }
1516 
UpdateRotationStatusForEffectNode(RSEffectRenderNode & node)1517 void RSUniRenderVisitor::UpdateRotationStatusForEffectNode(RSEffectRenderNode& node)
1518 {
1519      // folding/expanding screen force invalidate cache.
1520     node.SetFoldStatusChanged(doAnimate_ &&
1521         curDisplayNode_->GetScreenId() != node.GetCurrentAttachedScreenId());
1522     node.SetCurrentAttachedScreenId(curDisplayNode_->GetScreenId());
1523     node.SetRotationChanged(curDisplayNode_->IsRotationChanged());
1524 }
1525 
UpdatePrepareClip(RSRenderNode & node)1526 void RSUniRenderVisitor::UpdatePrepareClip(RSRenderNode& node)
1527 {
1528     const auto& property = node.GetRenderProperties();
1529     auto& geoPtr = property.GetBoundsGeometry();
1530     if (geoPtr == nullptr) {
1531         return;
1532     }
1533     // Dirty Region use abstract coordinate, property of node use relative coordinate
1534     // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
1535     if (property.GetClipToBounds()) {
1536         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
1537     }
1538     // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
1539     if (property.GetClipToFrame()) {
1540         // MapAbsRect do not handle the translation of OffsetX and OffsetY
1541         RectF frameRect{
1542             property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
1543             property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
1544             property.GetFrameWidth(), property.GetFrameHeight()};
1545         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
1546     }
1547     if (property.GetClipToRRect()) {
1548         RectF rect = property.GetClipRRect().rect_;
1549         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(rect));
1550     }
1551 }
1552 
IsLeashAndHasMainSubNode(RSRenderNode & node) const1553 bool RSUniRenderVisitor::IsLeashAndHasMainSubNode(RSRenderNode& node) const
1554 {
1555     if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1556         return false;
1557     }
1558     const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1559     if (!surfaceNode.IsLeashWindow()) {
1560         return false;
1561     }
1562     // check leashWindow surface has first level mainwindow node
1563     auto children = node.GetSortedChildren();
1564     auto iter = std::find_if((*children).begin(), (*children).end(),
1565         [](const std::shared_ptr<RSRenderNode>& node) {
1566         if (node && node->GetType() == RSRenderNodeType::SURFACE_NODE) {
1567             const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*node);
1568             return surfaceNode.IsMainWindowType();
1569         }
1570         return false;
1571     });
1572     return iter != (*children).end();
1573 }
1574 
NeedPrepareChindrenInReverseOrder(RSRenderNode & node) const1575 bool RSUniRenderVisitor::NeedPrepareChindrenInReverseOrder(RSRenderNode& node) const
1576 {
1577     if (!curSurfaceNode_ && node.GetType() != RSRenderNodeType::RS_NODE) {
1578         return true;
1579     }
1580     return IsLeashAndHasMainSubNode(node);
1581 }
1582 
QuickPrepareChildren(RSRenderNode & node)1583 void RSUniRenderVisitor::QuickPrepareChildren(RSRenderNode& node)
1584 {
1585     MergeRemovedChildDirtyRegion(node, true);
1586     if (node.LastFrameSubTreeSkipped() && curSurfaceDirtyManager_) {
1587         node.ForceMergeSubTreeDirtyRegion(*curSurfaceDirtyManager_, prepareClipRect_);
1588     }
1589     bool animationBackup = ancestorNodeHasAnimation_;
1590     ancestorNodeHasAnimation_ = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
1591     node.ResetChildRelevantFlags();
1592     node.ResetChildUifirstSupportFlag();
1593     auto children = node.GetSortedChildren();
1594     if (NeedPrepareChindrenInReverseOrder(node)) {
1595         auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
1596         curFrameInfoDetail.curFrameReverseChildren = true;
1597         RS_LOGD("RSUniRenderVisitor::%{public}s NeedPrepareChindrenInReverseOrder nodeId: %{public}" PRIu64,
1598             __func__, node.GetId());
1599         std::for_each(
1600             (*children).rbegin(), (*children).rend(), [this, &node](const std::shared_ptr<RSRenderNode>& child) {
1601             if (!child) {
1602                 return;
1603             }
1604             auto containerDirty = curContainerDirty_;
1605             curDirty_ = child->IsDirty();
1606             curContainerDirty_ = curContainerDirty_ || child->IsDirty();
1607             child->SetFirstLevelCrossNode(node.IsFirstLevelCrossNode() || child->IsCrossNode());
1608             child->zOrderForCalcHwcNodeEnableByFilter_ = curZorderForCalcHwcNodeEnableByFilter_++;
1609             child->QuickPrepare(shared_from_this());
1610             curContainerDirty_ = containerDirty;
1611         });
1612     } else {
1613         auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
1614         curFrameInfoDetail.curFrameReverseChildren = false;
1615         std::for_each(
1616             (*children).begin(), (*children).end(), [this, &node](const std::shared_ptr<RSRenderNode>& child) {
1617             if (!child) {
1618                 return;
1619             }
1620             curDirty_ = child->IsDirty();
1621             child->SetFirstLevelCrossNode(node.IsFirstLevelCrossNode() || child->IsCrossNode());
1622             child->zOrderForCalcHwcNodeEnableByFilter_ = curZorderForCalcHwcNodeEnableByFilter_++;
1623             child->QuickPrepare(shared_from_this());
1624         });
1625     }
1626     ancestorNodeHasAnimation_ = animationBackup;
1627     node.ResetGeoUpdateDelay();
1628 }
1629 
InitDisplayInfo(RSDisplayRenderNode & node)1630 bool RSUniRenderVisitor::InitDisplayInfo(RSDisplayRenderNode& node)
1631 {
1632     // 1 init curDisplay and curDisplayDirtyManager
1633     currentVisitDisplay_ = node.GetScreenId();
1634     displaySpecailSurfaceChanged_.emplace(currentVisitDisplay_, false);
1635     hasCaptureWindow_.emplace(currentVisitDisplay_, false);
1636     hasFingerprint_.emplace(currentVisitDisplay_, false);
1637     curDisplayDirtyManager_ = node.GetDirtyManager();
1638     curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
1639     if (!curDisplayDirtyManager_ || !curDisplayNode_) {
1640         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo dirtyMgr or node ptr is nullptr");
1641         return false;
1642     }
1643     curDisplayDirtyManager_->SetAdvancedDirtyRegionType(advancedDirtyType_);
1644     curDisplayNode_->GetMultableSpecialLayerMgr().Set(HAS_GENERAL_SPECIAL, false);
1645     curDisplayDirtyManager_->Clear();
1646     transparentCleanFilter_.clear();
1647     transparentDirtyFilter_.clear();
1648     transparentHwcCleanFilter_.clear();
1649     transparentHwcDirtyFilter_.clear();
1650     occlusionSurfaceOrder_ = TOP_OCCLUSION_SURFACES_NUM;
1651     node.SetHasChildCrossNode(false);
1652     node.SetIsFirstVisitCrossNodeDisplay(false);
1653     node.SetHasUniRenderHdrSurface(false);
1654     node.SetIsLuminanceStatusChange(false);
1655     CheckLuminanceStatusChange(curDisplayNode_->GetScreenId());
1656     // 2 init screenManager info
1657     screenManager_ = CreateOrGetScreenManager();
1658     if (!screenManager_) {
1659         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo screenManager_ is nullptr");
1660         return false;
1661     }
1662     screenInfo_ = screenManager_->QueryScreenInfo(node.GetScreenId());
1663     screenRect_ = screenInfo_.activeRect.IsEmpty() ? RectI{0, 0, screenInfo_.width, screenInfo_.height} :
1664         screenInfo_.activeRect;
1665     curDisplayDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1666     curDisplayDirtyManager_->SetActiveSurfaceRect(screenInfo_.activeRect);
1667     screenManager_->SetScreenHasProtectedLayer(currentVisitDisplay_, false);
1668     allBlackList_ = screenManager_->GetAllBlackList();
1669     allWhiteList_ = screenManager_->GetAllWhiteList();
1670 
1671     // 3 init Occlusion info
1672     needRecalculateOcclusion_ = false;
1673     accumulatedOcclusionRegion_.Reset();
1674     occlusionRegionWithoutSkipLayer_.Reset();
1675     if (!curMainAndLeashWindowNodesIds_.empty()) {
1676         std::queue<NodeId>().swap(curMainAndLeashWindowNodesIds_);
1677     }
1678 
1679     // 4. check isHardwareForcedDisabled
1680     auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1681     if (geoPtr == nullptr) {
1682         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo geoPtr is nullptr");
1683         return false;
1684     }
1685     if (geoPtr->IsNeedClientCompose()) {
1686         isHardwareForcedDisabled_ = true;
1687         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: id:%" PRIu64 " disabled by displayNode rotation", node.GetId());
1688     }
1689 
1690     // 5. check compositeType
1691     auto mirrorNode = node.GetMirrorSource().lock();
1692     node.SetIsMirrorScreen(mirrorNode != nullptr);
1693     switch (screenInfo_.state) {
1694         case ScreenState::SOFTWARE_OUTPUT_ENABLE:
1695             node.SetCompositeType(mirrorNode ?
1696                 RSDisplayRenderNode::CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1697                 RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1698             break;
1699         case ScreenState::HDI_OUTPUT_ENABLE:
1700             node.SetCompositeType(node.IsForceSoftComposite() ?
1701                 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
1702                 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
1703             break;
1704         default:
1705             return false;
1706     }
1707 
1708     // init hdr and color gamut info
1709     node.ResetDisplayHdrStatus();
1710     node.SetPixelFormat(GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888);
1711     node.SetColorSpace(GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB);
1712 
1713     // [Attention] Only used in PC window resize scene now
1714     windowKeyFrameNodeInf_.ClearLinkedNodeInfo();
1715 
1716     return true;
1717 }
1718 
BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1719 bool RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1720 {
1721     // 1. init and record surface info
1722     if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1723         hasCaptureWindow_[currentVisitDisplay_] = true;
1724     }
1725     node.UpdateUIFirstFrameGravity();
1726     if (node.IsMainWindowType() || node.IsLeashWindow()) {
1727         node.SetStencilVal(Drawing::Canvas::INVALID_STENCIL_VAL);
1728         // UpdateCurCornerRadius must process before curSurfaceNode_ update
1729         node.UpdateCurCornerRadius(curCornerRadius_);
1730         curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1731         // dirty manager should not be overrode by cross node in expand screen
1732         curSurfaceDirtyManager_ = (!curDisplayNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) ?
1733             std::make_shared<RSDirtyRegionManager>() : node.GetDirtyManager();
1734         if (!curSurfaceDirtyManager_ || !curSurfaceNode_) {
1735             RS_LOGE("RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc %{public}s has invalid"
1736                 " SurfaceDirtyManager or node ptr", node.GetName().c_str());
1737             return false;
1738         }
1739         curSurfaceDirtyManager_->Clear();
1740         curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1741         curSurfaceDirtyManager_->SetActiveSurfaceRect(screenInfo_.activeRect);
1742         filterInGlobal_ = curSurfaceNode_->IsTransparent();
1743         // update surfaceNode contentDirty and subTreeDirty flag for UIFirst purging policy
1744         RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1745         curSurfaceNode_->UpdateSurfaceCacheContentStaticFlag(IsAccessibilityConfigChanged());
1746         curSurfaceNode_->UpdateSurfaceSubTreeDirtyFlag();
1747         curSurfaceNode_->SetLeashWindowVisibleRegionEmpty(false);
1748     } else if (node.IsAbilityComponent()) {
1749         if (auto nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>()) {
1750             RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(nodePtr);
1751             nodePtr->UpdateSurfaceCacheContentStaticFlag(IsAccessibilityConfigChanged());
1752         }
1753     }
1754     // 2. update surface info and CheckIfOcclusionReusable
1755     node.SetAncestorDisplayNode(curDisplayNode_); // set for boot animation
1756     node.UpdateAncestorDisplayNodeInRenderParams();
1757     node.CleanDstRectChanged();
1758     // [planning] check node isDirty can be optimized.
1759     needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.IsDirty() ||
1760         node.CheckIfOcclusionReusable(preMainAndLeashWindowNodesIds_);
1761     if (autoCacheEnable_ && node.IsAppWindow()) {
1762         node.OpincSetInAppStateStart(unchangeMarkInApp_);
1763     }
1764     // 3. check pixelFormat and update RelMatrix
1765     CheckPixelFormat(node);
1766     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
1767         node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
1768     }
1769 #ifdef RS_ENABLE_GPU
1770     // 4. collect cursors and check for null
1771     if (node.IsHardwareEnabledTopSurface() && (node.ShouldPaint() || node.GetHardCursorStatus())) {
1772         auto surfaceNodeDrawable =
1773             std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(node.GetRenderDrawable());
1774         if (surfaceNodeDrawable) {
1775             RSPointerWindowManager::Instance().CollectAllHardCursor(curDisplayNode_->GetId(), node.GetRenderDrawable());
1776         }
1777     }
1778 #endif
1779     node.setQosCal((RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) &&
1780         RSSystemParameters::GetVSyncControlEnabled());
1781     return true;
1782 }
1783 
AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1784 bool RSUniRenderVisitor::AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1785 {
1786     // 1. Update surfaceNode info and AppWindow gravity
1787     const auto& property = node.GetRenderProperties();
1788     if (node.IsAppWindow()) {
1789         boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
1790         frameGravity_ = property.GetFrameGravity();
1791     }
1792     auto& geoPtr = property.GetBoundsGeometry();
1793     if (geoPtr == nullptr) {
1794         return false;
1795     }
1796     UpdateDstRect(node, geoPtr->GetAbsRect(), prepareClipRect_);
1797     node.UpdatePositionZ();
1798     if (node.IsHardwareEnabledType() && node.GetZorderChanged() && curSurfaceNode_) {
1799         curSurfaceNode_->SetNeedCollectHwcNode(true);
1800     }
1801     UpdateSurfaceRenderNodeScale(node);
1802     UpdateSurfaceRenderNodeRotate(node);
1803     if (node.IsMainWindowType() || node.IsLeashWindow()) {
1804         curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
1805         curDisplayNode_->AddSurfaceNodePosByDescZOrder(node.GetId(), node.GetOldDirtyInSurface());
1806     }
1807     // 2. Update Occlusion info before children preparation
1808     if (node.IsMainWindowType()) {
1809         UpdateNodeVisibleRegion(node);
1810     }
1811     // 3. Update HwcNode Info for appNode
1812     UpdateHwcNodeInfoForAppNode(node);
1813     if (node.IsHardwareEnabledTopSurface()) {
1814         UpdateSrcRect(node, geoPtr->GetAbsMatrix(), geoPtr->GetAbsRect());
1815     }
1816     // 4. Update color gamut for appNode
1817     auto colorGamutFeature = GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[COLOR_GAMUT]);
1818     auto colorGamutParam = std::static_pointer_cast<ColorGamutParam>(colorGamutFeature);
1819     if ((colorGamutParam != nullptr && !colorGamutParam->IsCoveredSurfaceCloseP3()) ||
1820         !node.GetVisibleRegion().IsEmpty() || !GetIsOpDropped()) {
1821         CheckColorSpace(node);
1822     }
1823     return true;
1824 }
1825 
UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode & node)1826 void RSUniRenderVisitor::UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode& node)
1827 {
1828     if (!node.IsLeashWindow() || !RSSystemParameters::GetUIFirstOcclusionEnabled()) {
1829         return;
1830     }
1831 
1832     auto dirtyManager = node.GetDirtyManager();
1833     if (dirtyManager && dirtyManager->IsCurrentFrameDirty()) {
1834         RS_LOGD("RSUniRenderVisitor::UpdateLeashWindowVisibleRegionEmpty[false] : %{public}s is current frame dirty.",
1835             node.GetName().c_str());
1836         node.SetLeashWindowVisibleRegionEmpty(false);
1837         return;
1838     }
1839 
1840     auto sortedChildren = node.GetSortedChildren();
1841     if (sortedChildren == nullptr || sortedChildren->empty()) {
1842         RS_TRACE_NAME_FMT("%s don't have children", node.GetName().c_str());
1843         node.SetLeashWindowVisibleRegionEmpty(true);
1844         return;
1845     }
1846 
1847     // leash window's visible region is empty when all child are app windows with empty visible region
1848     for (const auto& child : *sortedChildren) {
1849         const auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1850         if (!childSurfaceNode || !childSurfaceNode->IsAppWindow() ||
1851             !childSurfaceNode->GetVisibleRegion().IsEmpty()) {
1852             node.SetLeashWindowVisibleRegionEmpty(false);
1853             return;
1854         }
1855     }
1856     RS_TRACE_NAME_FMT("visible region of %s's children is empty", node.GetName().c_str());
1857     node.SetLeashWindowVisibleRegionEmpty(true);
1858 }
1859 
UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode & node)1860 void RSUniRenderVisitor::UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode& node)
1861 {
1862     // app node
1863     if (node.GetNeedCollectHwcNode()) {
1864         node.ResetChildHardwareEnabledNodes();
1865         node.SetExistTransparentHardwareEnabledNode(false);
1866     }
1867     // hwc node
1868     if (node.IsHardwareEnabledType() && curSurfaceNode_) {
1869         if (curSurfaceNode_->GetNeedCollectHwcNode()) {
1870             curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
1871         }
1872         if (!node.GetHardWareDisabledByReverse()) {
1873             node.SetHardwareForcedDisabledState(node.GetIsHwcPendingDisabled());
1874             if (node.GetIsHwcPendingDisabled()) {
1875                 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by IsHwcPendingDisabled",
1876                     node.GetName().c_str(), node.GetId());
1877             }
1878             node.SetIsHwcPendingDisabled(false);
1879         }
1880         node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1881         if (!IsHardwareComposerEnabled() || !node.IsDynamicHardwareEnable() ||
1882             curSurfaceNode_->GetVisibleRegion().IsEmpty() ||
1883             !node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1884             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by param/invisible/no buffer, "
1885                 "IsHardwareComposerEnabled[%d], IsDynamicHardwareEnable[%d], IsVisibleRegionEmpty[%d], IsNoBuffer[%d]",
1886                 node.GetName().c_str(), node.GetId(), IsHardwareComposerEnabled(), node.IsDynamicHardwareEnable(),
1887                 curSurfaceNode_->GetVisibleRegion().IsEmpty(),
1888                 node.GetRSSurfaceHandler() || node.GetRSSurfaceHandler()->GetBuffer());
1889 #ifdef HIPERF_TRACE_ENABLE
1890             RS_LOGW("hiperf_surface: name:%s disabled by param/invisible/no buffer, "
1891                 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", node.GetName().c_str(),
1892                 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
1893                 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom(),
1894                 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
1895                 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom());
1896 #endif
1897             node.SetHardwareForcedDisabledState(true);
1898             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
1899                 HwcDisabledReasons::DISABLED_BY_INVALID_PARAM, node.GetName());
1900             if (!node.GetFixRotationByUser()) {
1901                 return;
1902             }
1903         }
1904         auto& geo = node.GetRenderProperties().GetBoundsGeometry();
1905         if (geo == nullptr) {
1906             return;
1907         }
1908         UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
1909         UpdateHwcNodeByTransform(node, geo->GetAbsMatrix());
1910         UpdateHwcNodeEnableByBackgroundAlpha(node);
1911         UpdateHwcNodeEnableByBufferSize(node);
1912         UpdateHwcNodeEnableBySrcRect(node);
1913     }
1914 }
1915 
UpdateSrcRect(RSSurfaceRenderNode & node,const Drawing::Matrix & absMatrix,const RectI & absRect)1916 void RSUniRenderVisitor::UpdateSrcRect(RSSurfaceRenderNode& node,
1917     const Drawing::Matrix& absMatrix, const RectI& absRect)
1918 {
1919     auto canvas = std::make_unique<Rosen::Drawing::Canvas>(screenInfo_.phyWidth, screenInfo_.phyHeight);
1920     canvas->ConcatMatrix(absMatrix);
1921 
1922     const auto& dstRect = node.GetDstRect();
1923     Drawing::RectI dst = { std::round(dstRect.GetLeft()), std::round(dstRect.GetTop()), std::round(dstRect.GetRight()),
1924                            std::round(dstRect.GetBottom()) };
1925     node.UpdateSrcRect(*canvas.get(), dst);
1926     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
1927         RSUniRenderUtil::UpdateRealSrcRect(node, absRect);
1928     }
1929 }
1930 
UpdateDstRect(RSSurfaceRenderNode & node,const RectI & absRect,const RectI & clipRect)1931 void RSUniRenderVisitor::UpdateDstRect(RSSurfaceRenderNode& node, const RectI& absRect, const RectI& clipRect)
1932 {
1933     auto dstRect = absRect;
1934     if (!node.IsHardwareEnabledTopSurface()) {
1935         // If the screen is expanded, intersect the destination rectangle with the screen rectangle
1936         dstRect = dstRect.IntersectRect(RectI(0, 0, screenInfo_.width, screenInfo_.height));
1937         // global positon has been transformd to screen position in absRect
1938     }
1939     // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
1940     if (node.IsHardwareEnabledType() || node.IsHardwareEnabledTopSurface()) {
1941         dstRect = dstRect.IntersectRect(clipRect);
1942         if (curSurfaceNode_ && (node.GetId() != curSurfaceNode_->GetId())) {
1943             dstRect = dstRect.IntersectRect(curSurfaceNode_->GetDstRect());
1944         }
1945     }
1946     dstRect.left_ = static_cast<int>(std::round(dstRect.left_ * screenInfo_.GetRogWidthRatio()));
1947     dstRect.top_ = static_cast<int>(std::round(dstRect.top_ * screenInfo_.GetRogHeightRatio()));
1948     dstRect.width_ = static_cast<int>(std::round(dstRect.width_ * screenInfo_.GetRogWidthRatio()));
1949     dstRect.height_ = static_cast<int>(std::round(dstRect.height_ * screenInfo_.GetRogHeightRatio()));
1950     // Set the destination rectangle of the node
1951     node.SetDstRect(dstRect);
1952     node.SetDstRectWithoutRenderFit(dstRect);
1953 }
1954 
UpdateHwcNodeByTransform(RSSurfaceRenderNode & node,const Drawing::Matrix & totalMatrix)1955 void RSUniRenderVisitor::UpdateHwcNodeByTransform(RSSurfaceRenderNode& node, const Drawing::Matrix& totalMatrix)
1956 {
1957     if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1958         return;
1959     }
1960     node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1961     const uint32_t apiCompatibleVersion = node.GetApiCompatibleVersion();
1962     (apiCompatibleVersion != INVALID_API_COMPATIBLE_VERSION && apiCompatibleVersion < API18) ?
1963         RSUniRenderUtil::DealWithNodeGravityOldVersion(node, screenInfo_) :
1964         RSUniRenderUtil::DealWithNodeGravity(node, totalMatrix);
1965     RSUniRenderUtil::DealWithScalingMode(node, totalMatrix);
1966     RSUniRenderUtil::LayerRotate(node, screenInfo_);
1967     RSUniRenderUtil::LayerCrop(node, screenInfo_);
1968     RSUniRenderUtil::CalcSrcRectByBufferFlip(node, screenInfo_);
1969     node.SetCalcRectInPrepare(true);
1970 }
1971 
UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode & node)1972 void RSUniRenderVisitor::UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode& node)
1973 {
1974     if (node.GetAncoForceDoDirect()) {
1975         return;
1976     }
1977     bool bgTransport =
1978         static_cast<uint8_t>(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX;
1979     auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
1980     bool isSolidColorEnbaled = stagingSurfaceParams->GetSelfDrawingNodeType() == SelfDrawingNodeType::XCOM &&
1981         node.GetRenderProperties().GetBackgroundColor() != RgbPalette::Black();
1982     if (bgTransport) {
1983         // use in skip updating hardware state for hwcnode with background alpha in specific situation
1984         if (!RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag() &&
1985             !node.IsHardwareEnableHint()) {
1986 #ifdef HIPERF_TRACE_ENABLE
1987             RS_LOGW("hiperf_surface: name:%s disabled by background color alpha < 1, "
1988                 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", node.GetName().c_str(),
1989                 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
1990                 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom(),
1991                 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
1992                 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom());
1993 #endif
1994             node.SetHardwareForcedDisabledState(true);
1995             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by background color alpha < 1",
1996                 node.GetName().c_str(), node.GetId());
1997         }
1998         curSurfaceNode_->SetExistTransparentHardwareEnabledNode(true);
1999         node.SetNodeHasBackgroundColorAlpha(true);
2000         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2001             HwcDisabledReasons::DISABLED_BY_BACKGROUND_ALPHA, node.GetName());
2002     } else if (RsCommonHook::Instance().GetIsWhiteListForSolidColorLayerFlag() && isSolidColorEnbaled) {
2003         if (!RSSystemParameters::GetSolidLayerHwcEnabled()) {
2004             node.SetHardwareForcedDisabledState(true);
2005             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by solidLayer switch",
2006                 node.GetName().c_str(), node.GetId());
2007             return;
2008         }
2009         stagingSurfaceParams->SetIsHwcEnabledBySolidLayer(true);
2010     } else if (!RsCommonHook::Instance().GetIsWhiteListForSolidColorLayerFlag() && isSolidColorEnbaled) {
2011         node.SetHardwareForcedDisabledState(true);
2012         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by solid background color",
2013             node.GetName().c_str(), node.GetId());
2014         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2015             HwcDisabledReasons::DISABLED_BY_SOLID_BACKGROUND_ALPHA, node.GetName());
2016     }
2017 }
2018 
UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode & node)2019 void RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode& node)
2020 {
2021     if (!node.IsRosenWeb() || node.IsHardwareForcedDisabled()) {
2022         return;
2023     }
2024     if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
2025         return;
2026     }
2027     const auto& property = node.GetRenderProperties();
2028     auto gravity = property.GetFrameGravity();
2029     if (gravity != Gravity::TOP_LEFT) {
2030         return;
2031     }
2032     auto surfaceHandler = node.GetRSSurfaceHandler();
2033     auto consumer = surfaceHandler->GetConsumer();
2034     if (consumer == nullptr) {
2035         return;
2036     }
2037 
2038     auto buffer = surfaceHandler->GetBuffer();
2039     const auto bufferWidth = buffer->GetSurfaceBufferWidth();
2040     const auto bufferHeight = buffer->GetSurfaceBufferHeight();
2041     auto boundsWidth = property.GetBoundsWidth();
2042     auto boundsHeight = property.GetBoundsHeight();
2043 
2044     auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
2045     if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
2046         RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize GetSurfaceBufferTransformType failed");
2047     }
2048     if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
2049         transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
2050         std::swap(boundsWidth, boundsHeight);
2051     }
2052     if ((bufferWidth < boundsWidth) || (bufferHeight < boundsHeight)) {
2053         RS_OPTIONAL_TRACE_NAME_FMT(
2054             "hwc debug: name:%s id:%" PRIu64 " buffer:[%d, %d] bounds:[%f, %f] disabled by buffer nonmatching",
2055             node.GetName().c_str(), node.GetId(), bufferWidth, bufferHeight, boundsWidth, boundsHeight);
2056 #ifdef HIPERF_TRACE_ENABLE
2057             RS_LOGW("hiperf_surface: name:%s buffer:[%d, %d] bounds:[%f, %f] disabled by buffer nonmatching, "
2058                 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
2059                 node.GetName().c_str(), bufferWidth, bufferHeight, boundsWidth, boundsHeight,
2060                 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
2061                 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom(),
2062                 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
2063                 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom());
2064 #endif
2065         node.SetHardwareForcedDisabledState(true);
2066         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(
2067             node.GetId(), HwcDisabledReasons::DISABLED_BY_BUFFER_NONMATCH, node.GetName());
2068     }
2069 }
2070 
UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode & node)2071 void RSUniRenderVisitor::UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode& node)
2072 {
2073     if (node.IsHardwareForcedDisabled()) {
2074         return;
2075     }
2076     bool hasRotation = false;
2077     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetConsumer()) {
2078         const auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
2079         auto rotation = RSBaseRenderUtil::GetRotateTransform(
2080             RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, node.GetRSSurfaceHandler()->GetBuffer()));
2081         hasRotation = rotation == GRAPHIC_ROTATE_90 || rotation == GRAPHIC_ROTATE_270;
2082     }
2083     node.UpdateHwcDisabledBySrcRect(hasRotation);
2084     if (node.IsHardwareDisabledBySrcRect()) {
2085 #ifdef HIPERF_TRACE_ENABLE
2086         RS_LOGW("hiperf_surface: name:%s disabled by src Rect, surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
2087             node.GetName().c_str(),
2088             node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
2089             node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom(),
2090             node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
2091             node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom());
2092 #endif
2093         node.SetHardwareForcedDisabledState(true);
2094         RS_OPTIONAL_TRACE_NAME_FMT(
2095             "hwc debug: name:%s id:%" PRIu64 " disabled by isYUVBufferFormat and localClip not match bounds",
2096             node.GetName().c_str(), node.GetId());
2097         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2098             HwcDisabledReasons::DISABLED_BY_SRC_PIXEL, node.GetName());
2099     }
2100 }
2101 
UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2102 void RSUniRenderVisitor::UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2103 {
2104     auto alpha = hwcNode->GetGlobalAlpha();
2105     auto totalMatrix = hwcNode->GetTotalMatrix();
2106     if (alpha < 1.0f) {
2107         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by accumulated alpha:%f",
2108             hwcNode->GetName().c_str(), hwcNode->GetId(), alpha);
2109 #ifdef HIPERF_TRACE_ENABLE
2110         RS_LOGW("hiperf_surface: name:%s disabled by accumulated alpha:%.2f, "
2111             "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", hwcNode->GetName().c_str(), alpha,
2112                 hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2113                 hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom(),
2114                 hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2115                 hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom());
2116 #endif
2117         hwcNode->SetHardwareForcedDisabledState(true);
2118         if (!ROSEN_EQ(alpha, 0.f)) {
2119             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2120                 HwcDisabledReasons::DISABLED_BY_ACCUMULATED_ALPHA, hwcNode->GetName());
2121         }
2122         return;
2123     }
2124     // [planning] degree only multiples of 90 now
2125     float degree = RSUniRenderUtil::GetFloatRotationDegreeFromMatrix(totalMatrix);
2126     bool hasRotate = !ROSEN_EQ(std::remainder(degree, 90.f), 0.f, EPSILON);
2127     hasRotate = hasRotate || RSUniRenderUtil::HasNonZRotationTransform(totalMatrix);
2128     if (hasRotate) {
2129         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by rotation:%f",
2130             hwcNode->GetName().c_str(), hwcNode->GetId(), degree);
2131 #ifdef HIPERF_TRACE_ENABLE
2132         RS_LOGW("hiperf_surface: name:%s disabled by rotation:%d, surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
2133             hwcNode->GetName().c_str(), degree,
2134             hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2135             hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom(),
2136             hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2137             hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom());
2138 #endif
2139         hwcNode->SetHardwareForcedDisabledState(true);
2140         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2141             HwcDisabledReasons::DISABLED_BY_ROTATION, hwcNode->GetName());
2142         return;
2143     }
2144 }
2145 
ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode> & hwcNodePtr,bool & ancoHasGpu)2146 void RSUniRenderVisitor::ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr, bool& ancoHasGpu)
2147 {
2148     if (hwcNodePtr == nullptr) {
2149         return;
2150     }
2151     auto alpha = hwcNodePtr->GetGlobalAlpha();
2152     RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 "src %{public}s dst %{public}s "
2153         "alpha:%{public}.2f", hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(),
2154         hwcNodePtr->GetSrcRect().ToString().c_str(), hwcNodePtr->GetDstRect().ToString().c_str(), alpha);
2155     if (ROSEN_EQ(alpha, 0.0f)) {
2156         return;
2157     }
2158 
2159     if (!hwcNodePtr->GetRSSurfaceHandler() || !hwcNodePtr->GetRSSurfaceHandler()->GetBuffer()) {
2160         RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 " handler or buffer is null, skip",
2161             hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2162         return;
2163     }
2164     if (hwcNodePtr->IsHardwareForcedDisabled()) {
2165         RS_OPTIONAL_TRACE_NAME_FMT("ProcessAncoNode: name:%s id:%" PRIu64 " hardware force disabled",
2166             hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2167     }
2168     ancoHasGpu = (ancoHasGpu || hwcNodePtr->IsHardwareForcedDisabled());
2169 }
2170 
UpdateHwcNodeEnable()2171 void RSUniRenderVisitor::UpdateHwcNodeEnable()
2172 {
2173     std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>> ancoNodes;
2174 #ifdef HIPERF_TRACE_ENABLE
2175     int inputHwclayers = 3;
2176 #endif
2177     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2178     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2179 #ifdef HIPERF_TRACE_ENABLE
2180         [this, &inputHwclayers, &ancoNodes](RSBaseRenderNode::SharedPtr& nodePtr) {
2181 #else
2182         [this, &ancoNodes](RSBaseRenderNode::SharedPtr& nodePtr) {
2183 #endif
2184         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2185         if (!surfaceNode) {
2186             return;
2187         }
2188 
2189         if (RSSystemProperties::GetHveFilterEnabled()) {
2190             const auto &preHwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2191             for (const auto& preHwcNode : preHwcNodes) {
2192                 auto hwcNodePtr = preHwcNode.lock();
2193                 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2194                     continue;
2195                 }
2196                 hwcNodePtr->ResetMakeImageState();
2197             }
2198         }
2199 
2200         UpdateHwcNodeEnableByGlobalFilter(surfaceNode);
2201         surfaceNode->ResetNeedCollectHwcNode();
2202         const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2203         if (hwcNodes.empty()) {
2204             return;
2205         }
2206 #ifdef HIPERF_TRACE_ENABLE
2207         inputHwclayers += hwcNodes.size();
2208 #endif
2209         std::vector<RectI> hwcRects;
2210         for (const auto& hwcNode : hwcNodes) {
2211             auto hwcNodePtr = hwcNode.lock();
2212             if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2213                 continue;
2214             }
2215             if (hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2216                 drmNodes_.emplace_back(hwcNode);
2217                 auto firstLevelNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
2218                     hwcNodePtr->GetFirstLevelNode());
2219                 hwcNodePtr->SetForceDisableClipHoleForDRM(firstLevelNode != nullptr &&
2220                     firstLevelNode->GetRenderProperties().IsAttractionValid());
2221             }
2222             RSUniRenderUtil::UpdateHwcNodeProperty(hwcNodePtr);
2223             UpdateHwcNodeEnableByRotateAndAlpha(hwcNodePtr);
2224             if ((hwcNodePtr->GetAncoFlags() & static_cast<uint32_t>(AncoFlags::IS_ANCO_NODE)) != 0) {
2225                 ancoNodes.insert(hwcNodePtr);
2226             }
2227         }
2228     });
2229 #ifdef HIPERF_TRACE_ENABLE
2230     RS_LOGW("hiperf_surface_counter1 %{public}" PRIu64 " ", static_cast<uint64_t>(inputHwclayers));
2231 #endif
2232     PrevalidateHwcNode();
2233     UpdateHwcNodeEnableByNodeBelow();
2234     UpdateAncoNodeHWCDisabledState(ancoNodes);
2235 }
2236 
2237 void RSUniRenderVisitor::UpdateAncoNodeHWCDisabledState(
2238     std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>>& ancoNodes)
2239 {
2240     bool ancoHasGpu = false;
2241     for (auto hwcNodePtr : ancoNodes) {
2242         ProcessAncoNode(hwcNodePtr, ancoHasGpu);
2243     }
2244     if (ancoHasGpu) {
2245         for (const auto& hwcNodePtr : ancoNodes) {
2246             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by anco has gpu",
2247                 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2248             hwcNodePtr->SetHardwareForcedDisabledState(true);
2249         }
2250     }
2251 }
2252 
2253 void RSUniRenderVisitor::PrevalidateHwcNode()
2254 {
2255     if (!RSUniHwcPrevalidateUtil::GetInstance().IsPrevalidateEnable()) {
2256         RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate close");
2257 #ifdef HIPERF_TRACE_ENABLE
2258         RS_LOGW("hiperf_surface_counter2 %{public}" PRIu64 " ", static_cast<uint64_t>(0));
2259 #endif
2260         return;
2261     }
2262 #ifdef HIPERF_TRACE_ENABLE
2263     int shouldPreValidateLayersNum = 3;
2264 #endif
2265     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2266     std::vector<RequestLayerInfo> prevalidLayers;
2267     uint32_t curFps = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(curDisplayNode_->GetScreenId());
2268     uint32_t zOrder = static_cast<uint32_t>(globalZOrder_);
2269     // add surfaceNode layer
2270     RSUniHwcPrevalidateUtil::GetInstance().CollectSurfaceNodeLayerInfo(
2271         prevalidLayers, curMainAndLeashSurfaces, curFps, zOrder, screenInfo_);
2272     RS_TRACE_NAME_FMT("PrevalidateHwcNode hwcLayer: %u", prevalidLayers.size());
2273     if (prevalidLayers.size() == 0) {
2274         RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode no hardware layer");
2275 #ifdef HIPERF_TRACE_ENABLE
2276         RS_LOGW("hiperf_surface_counter2 %{public}" PRIu64 " ", static_cast<uint64_t>(shouldPreValidateLayersNum));
2277 #endif
2278         return;
2279     }
2280     // add display layer
2281     RequestLayerInfo displayLayer;
2282     if (RSUniHwcPrevalidateUtil::GetInstance().CreateDisplayNodeLayerInfo(
2283         zOrder++, curDisplayNode_, screenInfo_, curFps, displayLayer)) {
2284         prevalidLayers.emplace_back(displayLayer);
2285     }
2286     // add rcd layer
2287     RequestLayerInfo rcdLayer;
2288     if (RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
2289         auto topNode = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curDisplayNode_->GetRcdSurfaceNodeTop());
2290         if (topNode &&
2291             RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(topNode, screenInfo_, curFps, rcdLayer)) {
2292             prevalidLayers.emplace_back(rcdLayer);
2293         }
2294         auto bottomNode = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curDisplayNode_->GetRcdSurfaceNodeBottom());
2295         if (bottomNode &&
2296             RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(bottomNode, screenInfo_, curFps, rcdLayer)) {
2297             prevalidLayers.emplace_back(rcdLayer);
2298         }
2299     }
2300 #ifdef HIPERF_TRACE_ENABLE
2301     shouldPreValidateLayersNum = prevalidLayers.size();
2302     RS_LOGW("hiperf_surface_counter2 %{public}" PRIu64 " ", static_cast<uint64_t>(shouldPreValidateLayersNum));
2303 #endif
2304     std::map<uint64_t, RequestCompositionType> strategy;
2305     if (!RSUniHwcPrevalidateUtil::GetInstance().PreValidate(screenInfo_.id, prevalidLayers, strategy)) {
2306         RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate failed");
2307         return;
2308     }
2309     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2310     for (auto it : strategy) {
2311         RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode id: %{public}" PRIu64 ","
2312             " result: %{public}d", it.first, it.second);
2313         if (it.second == RequestCompositionType::DEVICE) {
2314             continue;
2315         }
2316         auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(it.first);
2317         if (node == nullptr) {
2318             continue;
2319         }
2320         if (it.second == RequestCompositionType::DEVICE_VSCF) {
2321             node->SetArsrTag(false);
2322             continue;
2323         }
2324         if (node->IsInFixedRotation() || node->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2325             continue;
2326         }
2327         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by prevalidate",
2328             node->GetName().c_str(), node->GetId());
2329 #ifdef HIPERF_TRACE_ENABLE
2330         RS_LOGW("hiperf_surface: name:%s disabled by prevalidate, surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
2331             node->GetName().c_str(),
2332             node->GetSrcRect().GetLeft(), node->GetSrcRect().GetRight(),
2333             node->GetSrcRect().GetTop(), node->GetSrcRect().GetBottom(),
2334             node->GetSrcRect().GetLeft(), node->GetSrcRect().GetRight(),
2335             node->GetSrcRect().GetTop(), node->GetSrcRect().GetBottom());
2336 #endif
2337         node->SetHardwareForcedDisabledState(true);
2338         if (node->GetRSSurfaceHandler()) {
2339             node->GetRSSurfaceHandler()->SetGlobalZOrder(-1.f);
2340         }
2341         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
2342             HwcDisabledReasons::DISABLED_BY_PREVALIDATE, node->GetName());
2343     }
2344 }
2345 
2346 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode>& node)
2347 {
2348     const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
2349     if (hwcNodes.empty() || !curDisplayNode_) {
2350         return;
2351     }
2352     std::vector<std::shared_ptr<RSSurfaceRenderNode>> topLayers;
2353     for (auto hwcNode : hwcNodes) {
2354         auto hwcNodePtr = hwcNode.lock();
2355         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2356             continue;
2357         }
2358         auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
2359         if (hwcNodePtr->IsLayerTop()) {
2360             topLayers.emplace_back(hwcNodePtr);
2361             continue;
2362         }
2363         if (IsHdrUseUnirender(curDisplayNode_->GetHasUniRenderHdrSurface(), hwcNodePtr)) {
2364             hwcNodePtr->SetHardwareForcedDisabledState(true);
2365             // DRM will force HDR to use unirender
2366             curDisplayNode_->SetHasUniRenderHdrSurface(curDisplayNode_->GetHasUniRenderHdrSurface() ||
2367                 RSHdrUtil::CheckIsHdrSurface(*hwcNodePtr) != HdrStatus::NO_HDR);
2368             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
2369                 HwcDisabledReasons::DISABLED_BY_RENDER_HDR_SURFACE, hwcNodePtr->GetName());
2370         }
2371         UpdateHwcNodeDirtyRegionForApp(node, hwcNodePtr);
2372         hwcNodePtr->SetCalcRectInPrepare(false);
2373         hwcNodePtr->SetHardWareDisabledByReverse(false);
2374         surfaceHandler->SetGlobalZOrder(hwcNodePtr->IsHardwareForcedDisabled() &&
2375             !hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED) ? -1.f : globalZOrder_++);
2376         auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(hwcNodePtr->GetStagingRenderParams().get());
2377         if (stagingSurfaceParams->GetIsHwcEnabledBySolidLayer()) {
2378             surfaceHandler->SetGlobalZOrder(globalZOrder_++);
2379         }
2380         auto transform = RSUniRenderUtil::GetLayerTransform(*hwcNodePtr, screenInfo_);
2381         hwcNodePtr->UpdateHwcNodeLayerInfo(transform);
2382     }
2383     curDisplayNode_->SetDisplayGlobalZOrder(globalZOrder_);
2384     if (!topLayers.empty()) {
2385         UpdateTopLayersDirtyStatus(topLayers);
2386     }
2387 }
2388 
2389 bool RSUniRenderVisitor::IsHdrUseUnirender(bool hasUniRenderHdrSurface,
2390     std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr)
2391 {
2392     if (hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2393         return false;
2394     }
2395     bool isHdrHardwareDisabled = RSLuminanceControl::Get().IsCloseHardwareHdr() &&
2396         (RSHdrUtil::CheckIsHdrSurface(*hwcNodePtr) != HdrStatus::NO_HDR ||
2397         RSLuminanceControl::Get().IsHdrOn(curDisplayNode_->GetScreenId()));
2398     if (hasUniRenderHdrSurface || !drmNodes_.empty() || hasFingerprint_[currentVisitDisplay_] ||
2399         isHdrHardwareDisabled) {
2400         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64
2401             " disabled by having UniRenderHdrSurface/DRM nodes, isHdrHardwareDisabled:%d",
2402             hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(), isHdrHardwareDisabled);
2403         return true;
2404     }
2405     return false;
2406 }
2407 
2408 void RSUniRenderVisitor::UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode>& pointWindow)
2409 {
2410     if (!pointWindow->IsHardwareEnabledTopSurface() || !pointWindow->ShouldPaint()) {
2411         pointWindow->SetHardCursorStatus(false);
2412         RSPointerWindowManager::Instance().SetIsPointerEnableHwc(false);
2413         return;
2414     }
2415     std::shared_ptr<RSSurfaceHandler> pointSurfaceHandler = pointWindow->GetMutableRSSurfaceHandler();
2416     if (pointSurfaceHandler) {
2417         // globalZOrder_ + 2 is displayNode layer, point window must be at the top.
2418         pointSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 2);
2419         if (!curDisplayNode_) {
2420             return;
2421         }
2422         bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curDisplayNode_->GetScreenId());
2423         pointWindow->SetHardwareForcedDisabledState(true);
2424         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by pointWindow and pointSurfaceHandler",
2425             pointWindow->GetName().c_str(), pointWindow->GetId());
2426         bool isMirrorMode = RSPointerWindowManager::Instance().HasMirrorDisplay();
2427         RSPointerWindowManager::Instance().SetIsPointerEnableHwc(isHardCursor && !isMirrorMode);
2428         auto transform = RSUniRenderUtil::GetLayerTransform(*pointWindow, screenInfo_);
2429         pointWindow->SetHardCursorStatus(isHardCursor);
2430         pointWindow->UpdateHwcNodeLayerInfo(transform, isHardCursor);
2431         if (isHardCursor) {
2432             RSPointerWindowManager::Instance().UpdatePointerDirtyToGlobalDirty(pointWindow, curDisplayNode_);
2433         }
2434     }
2435 }
2436 
2437 void RSUniRenderVisitor::UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& topLayers)
2438 {
2439     for (const auto& topLayer : topLayers) {
2440         std::shared_ptr<RSSurfaceHandler> topLayerSurfaceHandler = topLayer->GetMutableRSSurfaceHandler();
2441         if (topLayerSurfaceHandler) {
2442             topLayerSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 1);
2443             topLayer->SetCalcRectInPrepare(false);
2444             bool hwcDisabled = !IsHardwareComposerEnabled() || !topLayer->ShouldPaint() ||
2445                 curDisplayNode_->GetHasUniRenderHdrSurface() || !drmNodes_.empty();
2446             topLayer->SetHardwareForcedDisabledState(hwcDisabled);
2447             if (hwcDisabled) {
2448                 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by toplayers dirty status, "
2449                     "IsHardwareComposerEnabled[%d],TopLayerShouldPaint[%d],HasUniRenderHdrSurface[%d],DrmNodeEmpty[%d]",
2450                     topLayer->GetName().c_str(), topLayer->GetId(), IsHardwareComposerEnabled(),
2451                     topLayer->ShouldPaint(), curDisplayNode_->GetHasUniRenderHdrSurface(), drmNodes_.empty());
2452             }
2453             auto transform = RSUniRenderUtil::GetLayerTransform(*topLayer, screenInfo_);
2454             topLayer->UpdateHwcNodeLayerInfo(transform);
2455         }
2456     }
2457 }
2458 
2459 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode>& appNode,
2460     std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2461 {
2462     // if current frame hwc enable status not equal with last frame
2463     // or current frame do gpu composition and has buffer consumed,
2464     // we need merge hwc node dst rect to dirty region.
2465     if (!hwcNode->IsHardwareForcedDisabled() != hwcNode->GetIsLastFrameHwcEnabled()) {
2466         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
2467         return;
2468     }
2469     if (!hwcNode->GetRSSurfaceHandler()) {
2470         return;
2471     }
2472     if (hwcNode->IsHardwareForcedDisabled() && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
2473         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetOldDirtyInSurface());
2474     }
2475     if (hasMirrorDisplay_ && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2476         !appNode->GetVisibleRegion().IsEmpty()) {
2477         // merge hwc node dst rect for virtual screen dirty, in case the main display node skip
2478         curDisplayDirtyManager_->MergeHwcDirtyRect(hwcNode->GetDstRect());
2479     }
2480 }
2481 
2482 void RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty()
2483 {
2484     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2485     // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
2486     Occlusion::Region accumulatedDirtyRegion;
2487     bool hasMainAndLeashSurfaceDirty = false;
2488     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2489         [this, &accumulatedDirtyRegion, &hasMainAndLeashSurfaceDirty](RSBaseRenderNode::SharedPtr& nodePtr) {
2490         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2491         if (!surfaceNode) {
2492             RS_LOGE("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surfaceNode is nullptr");
2493             return;
2494         }
2495         auto dirtyManager = surfaceNode->GetDirtyManager();
2496         RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
2497         // 0. update hwc node dirty region and create layer
2498         UpdateHwcNodeDirtyRegionAndCreateLayer(surfaceNode);
2499         // cal done node dirtyRegion for uifirst
2500         RSUifirstManager::Instance().MergeOldDirtyToDirtyManager(surfaceNode);
2501         UpdatePointWindowDirtyStatus(surfaceNode);
2502         // 1. calculate abs dirtyrect and update partialRenderParams
2503         // currently only sync visible region info
2504         surfaceNode->UpdatePartialRenderParams();
2505         if (dirtyManager && dirtyManager->IsCurrentFrameDirty() &&
2506             surfaceNode->GetVisibleRegion().IsIntersectWith(dirtyManager->GetCurrentFrameDirtyRegion())) {
2507             hasMainAndLeashSurfaceDirty = true;
2508         }
2509         // 2. check surface node dirtyrect need merge into displayDirtyManager
2510         CheckMergeSurfaceDirtysForDisplay(surfaceNode);
2511         // 3. check merge transparent filter when it intersects with pre-dirty.
2512         CheckMergeDisplayDirtyByTransparentFilter(surfaceNode, accumulatedDirtyRegion);
2513         // 4. for cross-display node, process its filter (which is not collected during prepare).
2514         CollectFilterInCrossDisplayWindow(surfaceNode, accumulatedDirtyRegion);
2515         // 5. accumulate dirty region of this surface.
2516         AccumulateSurfaceDirtyRegion(surfaceNode, accumulatedDirtyRegion);
2517     });
2518     curDisplayNode_->SetMainAndLeashSurfaceDirty(hasMainAndLeashSurfaceDirty);
2519     CheckMergeDebugRectforRefreshRate(curMainAndLeashSurfaces);
2520     CheckMergeDisplayDirtyByRoundCornerDisplay();
2521     CheckMergeGlobalFilterForDisplay(accumulatedDirtyRegion);
2522     ResetDisplayDirtyRegion();
2523     if (curDisplayDirtyManager_) {
2524         curDisplayDirtyManager_->ClipDirtyRectWithinSurface();
2525         if (curDisplayDirtyManager_->IsActiveSurfaceRectChanged()) {
2526             RS_TRACE_NAME_FMT("ActiveSurfaceRectChanged, form %s to %s",
2527                 curDisplayDirtyManager_->GetLastActiveSurfaceRect().ToString().c_str(),
2528                 curDisplayDirtyManager_->GetActiveSurfaceRect().ToString().c_str());
2529             curDisplayDirtyManager_->MergeDirtyRect(curDisplayDirtyManager_->GetSurfaceRect());
2530         }
2531     }
2532     curDisplayNode_->ClearCurrentSurfacePos();
2533     std::swap(preMainAndLeashWindowNodesIds_, curMainAndLeashWindowNodesIds_);
2534 
2535 #ifdef RS_PROFILER_ENABLED
2536     RS_PROFILER_SET_DIRTY_REGION(accumulatedDirtyRegion);
2537 #endif
2538 }
2539 
2540 void RSUniRenderVisitor::UpdateDisplayRcdRenderNode()
2541 {
2542     RSSingleton<RoundCornerDisplayManager>::GetInstance().RefreshFlagAndUpdateResource(curDisplayNode_->GetId());
2543     bool isRcdEnabled = RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable();
2544 
2545     if (isRcdEnabled) {
2546         if (!curDisplayNode_->GetRcdSurfaceNodeTop()) {
2547             auto node = RSRcdSurfaceRenderNode::Create(
2548                 curDisplayNode_->GetId(), RCDSurfaceType::TOP, curDisplayNode_->GetContext());
2549             curDisplayNode_->SetRcdSurfaceNodeTop(node);
2550         }
2551         if (!curDisplayNode_->GetRcdSurfaceNodeBottom()) {
2552             auto node = RSRcdSurfaceRenderNode::Create(
2553                 curDisplayNode_->GetId(), RCDSurfaceType::BOTTOM, curDisplayNode_->GetContext());
2554             curDisplayNode_->SetRcdSurfaceNodeBottom(node);
2555         }
2556 
2557         auto hardInfo =
2558             RSSingleton<RoundCornerDisplayManager>::GetInstance().PrepareHardwareInfo(curDisplayNode_->GetId());
2559         if (hardInfo.topLayer && hardInfo.bottomLayer) {
2560             auto topNode = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curDisplayNode_->GetRcdSurfaceNodeTop());
2561             auto bottomNode =
2562                 std::static_pointer_cast<RSRcdSurfaceRenderNode>(curDisplayNode_->GetRcdSurfaceNodeBottom());
2563 
2564             if (hardInfo.resourceChanged) {
2565                 topNode->SetRenderDisplayRect(hardInfo.displayRect);
2566                 topNode->PrepareHardwareResource(hardInfo.topLayer);
2567                 bottomNode->SetRenderDisplayRect(hardInfo.displayRect);
2568                 bottomNode->PrepareHardwareResource(hardInfo.bottomLayer);
2569             }
2570 
2571             topNode->UpdateRcdRenderParams(hardInfo.resourceChanged, hardInfo.topLayer->curBitmap);
2572             bottomNode->UpdateRcdRenderParams(hardInfo.resourceChanged, hardInfo.bottomLayer->curBitmap);
2573         }
2574     }
2575 }
2576 
2577 void RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow()
2578 {
2579     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2580     // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
2581     std::vector<RectI> hwcRects;
2582     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2583         [this, &hwcRects](RSBaseRenderNode::SharedPtr& nodePtr) {
2584         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2585         if (!surfaceNode) {
2586             RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow surfaceNode is nullptr");
2587             return;
2588         }
2589         // use in temporary scheme to realize DSS
2590         auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2591         if (!hwcNodes.empty() && RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag() &&
2592             RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
2593             UpdateHardwareStateByHwcNodeBackgroundAlpha(hwcNodes);
2594         } else if (surfaceNode->ExistTransparentHardwareEnabledNode()) {
2595             UpdateTransparentHwcNodeEnable(hwcNodes);
2596         }
2597         // use end
2598         UpdateChildHwcNodeEnableByHwcNodeBelow(hwcRects, surfaceNode);
2599     });
2600 }
2601 
2602 void RSUniRenderVisitor::UpdateTransparentHwcNodeEnable(
2603     const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes)
2604 {
2605     for (size_t index = 1; index < hwcNodes.size(); ++index) {
2606         auto transparentHwcNodeSPtr = hwcNodes[index].lock();
2607         if (!transparentHwcNodeSPtr) {
2608             continue;
2609         }
2610         const bool isTransparentEnableHwcNode = transparentHwcNodeSPtr->IsNodeHasBackgroundColorAlpha() &&
2611             !transparentHwcNodeSPtr->IsHardwareForcedDisabled() && transparentHwcNodeSPtr->IsHardwareEnableHint();
2612         if (!isTransparentEnableHwcNode) {
2613             continue;
2614         }
2615         auto transparentDstRect = transparentHwcNodeSPtr->GetDstRect();
2616         for (size_t lowerIndex = 0; lowerIndex < index; ++lowerIndex) {
2617             // 'lowerHwcNode' means lower device composition layer.
2618             auto lowerHwcNodeSPtr = hwcNodes[lowerIndex].lock();
2619             if (!lowerHwcNodeSPtr || !lowerHwcNodeSPtr->IsHardwareForcedDisabled()) {
2620                 continue;
2621             }
2622             auto lowerHwcNodeRect = lowerHwcNodeSPtr->GetDstRect();
2623             bool isIntersect = !transparentDstRect.IntersectRect(lowerHwcNodeRect).IsEmpty();
2624             if (isIntersect) {
2625                 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparent hwc node"
2626                     " cover other disabled hwc node name:%s id:%" PRIu64,
2627                     transparentHwcNodeSPtr->GetName().c_str(), transparentHwcNodeSPtr->GetId(),
2628                     lowerHwcNodeSPtr->GetName().c_str(), lowerHwcNodeSPtr->GetId());
2629                 transparentHwcNodeSPtr->SetHardwareForcedDisabledState(true);
2630                 break;
2631             }
2632         }
2633     }
2634 }
2635 
2636 void RSUniRenderVisitor::UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI>& hwcRects,
2637     std::shared_ptr<RSSurfaceRenderNode>& appNode)
2638 {
2639     const auto& hwcNodes = appNode->GetChildHardwareEnabledNodes();
2640     for (auto hwcNode : hwcNodes) {
2641         auto hwcNodePtr = hwcNode.lock();
2642         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2643             continue;
2644         }
2645         UpdateHwcNodeEnableByHwcNodeBelowSelf(hwcRects, hwcNodePtr,
2646             hwcNodePtr->GetIntersectedRoundCornerAABBsSize() != 0);
2647     }
2648 }
2649 
2650 void RSUniRenderVisitor::UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,
2651     std::vector<RectI>& hwcRects)
2652 {
2653     if (!hwcNode || !hwcNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2654         return;
2655     }
2656     auto instanceNode = hwcNode->GetInstanceRootNode() ?
2657         hwcNode->GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
2658     if (!instanceNode) {
2659         hwcNode->SetCornerRadiusInfoForDRM({});
2660         return;
2661     }
2662     auto instanceAbsRect = instanceNode->GetAbsDrawRect();
2663     auto instanceCornerRadius = instanceNode->GetGlobalCornerRadius();
2664     if (instanceAbsRect.IsEmpty() || instanceCornerRadius.IsZero() ||
2665         ROSEN_EQ(instanceNode->GetRenderProperties().GetBoundsWidth(), 0.0f)) {
2666         hwcNode->SetCornerRadiusInfoForDRM({});
2667         return;
2668     }
2669     auto hwcGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2670     if (!hwcGeo) {
2671         hwcNode->SetCornerRadiusInfoForDRM({});
2672         return;
2673     }
2674     auto hwcAbsRect = hwcGeo->MapRect(hwcNode->GetSelfDrawRect(), hwcNode->GetTotalMatrix());
2675     hwcAbsRect = hwcAbsRect.IntersectRect(instanceAbsRect);
2676     if (hwcAbsRect.IsEmpty()) {
2677         hwcNode->SetCornerRadiusInfoForDRM({});
2678         return;
2679     }
2680     auto ratio = static_cast<float>(instanceAbsRect.GetWidth()) /
2681         instanceNode->GetRenderProperties().GetBoundsWidth();
2682     std::vector<float> ratioVector = { 0.0f, 0.0f, 0.0f, 0.0f };
2683     bool isIntersectWithRoundCorner =
2684         CheckIfRoundCornerIntersectDRM(ratio, ratioVector, instanceCornerRadius, instanceAbsRect, hwcAbsRect);
2685     // store radius information when drm overlaps with other hwc nodes
2686     if (isIntersectWithRoundCorner) {
2687         for (const auto& rect : hwcRects) {
2688             if (hwcAbsRect.Intersect(rect)) {
2689                 std::vector<float> drmCornerRadiusInfo = {
2690                     static_cast<float>(hwcAbsRect.GetLeft()), static_cast<float>(hwcAbsRect.GetTop()),
2691                     static_cast<float>(hwcAbsRect.GetWidth()), static_cast<float>(hwcAbsRect.GetHeight()),
2692                     // get corner radius num by index 0, 1, 2, 3
2693                     instanceCornerRadius[0] * ratioVector[0], instanceCornerRadius[1] * ratioVector[1],
2694                     instanceCornerRadius[2] * ratioVector[2], instanceCornerRadius[3] * ratioVector[3]};
2695                 hwcNode->SetCornerRadiusInfoForDRM(drmCornerRadiusInfo);
2696                 return;
2697             }
2698         }
2699     }
2700     hwcNode->SetCornerRadiusInfoForDRM({});
2701 }
2702 
2703 bool RSUniRenderVisitor::CheckIfRoundCornerIntersectDRM(const float& ratio, std::vector<float>& ratioVector,
2704     const Vector4f& instanceCornerRadius, const RectI& instanceAbsRect, const RectI& hwcAbsRect)
2705 {
2706     auto maxRadius = *std::max_element(std::begin(instanceCornerRadius.data_),
2707         std::end(instanceCornerRadius.data_)) * ratio;
2708     bool isIntersectWithRoundCorner = false;
2709     static const std::vector<UIPoint> offsetVecs = { UIPoint { 0, 0 }, UIPoint { 1, 0 },
2710         UIPoint { 0, 1 }, UIPoint { 1, 1 } };
2711     UIPoint offset { instanceAbsRect.GetWidth() - maxRadius, instanceAbsRect.GetHeight() - maxRadius };
2712     UIPoint anchorPoint { instanceAbsRect.GetLeft(), instanceAbsRect.GetTop() };
2713     // if round corners intersect drm, update ratioVectors
2714     for (size_t i = 0; i < offsetVecs.size(); i++) {
2715         auto res = anchorPoint + offset * offsetVecs[i];
2716         if (RectI(res.x_, res.y_, maxRadius, maxRadius).Intersect(hwcAbsRect)) {
2717             isIntersectWithRoundCorner = true;
2718             ratioVector[i] = ratio;
2719         }
2720     }
2721     return isIntersectWithRoundCorner;
2722 }
2723 
2724 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI>& hwcRects,
2725     std::shared_ptr<RSSurfaceRenderNode>& hwcNode, bool isIntersectWithRoundCorner)
2726 {
2727     if (!curDisplayNode_) {
2728         RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelf curDisplayNode is null");
2729         return;
2730     }
2731     if (hwcNode->IsHardwareForcedDisabled()) {
2732         if (RSHdrUtil::CheckIsHdrSurface(*hwcNode) != HdrStatus::NO_HDR) {
2733             curDisplayNode_->SetHasUniRenderHdrSurface(true);
2734         }
2735         return;
2736     }
2737     auto absBound = RectI();
2738     if (auto geo = hwcNode->GetRenderProperties().GetBoundsGeometry()) {
2739         absBound = geo->GetAbsRect();
2740     } else {
2741         return;
2742     }
2743     if (hwcNode->GetAncoForceDoDirect() || !isIntersectWithRoundCorner) {
2744         hwcRects.emplace_back(absBound);
2745         return;
2746     }
2747     for (const auto& rect : hwcRects) {
2748         for (auto& roundCornerAABB : hwcNode->GetIntersectedRoundCornerAABBs()) {
2749             if (!roundCornerAABB.IntersectRect(rect).IsEmpty()) {
2750 #ifdef HIPERF_TRACE_ENABLE
2751                 RS_LOGW("hiperf_surface: name:%s disabled by corner radius + hwc node below, "
2752                     "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", hwcNode->GetName().c_str(),
2753                     hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2754                     hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom(),
2755                     hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2756                     hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom());
2757 #endif
2758                 if (hwcNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2759                     continue;
2760                 }
2761                 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by corner radius + "
2762                     "hwc node below, rect:%s", hwcNode->GetName().c_str(), hwcNode->GetId(), rect.ToString().c_str());
2763                 hwcNode->SetHardwareForcedDisabledState(true);
2764                 if (RSHdrUtil::CheckIsHdrSurface(*hwcNode) != HdrStatus::NO_HDR) {
2765                     curDisplayNode_->SetHasUniRenderHdrSurface(true);
2766                 }
2767                 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2768                     HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
2769                 return;
2770             }
2771         }
2772     }
2773     hwcRects.emplace_back(absBound);
2774 }
2775 
2776 void RSUniRenderVisitor::UpdateSurfaceOcclusionInfo()
2777 {
2778     allDstCurVisVec_.insert(allDstCurVisVec_.end(), dstCurVisVec_.begin(), dstCurVisVec_.end());
2779     dstCurVisVec_.clear();
2780 }
2781 
2782 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode& surfaceNode) const
2783 {
2784     // surfaceNode is transparent
2785     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2786     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2787     Occlusion::Region visibleRegion = hasMirrorDisplay_ ?
2788         surfaceNode.GetVisibleRegionInVirtual() : surfaceNode.GetVisibleRegion();
2789     if (surfaceNode.IsMainWindowType() && !visibleRegion.IsIntersectWith(dirtyRect)) {
2790         return;
2791     }
2792     if (surfaceNode.IsTransparent()) {
2793         RectI transparentDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2794         if (!transparentDirtyRect.IsEmpty()) {
2795             RS_LOGD("CheckMergeDisplayDirtyByTransparent global merge transparent dirty "
2796                 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2797                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2798                 transparentDirtyRect.ToString().c_str());
2799             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(transparentDirtyRect);
2800         }
2801     }
2802     // surfaceNode has transparent regions
2803     CheckMergeDisplayDirtyByTransparentRegions(surfaceNode);
2804 }
2805 
2806 void RSUniRenderVisitor::CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode& surfaceNode) const
2807 {
2808     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2809     if (surfaceNode.GetZorderChanged()) {
2810         RS_LOGD("CheckMergeDisplayDirtyByZorderChanged global merge GetZorderChanged "
2811             "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2812             curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2813             oldDirtyInSurface.ToString().c_str());
2814         curDisplayNode_->GetDirtyManager()->MergeDirtyRect(oldDirtyInSurface);
2815     }
2816 }
2817 
2818 void RSUniRenderVisitor::CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode& surfaceNode) const
2819 {
2820     bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curDisplayNode_->GetScreenId());
2821     if (isHardCursor && surfaceNode.IsHardwareEnabledTopSurface() && surfaceNode.GetHardCursorStatus()) {
2822         return;
2823     }
2824     RectI lastFrameSurfacePos = curDisplayNode_->GetLastFrameSurfacePos(surfaceNode.GetId());
2825     RectI currentFrameSurfacePos = curDisplayNode_->GetCurrentFrameSurfacePos(surfaceNode.GetId());
2826     if (surfaceNode.GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
2827         RS_LOGD("CheckMergeDisplayDirtyByPosChanged global merge surface pos changed "
2828             "%{public}s: global dirty %{public}s, lastFrameRect %{public}s currentFrameRect %{public}s",
2829             surfaceNode.GetName().c_str(),
2830             curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2831             lastFrameSurfacePos.ToString().c_str(), currentFrameSurfacePos.ToString().c_str());
2832         if (!lastFrameSurfacePos.IsEmpty()) {
2833             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
2834         }
2835         if (!currentFrameSurfacePos.IsEmpty()) {
2836             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(currentFrameSurfacePos);
2837         }
2838     }
2839 }
2840 
2841 void RSUniRenderVisitor::CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode& surfaceNode) const
2842 {
2843     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2844     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2845     bool isShadowDisappear = !surfaceNode.GetRenderProperties().IsShadowValid() &&
2846         surfaceNode.IsShadowValidLastFrame();
2847     if (surfaceNode.GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2848         RectI shadowDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2849         // There are two situation here:
2850         // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2851         // dirtyRect == surfaceNode.GetOldDirtyInSurface()
2852         // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2853         // dirtyRect > surfaceNode.GetOldDirtyInSurface()
2854         // So we should always merge dirtyRect here.
2855         if (!shadowDirtyRect.IsEmpty()) {
2856             RS_LOGD("CheckMergeDisplayDirtyByShadowChanged global merge ShadowValid %{public}s: "
2857                 "global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2858                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2859                 dirtyRect.ToString().c_str());
2860             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRect);
2861         }
2862         if (isShadowDisappear) {
2863             surfaceNode.SetShadowValidLastFrame(false);
2864         }
2865     }
2866 }
2867 
2868 void RSUniRenderVisitor::CheckMergeDisplayDirtyBySurfaceChanged() const
2869 {
2870     std::vector<RectI> surfaceChangedRects = curDisplayNode_->GetSurfaceChangedRects();
2871     for (auto& surfaceChangedRect : surfaceChangedRects) {
2872         if (!surfaceChangedRect.IsEmpty()) {
2873             RS_LOGD("CheckMergeDisplayDirtyBySurfaceChanged global merge Surface closed, global dirty %{public}s,"
2874                 "add rect %{public}s",
2875                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2876                 surfaceChangedRect.ToString().c_str());
2877             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(surfaceChangedRect);
2878         }
2879     }
2880 }
2881 
2882 void RSUniRenderVisitor::CheckMergeDisplayDirtyByAttraction(RSSurfaceRenderNode& surfaceNode) const
2883 {
2884     if (surfaceNode.GetRenderProperties().IsAttractionValid()) {
2885         auto attractionDirtyRect = surfaceNode.GetRenderProperties().GetAttractionEffectCurrentDirtyRegion();
2886         RS_LOGD("CheckMergeDisplayDirtyByAttraction global merge attraction %{public}s: global dirty %{public}s,"
2887             "add rect %{public}s", surfaceNode.GetName().c_str(),
2888             curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2889             attractionDirtyRect.ToString().c_str());
2890         auto boundsGeometry = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
2891         if (boundsGeometry) {
2892             Drawing::Rect rect(attractionDirtyRect.GetLeft(), attractionDirtyRect.GetTop(),
2893                 attractionDirtyRect.GetRight(), attractionDirtyRect.GetBottom());
2894             Drawing::Rect tempRect;
2895             boundsGeometry->GetMatrix().MapRect(tempRect, rect);
2896             attractionDirtyRect =
2897                 RectI(tempRect.GetLeft(), tempRect.GetTop(), tempRect.GetWidth(), tempRect.GetHeight());
2898         }
2899         curDisplayNode_->GetDirtyManager()->MergeDirtyRect(attractionDirtyRect);
2900     }
2901 }
2902 
2903 void RSUniRenderVisitor::CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2904 {
2905     if (surfaceNode->GetDirtyManager() == nullptr || curDisplayNode_->GetDirtyManager() == nullptr) {
2906         return;
2907     }
2908     // 1 handle last and curframe surfaces which appear or disappear case
2909     CheckMergeDisplayDirtyBySurfaceChanged();
2910     // 2 if the surface node is cross-display and prepared again, convert its dirty region into global.
2911     if (surfaceNode->IsFirstLevelCrossNode() && !curDisplayNode_->IsFirstVisitCrossNodeDisplay()) {
2912         CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2913         CheckMergeDisplayDirtyByCrossDisplayWindow(*surfaceNode);
2914         return;
2915     }
2916     // 3 Handles the case of transparent surface, merge transparent dirty rect
2917     CheckMergeDisplayDirtyByTransparent(*surfaceNode);
2918     // 4 Zorder changed case, merge surface dest Rect
2919     CheckMergeDisplayDirtyByZorderChanged(*surfaceNode);
2920     // 5 surfacePos chanded case, merge surface lastframe pos or curframe pos
2921     CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2922     // 6 shadow disappear and appear case.
2923     CheckMergeDisplayDirtyByShadowChanged(*surfaceNode);
2924     // 7 handle surface has attraction effect
2925     CheckMergeDisplayDirtyByAttraction(*surfaceNode);
2926     // More: any other display dirty caused by surfaceNode should be added here like CheckMergeDisplayDirtByXXX
2927 }
2928 
2929 void RSUniRenderVisitor::CheckMergeDisplayDirtyByCrossDisplayWindow(RSSurfaceRenderNode& surfaceNode) const
2930 {
2931     auto geoPtr = surfaceNode.GetRenderProperties().GetBoundsGeometry();
2932     if (!geoPtr) {
2933         return;
2934     }
2935     // transfer from the display coordinate system during quickprepare into current display coordinate system.
2936     auto dirtyRect = geoPtr->MapRect(surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion().ConvertTo<float>(),
2937         surfaceNode.GetCrossNodeSkipDisplayConversionMatrix(curDisplayNode_->GetId()));
2938     RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeDisplayDirtyByCrossDisplayWindow %s, global dirty %s, add rect %s",
2939         surfaceNode.GetName().c_str(), curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
2940         dirtyRect.ToString().c_str());
2941     curDisplayDirtyManager_->MergeDirtyRect(dirtyRect);
2942 }
2943 
2944 void RSUniRenderVisitor::CollectFilterInCrossDisplayWindow(
2945     std::shared_ptr<RSSurfaceRenderNode>& surfaceNode, Occlusion::Region& accumulatedDirtyRegion)
2946 {
2947     auto geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
2948     if (!surfaceNode->IsFirstLevelCrossNode() || curDisplayNode_->IsFirstVisitCrossNodeDisplay() || !geoPtr) {
2949         return;
2950     }
2951     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2952     for (auto& child : surfaceNode->GetVisibleFilterChild()) {
2953         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2954         if (!filterNode) {
2955             continue;
2956         }
2957         auto filterRect = geoPtr->MapRect(filterNode->GetAbsDrawRect().ConvertTo<float>(),
2958             surfaceNode->GetCrossNodeSkipDisplayConversionMatrix(curDisplayNode_->GetId())).IntersectRect(screenRect_);
2959         if (surfaceNode->IsTransparent() && accumulatedDirtyRegion.IsIntersectWith(Occlusion::Rect(filterRect))) {
2960             RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInCrossDisplayWindow [%s] has filter, add [%s] to global dirty",
2961                 surfaceNode->GetName().c_str(), filterRect.ToString().c_str());
2962             curDisplayDirtyManager_->MergeDirtyRect(filterRect);
2963         } else {
2964             RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInCrossDisplayWindow [%s] has filter, add [%s] to global filter",
2965                 surfaceNode->GetName().c_str(), filterRect.ToString().c_str());
2966             globalFilter_.insert({ filterNode->GetId(), filterRect });
2967         }
2968     }
2969 }
2970 
2971 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode& surfaceNode) const
2972 {
2973     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2974     if (surfaceNode.HasContainerWindow()) {
2975         // If a surface's dirty is intersect with container region (which can be considered transparent)
2976         // should be added to display dirty region.
2977         // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2978         auto containerRegion = surfaceNode.GetContainerRegion();
2979         auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2980         auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2981         if (!containerDirtyRegion.IsEmpty()) {
2982             RS_LOGD("CheckMergeDisplayDirtyByContainer global merge containerDirtyRegion "
2983                 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2984                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2985                 containerDirtyRegion.GetRegionInfo().c_str());
2986             // plan: we can use surfacenode's absrect as containerRegion's bound
2987             const auto& rect = containerRegion.GetBoundRef();
2988             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(
2989                 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2990         }
2991     } else {
2992         // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2993         // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
2994         // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2995         // which include transparent region but not counted in display dirtyregion)
2996         if (!surfaceNode.IsNodeDirty()) {
2997             return;
2998         }
2999         auto transparentRegion = surfaceNode.GetTransparentRegion();
3000         auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
3001         Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
3002         if (!transparentDirtyRegion.IsEmpty()) {
3003             RS_LOGD("CheckMergeDisplayDirtyByTransparentRegions global merge TransparentDirtyRegion "
3004                 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
3005                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3006                 transparentDirtyRegion.GetRegionInfo().c_str());
3007             const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
3008             for (const auto& rect : rects) {
3009                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(RectI{ rect.left_, rect.top_,
3010                     rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
3011             }
3012         }
3013     }
3014 }
3015 
3016 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter(
3017     std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
3018     Occlusion::Region& accumulatedDirtyRegion)
3019 {
3020     auto disappearedSurfaceRegionBelowCurrent =
3021         curDisplayNode_->GetDisappearedSurfaceRegionBelowCurrent(surfaceNode->GetId());
3022     accumulatedDirtyRegion.OrSelf(disappearedSurfaceRegionBelowCurrent);
3023     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3024     auto filterVecIter = transparentCleanFilter_.find(surfaceNode->GetId());
3025     if (filterVecIter != transparentCleanFilter_.end()) {
3026         RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter surface:%{public}s "
3027             "has transparentCleanFilter", surfaceNode->GetName().c_str());
3028         // check accumulatedDirtyRegion influence filter nodes which in the current surface
3029         for (auto it = filterVecIter->second.begin(); it != filterVecIter->second.end(); ++it) {
3030             auto filterNode = nodeMap.GetRenderNode(it->first);
3031             if (filterNode == nullptr) {
3032                 continue;
3033             }
3034             auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
3035             auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
3036             if (!filterDirtyRegion.IsEmpty()) {
3037                 if (filterNode->GetRenderProperties().GetBackgroundFilter() ||
3038                     filterNode->GetRenderProperties().GetNeedDrawBehindWindow()) {
3039                     // backgroundfilter affected by below dirty
3040                     filterNode->MarkFilterStatusChanged(false, false);
3041                 }
3042                 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter global merge filterRegion "
3043                     "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode->GetName().c_str(),
3044                     curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3045                     it->second.ToString().c_str());
3046                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
3047                 if (filterNode->GetRenderProperties().GetFilter()) {
3048                     // foregroundfilter affected by below dirty
3049                     filterNode->MarkFilterStatusChanged(true, false);
3050                 }
3051             } else {
3052                 globalFilter_.insert(*it);
3053             }
3054             filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
3055             RsFrameBlurPredict::GetInstance().PredictDrawLargeAreaBlur(*filterNode);
3056         }
3057     }
3058 }
3059 
3060 void RSUniRenderVisitor::AccumulateSurfaceDirtyRegion(
3061     std::shared_ptr<RSSurfaceRenderNode>& surfaceNode, Occlusion::Region& accumulatedDirtyRegion) const
3062 {
3063     auto geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
3064     if (!surfaceNode->GetDirtyManager() || !geoPtr) {
3065         return;
3066     }
3067     auto surfaceDirtyRect = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
3068     if (surfaceNode->IsFirstLevelCrossNode() && !curDisplayNode_->IsFirstVisitCrossNodeDisplay()) {
3069         surfaceDirtyRect = geoPtr->MapRect(surfaceDirtyRect.ConvertTo<float>(),
3070             surfaceNode->GetCrossNodeSkipDisplayConversionMatrix(curDisplayNode_->GetId()));
3071     }
3072     auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ surfaceDirtyRect } };
3073     accumulatedDirtyRegion.OrSelf(surfaceDirtyRegion);
3074 }
3075 
3076 void RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion()
3077 {
3078     if (curDisplayNode_ == nullptr) {
3079         RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion curDisplayNode_ is nullptr");
3080         return;
3081     }
3082     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
3083     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3084     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
3085         [this, &nodeMap](RSBaseRenderNode::SharedPtr& nodePtr) {
3086         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
3087         if (surfaceNode == nullptr) {
3088             RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion surfaceNode is nullptr");
3089             return;
3090         }
3091         if (!surfaceNode->IsMainWindowType()) {
3092             return;
3093         }
3094         Occlusion::Region extendRegion;
3095         if (!surfaceNode->GetVisibleRegion().IsEmpty()) {
3096             ProcessFilterNodeObscured(surfaceNode, extendRegion, nodeMap);
3097         }
3098         surfaceNode->UpdateExtendVisibleRegion(extendRegion);
3099     });
3100 }
3101 
3102 void RSUniRenderVisitor::ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
3103     Occlusion::Region& extendRegion, const RSRenderNodeMap& nodeMap)
3104 {
3105     const auto& visibleFilterChild = surfaceNode->GetVisibleFilterChild();
3106     auto visibleRegion = surfaceNode->GetVisibleRegion();
3107     auto currentFrameDirtyRegion = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
3108     auto isTransparent = surfaceNode->IsTransparent();
3109     for (const auto& child : visibleFilterChild) {
3110         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3111         if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
3112             continue;
3113         }
3114         MarkBlurIntersectWithDRM(filterNode);
3115         auto filterRect = filterNode->GetOldDirtyInSurface();
3116         auto visibleRects = visibleRegion.GetRegionRectIs();
3117         auto iter = std::find_if(visibleRects.begin(), visibleRects.end(), [&filterRect](const auto& rect) {
3118             return filterRect.IsInsideOf(rect);
3119         });
3120         if (iter != visibleRects.end()) {
3121             continue;
3122         }
3123         if (!visibleRegion.IsIntersectWith(filterRect)) {
3124             continue;
3125         }
3126         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ filterRect } };
3127         extendRegion = extendRegion.Or(filterRegion);
3128         if (!isTransparent && filterRect.Intersect(currentFrameDirtyRegion)) {
3129             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(filterRect);
3130         }
3131     }
3132 }
3133 
3134 void RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
3135 {
3136     if (surfaceNode == nullptr) {
3137         return;
3138     }
3139     if (surfaceNode->HasBlurFilter()) {
3140         surfaceNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
3141     }
3142     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3143     for (auto& child : surfaceNode->GetVisibleFilterChild()) {
3144         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3145         if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
3146             continue;
3147         }
3148         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode "
3149             "surfaceNode: %s, filterNode:[%lld], IsOccludedByFilterCache:%d", surfaceNode->GetName().c_str(),
3150             filterNode->GetId(), surfaceNode->IsOccludedByFilterCache());
3151         filterNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
3152     }
3153 }
3154 
3155 void RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay(Occlusion::Region& accumulatedDirtyRegion)
3156 {
3157     // [planning] if not allowed containerNode filter, The following processing logic can be removed
3158     // Recursively traverses container nodes need filter
3159     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3160     for (auto it = containerFilter_.begin(); it != containerFilter_.end(); ++it) {
3161         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(it->first);
3162         if (filterNode == nullptr) {
3163             continue;
3164         }
3165         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
3166         auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
3167         RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeGlobalFilterForDisplay::filternode:%" PRIu64
3168                                    ", filterRect:%s, dirtyRegion:%s",
3169             filterNode->GetId(), it->second.ToString().c_str(), accumulatedDirtyRegion.GetRegionInfo().c_str());
3170         if (!filterDirtyRegion.IsEmpty()) {
3171             RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
3172                 "global dirty %{public}s, add container filterRegion %{public}s",
3173                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3174                 (it->second).ToString().c_str());
3175             if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3176                 filterNode->MarkFilterStatusChanged(false, false); // background filter affected by below dirty
3177             }
3178             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
3179             if (filterNode->GetRenderProperties().GetFilter()) {
3180                 filterNode->MarkFilterStatusChanged(true, false); // foreground filter affected by below dirty
3181             }
3182         } else {
3183             globalFilter_.insert(*it);
3184         }
3185         filterNode->UpdateFilterCacheWithSelfDirty();
3186         filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
3187     }
3188 
3189     UpdateDisplayDirtyAndExtendVisibleRegion();
3190     CheckMergeFilterDirtyByIntersectWithDirty(globalFilter_, true);
3191 }
3192 
3193 void RSUniRenderVisitor::CollectEffectInfo(RSRenderNode& node)
3194 {
3195     auto nodeParent = node.GetParent().lock();
3196     if (nodeParent == nullptr) {
3197         return;
3198     }
3199     if (node.GetRenderProperties().NeedFilter() || node.ChildHasVisibleFilter()) {
3200         nodeParent->SetChildHasVisibleFilter(true);
3201         nodeParent->UpdateVisibleFilterChild(node);
3202     }
3203     if ((node.GetRenderProperties().GetUseEffect() && node.ShouldPaint())|| node.ChildHasVisibleEffect()) {
3204         nodeParent->SetChildHasVisibleEffect(true);
3205         nodeParent->UpdateVisibleEffectChild(node);
3206     }
3207     if (node.GetSharedTransitionParam() || node.ChildHasSharedTransition()) {
3208         nodeParent->SetChildHasSharedTransition(true);
3209     }
3210 }
3211 
3212 void RSUniRenderVisitor::PostPrepare(RSRenderNode& node, bool subTreeSkipped)
3213 {
3214     UpdateCurFrameInfoDetail(node, subTreeSkipped, true);
3215     if (const auto& sharedTransitionParam = node.GetSharedTransitionParam()) {
3216         sharedTransitionParam->GenerateDrawable(node);
3217     }
3218     auto curDirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
3219     if (!curDirtyManager) {
3220         return;
3221     }
3222     auto isOccluded = curSurfaceNode_ ?
3223         curSurfaceNode_->IsMainWindowType() && curSurfaceNode_->GetVisibleRegion().IsEmpty() : false;
3224     if (subTreeSkipped && (!isOccluded || node.IsFirstLevelCrossNode())) {
3225         UpdateHwcNodeRectInSkippedSubTree(node);
3226         CheckFilterNodeInSkippedSubTreeNeedClearCache(node, *curDirtyManager);
3227         UpdateSubSurfaceNodeRectInSkippedSubTree(node);
3228     }
3229     if (node.NeedUpdateDrawableBehindWindow()) {
3230         node.GetMutableRenderProperties().SetNeedDrawBehindWindow(node.NeedDrawBehindWindow());
3231     }
3232     auto globalFilterRect = (node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren()) ?
3233         GetVisibleEffectDirty(node) : node.GetOldDirtyInSurface();
3234     auto globalHwcFilterRect = (node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren()) ?
3235         GetHwcVisibleEffectDirty(node, globalFilterRect) : globalFilterRect;
3236     if (node.NeedDrawBehindWindow()) {
3237         node.CalDrawBehindWindowRegion();
3238         globalFilterRect = node.GetFilterRect();
3239     }
3240     if (node.GetRenderProperties().NeedFilter() || node.IsBlendWithBackground()) {
3241         UpdateHwcNodeEnableByFilterRect(
3242             curSurfaceNode_, node.GetOldDirtyInSurface(), node.GetId(), NeedPrepareChindrenInReverseOrder(node),
3243             node.zOrderForCalcHwcNodeEnableByFilter_);
3244         node.CalVisibleFilterRect(prepareClipRect_);
3245         node.MarkClearFilterCacheIfEffectChildrenChanged();
3246         CollectFilterInfoAndUpdateDirty(node, *curDirtyManager, globalFilterRect, globalHwcFilterRect);
3247         node.SetGlobalAlpha(curAlpha_);
3248     }
3249     CollectEffectInfo(node);
3250     node.MapAndUpdateChildrenRect();
3251     node.UpdateSubTreeInfo(prepareClipRect_);
3252     node.UpdateLocalDrawRect();
3253     node.UpdateAbsDrawRect();
3254     node.ResetChangeState();
3255     node.SetHasUnobscuredUEC();
3256     if (isDrawingCacheEnabled_) {
3257         node.UpdateDrawingCacheInfoAfterChildren();
3258     }
3259     if (auto nodeParent = node.GetParent().lock()) {
3260         nodeParent->UpdateChildUifirstSupportFlag(node.GetUifirstSupportFlag());
3261         nodeParent->OpincUpdateNodeSupportFlag(node.OpincGetNodeSupportFlag());
3262     }
3263     auto& stagingRenderParams = node.GetStagingRenderParams();
3264     if (stagingRenderParams != nullptr) {
3265         if (node.GetSharedTransitionParam() && node.GetRenderProperties().GetSandBox()) {
3266             stagingRenderParams->SetAlpha(curAlpha_);
3267         } else {
3268             stagingRenderParams->SetAlpha(node.GetRenderProperties().GetAlpha());
3269         }
3270     }
3271 
3272     // planning: only do this if node is dirty
3273     node.UpdateRenderParams();
3274 
3275     // add if node is dirty
3276     node.AddToPendingSyncList();
3277 }
3278 
3279 void RSUniRenderVisitor::MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const
3280 {
3281     if (!RSSystemProperties::GetDrmMarkedFilterEnabled()) {
3282         return;
3283     }
3284     static std::vector<std::string> drmKeyWins = { "SCBVolumePanel", "SCBBannerNotification" };
3285     auto appWindowNodeId = node->GetInstanceRootNodeId();
3286     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3287     auto appWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
3288     if (appWindowNode == nullptr) {
3289         return;
3290     }
3291     for (const auto& win : drmKeyWins) {
3292         if (appWindowNode->GetName().find(win) == std::string::npos) {
3293             continue;
3294         }
3295         for (auto& drmNode : drmNodes_) {
3296             auto drmNodePtr = drmNode.lock();
3297             if (drmNodePtr == nullptr) {
3298                 continue;
3299             }
3300             bool isIntersect =
3301                 drmNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(node->GetFilterRegion());
3302             if (isIntersect) {
3303                 node->MarkBlurIntersectWithDRM(true, RSMainThread::Instance()->GetGlobalDarkColorMode());
3304             }
3305         }
3306     }
3307 }
3308 
3309 void RSUniRenderVisitor::CheckFilterNodeInSkippedSubTreeNeedClearCache(
3310     const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager)
3311 {
3312     bool rotationChanged = curDisplayNode_ ?
3313         curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
3314     bool rotationStatusChanged = curDisplayNode_ ?
3315         curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
3316     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3317     for (auto& child : rootNode.GetVisibleFilterChild()) {
3318         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3319         if (filterNode == nullptr) {
3320             continue;
3321         }
3322         RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInSkippedSubTreeNeedClearCache node[%lld]", filterNode->GetId());
3323         if (auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode)) {
3324             UpdateRotationStatusForEffectNode(*effectNode);
3325         }
3326         filterNode->CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
3327         filterNode->MarkClearFilterCacheIfEffectChildrenChanged();
3328         if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3329             filterNode->UpdateFilterCacheWithBelowDirty(dirtyManager, false);
3330         }
3331         RectI filterRect;
3332         filterNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, prepareClipRect_);
3333         UpdateHwcNodeEnableByFilterRect(curSurfaceNode_, filterNode->GetOldDirtyInSurface(), filterNode->GetId());
3334         CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager, filterRect, filterRect);
3335     }
3336 }
3337 
3338 void RSUniRenderVisitor::UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3339 {
3340     if (!curSurfaceNode_ || RS_PROFILER_SHOULD_BLOCK_HWCNODE()) {
3341         return;
3342     }
3343     const auto& hwcNodes = curSurfaceNode_->GetChildHardwareEnabledNodes();
3344     if (hwcNodes.empty()) {
3345         return;
3346     }
3347     for (auto hwcNode : hwcNodes) {
3348         auto hwcNodePtr = hwcNode.lock();
3349         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree() || hwcNodePtr->GetCalcRectInPrepare()) {
3350             continue;
3351         }
3352         const auto& property = hwcNodePtr->GetRenderProperties();
3353         auto geoPtr = property.GetBoundsGeometry();
3354         if (geoPtr == nullptr) {
3355             return;
3356         }
3357         auto originalMatrix = geoPtr->GetMatrix();
3358         auto matrix = Drawing::Matrix();
3359         auto parent = hwcNodePtr->GetCurCloneNodeParent().lock();
3360         if (parent == nullptr) {
3361             parent = hwcNodePtr->GetParent().lock();
3362         }
3363         if (!FindRootAndUpdateMatrix(parent, matrix, rootNode)) {
3364             continue;
3365         }
3366         if (parent) {
3367             const auto& parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
3368             if (parentGeoPtr) {
3369                 matrix.PostConcat(parentGeoPtr->GetMatrix());
3370             }
3371         }
3372         RectI clipRect;
3373         UpdateHWCNodeClipRect(hwcNodePtr, clipRect, rootNode);
3374         auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
3375         auto& properties = hwcNodePtr->GetMutableRenderProperties();
3376         auto offset = std::nullopt;
3377         properties.UpdateGeometryByParent(&matrix, offset);
3378         matrix.PreConcat(originalMatrix);
3379         Drawing::Rect bounds = Drawing::Rect(0, 0, properties.GetBoundsWidth(), properties.GetBoundsHeight());
3380         Drawing::Rect absRect;
3381         matrix.MapRect(absRect, bounds);
3382         RectI rect;
3383         rect.left_ = static_cast<int>(std::floor(absRect.GetLeft()));
3384         rect.top_ = static_cast<int>(std::floor(absRect.GetTop()));
3385         rect.width_ = static_cast<int>(std::ceil(absRect.GetRight() - rect.left_));
3386         rect.height_ = static_cast<int>(std::ceil(absRect.GetBottom() - rect.top_));
3387         UpdateDstRect(*hwcNodePtr, rect, clipRect);
3388         UpdateSrcRect(*hwcNodePtr, matrix, rect);
3389         UpdateHwcNodeByTransform(*hwcNodePtr, matrix);
3390         UpdateHwcNodeEnableByBackgroundAlpha(*hwcNodePtr);
3391         UpdateHwcNodeEnableBySrcRect(*hwcNodePtr);
3392         UpdateHwcNodeEnableByBufferSize(*hwcNodePtr);
3393         hwcNodePtr->SetTotalMatrix(matrix);
3394         hwcNodePtr->SetOldDirtyInSurface(geoPtr->MapRect(hwcNodePtr->GetSelfDrawRect(), matrix));
3395     }
3396 }
3397 
3398 bool RSUniRenderVisitor::FindRootAndUpdateMatrix(std::shared_ptr<RSRenderNode>& parent, Drawing::Matrix& matrix,
3399     const RSRenderNode& rootNode)
3400 {
3401     bool findInRoot = parent ? parent->GetId() == rootNode.GetId() : false;
3402     while (parent && parent->GetType() != RSRenderNodeType::DISPLAY_NODE) {
3403         if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
3404             matrix.PostConcat(opt.value());
3405         } else {
3406             break;
3407         }
3408         auto cloneNodeParent = parent->GetCurCloneNodeParent().lock();
3409         parent = cloneNodeParent ? cloneNodeParent : parent->GetParent().lock();
3410         if (!parent) {
3411             break;
3412         }
3413         findInRoot = parent->GetId() == rootNode.GetId() ? true : findInRoot;
3414     }
3415     return findInRoot;
3416 }
3417 
3418 void RSUniRenderVisitor::UpdateHWCNodeClipRect(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr, RectI& clipRect,
3419     const RSRenderNode& rootNode)
3420 {
3421     // The value here represents an imaginary plane of infinite width and infinite height,
3422     // using values summarized empirically.
3423     constexpr float MAX_FLOAT = std::numeric_limits<float>::max() * 1e-30;
3424     Drawing::Rect childRectMapped(0.0f, 0.0f, MAX_FLOAT, MAX_FLOAT);
3425     RSRenderNode::SharedPtr hwcNodeParent = hwcNodePtr;
3426     while (hwcNodeParent && hwcNodeParent->GetType() != RSRenderNodeType::DISPLAY_NODE &&
3427            hwcNodeParent->GetId() != rootNode.GetId()) {
3428         const auto& parentProperties = hwcNodeParent->GetRenderProperties();
3429         const auto& parentGeoPtr = parentProperties.GetBoundsGeometry();
3430         parentGeoPtr->GetMatrix().MapRect(childRectMapped, childRectMapped);
3431         if (parentProperties.GetClipToBounds()) {
3432             auto selfDrawRectF = hwcNodeParent->GetSelfDrawRect();
3433             Drawing::Rect clipSelfDrawRect(selfDrawRectF.left_, selfDrawRectF.top_,
3434                 selfDrawRectF.GetRight(), selfDrawRectF.GetBottom());
3435             Drawing::Rect clipBoundRectMapped;
3436             parentGeoPtr->GetMatrix().MapRect(clipBoundRectMapped, clipSelfDrawRect);
3437             childRectMapped.Intersect(clipBoundRectMapped);
3438         }
3439         if (parentProperties.GetClipToFrame()) {
3440             auto left = parentProperties.GetFrameOffsetX() * parentGeoPtr->GetMatrix().Get(Drawing::Matrix::SCALE_X);
3441             auto top = parentProperties.GetFrameOffsetY() * parentGeoPtr->GetMatrix().Get(Drawing::Matrix::SCALE_Y);
3442             Drawing::Rect clipFrameRect(
3443                 left, top, left + parentProperties.GetFrameWidth(), top + parentProperties.GetFrameHeight());
3444             Drawing::Rect clipFrameRectMapped;
3445             parentGeoPtr->GetMatrix().MapRect(clipFrameRectMapped, clipFrameRect);
3446             childRectMapped.Intersect(clipFrameRectMapped);
3447         }
3448         if (parentProperties.GetClipToRRect()) {
3449             RectF rectF = parentProperties.GetClipRRect().rect_;
3450             Drawing::Rect clipRect(rectF.left_, rectF.top_, rectF.GetRight(), rectF.GetBottom());
3451             Drawing::Rect clipRectMapped;
3452             parentGeoPtr->GetMatrix().MapRect(clipRectMapped, clipRect);
3453             childRectMapped.Intersect(clipRectMapped);
3454         }
3455         hwcNodeParent = hwcNodeParent->GetParent().lock();
3456     }
3457     Drawing::Matrix rootNodeAbsMatrix = rootNode.GetRenderProperties().GetBoundsGeometry()->GetAbsMatrix();
3458     Drawing::Rect absClipRect;
3459     rootNodeAbsMatrix.MapRect(absClipRect, childRectMapped);
3460     Drawing::Rect prepareClipRect(prepareClipRect_.left_, prepareClipRect_.top_,
3461         prepareClipRect_.GetRight(), prepareClipRect_.GetBottom());
3462     absClipRect.Intersect(prepareClipRect);
3463     clipRect.left_ = static_cast<int>(std::floor(absClipRect.GetLeft()));
3464     clipRect.top_ = static_cast<int>(std::floor(absClipRect.GetTop()));
3465     clipRect.width_ = static_cast<int>(std::ceil(absClipRect.GetRight() - clipRect.left_));
3466     clipRect.height_ = static_cast<int>(std::ceil(absClipRect.GetBottom() - clipRect.top_));
3467 }
3468 
3469 bool RSUniRenderVisitor::IsStencilPixelOcclusionCullingEnable() const
3470 {
3471     static auto stencilPixelOcclusionCullingParam =
3472             GraphicFeatureParamManager::GetInstance().GetFeatureParam("SpocConfig");
3473     auto stencilPixelOcclusionCullingFeature =
3474         std::static_pointer_cast<StencilPixelOcclusionCullingParam>(stencilPixelOcclusionCullingParam);
3475     if (stencilPixelOcclusionCullingFeature == nullptr) {
3476         ROSEN_LOGE("RSUniRenderVisitor::IsStencilPixelOcclusionCullingEnable "
3477         "stencilPixelOcclusionCullingFeature is nullptr");
3478         return false;
3479     }
3480     return stencilPixelOcclusionCullingFeature->IsStencilPixelOcclusionCullingEnable();
3481 }
3482 
3483 void RSUniRenderVisitor::UpdateHardwareStateByHwcNodeBackgroundAlpha(
3484     const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes)
3485 {
3486     std::list<RectI> hwcRects;
3487     for (size_t i = 0; i < hwcNodes.size(); i++) {
3488         auto hwcNodePtr = hwcNodes[i].lock();
3489         if (!hwcNodePtr) {
3490             continue;
3491         }
3492         if (!hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled()) {
3493             hwcRects.push_back(hwcNodePtr->GetDstRect());
3494         } else if (hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled() &&
3495             hwcRects.size() != 0) {
3496             continue;
3497         } else {
3498             hwcNodePtr->SetHardwareForcedDisabledState(true);
3499             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by hwc node backgound alpha",
3500                 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
3501         }
3502     }
3503 }
3504 
3505 bool RSUniRenderVisitor::IsNodeAboveInsideOfNodeBelow(const RectI& rectAbove, std::list<RectI>& hwcNodeRectList)
3506 {
3507     for (auto rectBelow: hwcNodeRectList) {
3508         if (rectAbove.IsInsideOf(rectBelow)) {
3509             return true;
3510         }
3511     }
3512     return false;
3513 }
3514 
3515 void RSUniRenderVisitor::CalcHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode>& node,
3516     const RectI& filterRect, NodeId filterNodeId, bool isReverseOrder, int32_t filterZorder)
3517 {
3518     if (!node) {
3519         return;
3520     }
3521     if (filterZorder != 0 && node->zOrderForCalcHwcNodeEnableByFilter_ != 0 &&
3522         node->zOrderForCalcHwcNodeEnableByFilter_ > filterZorder) {
3523         return;
3524     }
3525     auto& geoPtr = node->GetRenderProperties().GetBoundsGeometry();
3526     if (geoPtr == nullptr) {
3527         return;
3528     }
3529     auto bound = geoPtr->GetAbsRect();
3530     bool isIntersect = !bound.IntersectRect(filterRect).IsEmpty();
3531     if (isIntersect) {
3532         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by filter rect, filterId:%" PRIu64,
3533             node->GetName().c_str(), node->GetId(), filterNodeId);
3534 #ifdef HIPERF_TRACE_ENABLE
3535         RS_LOGW("hiperf_surface: name:%s disabled by filter rect, surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
3536             node->GetName().c_str(),
3537             node->GetSrcRect().GetLeft(), node->GetSrcRect().GetRight(),
3538             node->GetSrcRect().GetTop(), node->GetSrcRect().GetBottom(),
3539             node->GetSrcRect().GetLeft(), node->GetSrcRect().GetRight(),
3540             node->GetSrcRect().GetTop(), node->GetSrcRect().GetBottom());
3541 #endif
3542         node->SetIsHwcPendingDisabled(true);
3543         node->SetHardwareForcedDisabledState(true);
3544         node->SetHardWareDisabledByReverse(isReverseOrder);
3545         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
3546             HwcDisabledReasons::DISABLED_BY_FLITER_RECT, node->GetName());
3547     }
3548 }
3549 
3550 void RSUniRenderVisitor::UpdateHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode>& node,
3551     const RectI& filterRect, NodeId filterNodeId, bool isReverseOrder, int32_t filterZorder)
3552 {
3553     if (filterRect.IsEmpty()) {
3554         return;
3555     }
3556     if (!node) {
3557         const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
3558         if (selfDrawingNodes.empty()) {
3559             return;
3560         }
3561         for (auto hwcNode : selfDrawingNodes) {
3562             CalcHwcNodeEnableByFilterRect(hwcNode, filterRect, filterNodeId, isReverseOrder, filterZorder);
3563         }
3564     } else {
3565         const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
3566         if (hwcNodes.empty()) {
3567             return;
3568         }
3569         for (auto hwcNode : hwcNodes) {
3570             auto hwcNodePtr = hwcNode.lock();
3571             CalcHwcNodeEnableByFilterRect(hwcNodePtr, filterRect, filterNodeId, isReverseOrder, filterZorder);
3572         }
3573     }
3574 }
3575 
3576 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode>& node)
3577 {
3578     auto cleanFilter = transparentHwcCleanFilter_.find(node->GetId());
3579     bool cleanFilterFound = (cleanFilter != transparentHwcCleanFilter_.end());
3580     auto dirtyFilter = transparentHwcDirtyFilter_.find(node->GetId());
3581     bool dirtyFilterFound = (dirtyFilter != transparentHwcDirtyFilter_.end());
3582     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
3583     for (auto it = curMainAndLeashSurfaces.rbegin(); it != curMainAndLeashSurfaces.rend(); ++it) {
3584         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
3585         if (surfaceNode == nullptr) {
3586             continue;
3587         }
3588         if (surfaceNode->GetId() == node->GetId()) {
3589             return;
3590         }
3591         const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
3592         if (hwcNodes.empty()) {
3593             continue;
3594         }
3595         for (auto hwcNode : hwcNodes) {
3596             auto hwcNodePtr = hwcNode.lock();
3597             if (!hwcNodePtr || hwcNodePtr->IsHardwareForcedDisabled() ||
3598                 !hwcNodePtr->GetRenderProperties().GetBoundsGeometry()) {
3599                 continue;
3600             }
3601             if (cleanFilterFound) {
3602                 UpdateHwcNodeEnableByGlobalCleanFilter(cleanFilter->second, *hwcNodePtr);
3603                 if (hwcNodePtr->IsHardwareForcedDisabled()) {
3604                     continue;
3605                 }
3606             }
3607             if (!dirtyFilterFound) {
3608                 continue;
3609             }
3610             for (auto filter = dirtyFilter->second.begin(); filter != dirtyFilter->second.end(); ++filter) {
3611                 if (hwcNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(filter->second)) {
3612                     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentDirtyFilter, "
3613                         "filterId:%" PRIu64, hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(), filter->first);
3614 #ifdef HIPERF_TRACE_ENABLE
3615                     RS_LOGW("hiperf_surface: name:%s disabled by transparentDirtyFilter, "
3616                         "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", hwcNodePtr->GetName().c_str(),
3617                         hwcNodePtr->GetSrcRect().GetLeft(), hwcNodePtr->GetSrcRect().GetRight(),
3618                         hwcNodePtr->GetSrcRect().GetTop(), hwcNodePtr->GetSrcRect().GetBottom(),
3619                         hwcNodePtr->GetSrcRect().GetLeft(), hwcNodePtr->GetSrcRect().GetRight(),
3620                         hwcNodePtr->GetSrcRect().GetTop(), hwcNodePtr->GetSrcRect().GetBottom());
3621 #endif
3622                     hwcNodePtr->SetHardwareForcedDisabledState(true);
3623                     hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
3624                         HwcDisabledReasons::DISABLED_BY_TRANSPARENT_DIRTY_FLITER, hwcNodePtr->GetName());
3625                     break;
3626                 }
3627             }
3628         }
3629     }
3630 }
3631 
3632 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalCleanFilter(
3633     const std::vector<std::pair<NodeId, RectI>>& cleanFilter, RSSurfaceRenderNode& hwcNodePtr)
3634 {
3635     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3636     bool intersectedWithAIBar = false;
3637     bool checkDrawAIBar = false;
3638     for (auto filter = cleanFilter.begin(); filter != cleanFilter.end(); ++filter) {
3639         auto geo = hwcNodePtr.GetRenderProperties().GetBoundsGeometry();
3640         if (!geo) {
3641             return;
3642         }
3643         if (!geo->GetAbsRect().IntersectRect(filter->second).IsEmpty()) {
3644             auto& rendernode = nodeMap.GetRenderNode<RSRenderNode>(filter->first);
3645             if (rendernode == nullptr) {
3646                 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: rendernode is null");
3647                 continue;
3648             }
3649 
3650             if (rendernode->IsAIBarFilter()) {
3651                 intersectedWithAIBar = true;
3652                 if (rendernode->IsAIBarFilterCacheValid()) {
3653                     ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: skip intersection for using cache");
3654                     continue;
3655                 } else if (RSSystemProperties::GetHveFilterEnabled()) {
3656                     checkDrawAIBar = true;
3657                     continue;
3658                 }
3659             }
3660             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentCleanFilter, filterId:"
3661                 "%" PRIu64, hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId(), filter->first);
3662 #ifdef HIPERF_TRACE_ENABLE
3663             RS_LOGW("hiperf_surface: name:%s disabled by transparentCleanFilter, "
3664                 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", hwcNodePtr.GetName().c_str(),
3665                 hwcNodePtr.GetSrcRect().GetLeft(), hwcNodePtr.GetSrcRect().GetRight(),
3666                 hwcNodePtr.GetSrcRect().GetTop(), hwcNodePtr.GetSrcRect().GetBottom(),
3667                 hwcNodePtr.GetSrcRect().GetLeft(), hwcNodePtr.GetSrcRect().GetRight(),
3668                 hwcNodePtr.GetSrcRect().GetTop(), hwcNodePtr.GetSrcRect().GetBottom());
3669 #endif
3670             hwcNodePtr.SetHardwareForcedDisabledState(true);
3671             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr.GetId(),
3672                 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_CLEAN_FLITER, hwcNodePtr.GetName());
3673             break;
3674         }
3675     }
3676     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64", checkDrawAIBar:%d, intersectedWithAIBar:%d",
3677         hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId(), checkDrawAIBar, intersectedWithAIBar);
3678     if (checkDrawAIBar) {
3679         hwcNodePtr.SetHardwareNeedMakeImage(checkDrawAIBar);
3680     }
3681     if (intersectedWithAIBar) {
3682         hwcNodePtr.SetIntersectWithAIBar(intersectedWithAIBar);
3683     }
3684 }
3685 
3686 inline static void ResetSubSurfaceNodesCalState(
3687     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>>& subSurfaceNodes)
3688 {
3689     for (auto& [id, node] : subSurfaceNodes) {
3690         auto subSurfaceNodePtr = node.lock();
3691         if (!subSurfaceNodePtr) {
3692             continue;
3693         }
3694         subSurfaceNodePtr->SetCalcRectInPrepare(false);
3695     }
3696 }
3697 
3698 void RSUniRenderVisitor::UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3699 {
3700     if (!curSurfaceNode_ || !curSurfaceDirtyManager_) {
3701         return;
3702     }
3703     auto rootGeo = rootNode.GetRenderProperties().GetBoundsGeometry();
3704     if (!rootGeo) {
3705         return;
3706     }
3707 
3708     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
3709     curSurfaceNode_->GetAllSubSurfaceNodes(allSubSurfaceNodes);
3710     for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
3711         auto subSurfaceNodePtr = subSurfaceNode.lock();
3712         Drawing::Matrix absMatrix;
3713         if (!subSurfaceNodePtr || subSurfaceNodePtr->GetCalcRectInPrepare() ||
3714             !subSurfaceNodePtr->GetAbsMatrixReverse(rootNode, absMatrix)) {
3715             continue;
3716         }
3717 
3718         Drawing::RectF absDrawRect;
3719         absMatrix.MapRect(absDrawRect, RSPropertiesPainter::Rect2DrawingRect(subSurfaceNodePtr->GetSelfDrawRect()));
3720         RectI subSurfaceRect = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
3721             absDrawRect.GetWidth(), absDrawRect.GetHeight());
3722 
3723         subSurfaceNodePtr->SetOldDirtyInSurface(subSurfaceRect.IntersectRect(prepareClipRect_));
3724         UpdateNodeVisibleRegion(*subSurfaceNodePtr);
3725         UpdateDstRect(*subSurfaceNodePtr, subSurfaceRect, prepareClipRect_);
3726         subSurfaceNodePtr->SetCalcRectInPrepare(true);
3727         if (subSurfaceNodePtr->IsLeashOrMainWindow()) {
3728             curMainAndLeashWindowNodesIds_.push(subSurfaceNodePtr->GetId());
3729             curDisplayNode_->RecordMainAndLeashSurfaces(subSurfaceNodePtr);
3730             curDisplayNode_->UpdateSurfaceNodePos(
3731                 subSurfaceNodePtr->GetId(), subSurfaceNodePtr->GetOldDirtyInSurface());
3732             if (auto subSurfaceDirtyManager = subSurfaceNodePtr->GetDirtyManager()) {
3733                 subSurfaceDirtyManager->MergeDirtyRect(subSurfaceNodePtr->GetOldDirtyInSurface().IntersectRect(
3734                     curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion()));
3735             }
3736             CollectOcclusionInfoForWMS(*subSurfaceNodePtr);
3737             auto& rateReduceManager = RSMainThread::Instance()->GetRSVsyncRateReduceManager();
3738             rateReduceManager.PushWindowNodeId(subSurfaceNodePtr->GetId());
3739             rateReduceManager.CollectSurfaceVsyncInfo(screenInfo_, *subSurfaceNodePtr);
3740             subSurfaceNodePtr->UpdateRenderParams();
3741         }
3742     }
3743     ResetSubSurfaceNodesCalState(allSubSurfaceNodes);
3744 }
3745 
3746 RectI RSUniRenderVisitor::GetVisibleEffectDirty(RSRenderNode& node) const
3747 {
3748     RectI childEffectRect;
3749     auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3750     for (auto& nodeId : node.GetVisibleEffectChild()) {
3751         if (auto& subnode = nodeMap.GetRenderNode<RSRenderNode>(nodeId)) {
3752             childEffectRect = childEffectRect.JoinRect(subnode->GetOldDirtyInSurface());
3753         }
3754     }
3755     return childEffectRect;
3756 }
3757 
3758 RectI RSUniRenderVisitor::GetHwcVisibleEffectDirty(RSRenderNode& node, const RectI globalFilterRect) const
3759 {
3760     RectI childEffectRect;
3761     if (!globalFilterRect.IsEmpty()) {
3762         childEffectRect = globalFilterRect.JoinRect(node.GetFilterRect());
3763     }
3764     return childEffectRect;
3765 }
3766 
3767 void RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty(RSRenderNode& node,
3768     RSDirtyRegionManager& dirtyManager, const RectI& globalFilterRect, const RectI& globalHwcFilterRect)
3769 {
3770     bool isNodeAddedToTransparentCleanFilters = false;
3771     if (curSurfaceNode_) {
3772         bool isIntersect = dirtyManager.GetCurrentFrameDirtyRegion().Intersect(globalFilterRect);
3773         if (isIntersect) {
3774             dirtyManager.MergeDirtyRect(globalHwcFilterRect);
3775         } else {
3776             curSurfaceNoBelowDirtyFilter_.insert({node.GetId(), globalHwcFilterRect});
3777         }
3778         if (node.GetRenderProperties().GetFilter()) {
3779             node.UpdateFilterCacheWithBelowDirty(dirtyManager, true);
3780         }
3781         node.UpdateFilterCacheWithSelfDirty();
3782         if (curSurfaceNode_->IsTransparent()) {
3783             if (!isIntersect || (isIntersect && (node.GetRenderProperties().GetBackgroundFilter() ||
3784                 node.GetRenderProperties().GetNeedDrawBehindWindow()) && !node.IsBackgroundInAppOrNodeSelfDirty())) {
3785                 // record nodes which has transparent clean filter
3786                 RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInfoAndUpdateDirty::surfaceNode:%s, add node[%lld] to "
3787                     "transparentCleanFilter", curSurfaceNode_->GetName().c_str(), node.GetId());
3788                 transparentCleanFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalHwcFilterRect});
3789                 transparentHwcCleanFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalHwcFilterRect});
3790                 isNodeAddedToTransparentCleanFilters = true;
3791             }
3792             if (isIntersect) {
3793                 transparentDirtyFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalHwcFilterRect});
3794                 transparentHwcDirtyFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalHwcFilterRect});
3795                 RS_LOGD("RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty global merge transparentDirtyFilter "
3796                     "%{public}s, global dirty %{public}s, add rect %{public}s", curSurfaceNode_->GetName().c_str(),
3797                     curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
3798                     globalHwcFilterRect.ToString().c_str());
3799                 curDisplayDirtyManager_->MergeDirtyRect(globalHwcFilterRect);
3800             }
3801         } else {
3802             // record surface nodes and nodes in surface which has clean filter
3803             globalFilter_.insert({node.GetId(), globalHwcFilterRect});
3804         }
3805     } else {
3806         // record container nodes which need filter
3807         containerFilter_.insert({node.GetId(), globalHwcFilterRect});
3808     }
3809     if (curSurfaceNode_ && !isNodeAddedToTransparentCleanFilters) {
3810         node.PostPrepareForBlurFilterNode(dirtyManager, needRequestNextVsync_);
3811         RsFrameBlurPredict::GetInstance().PredictDrawLargeAreaBlur(node);
3812     }
3813 }
3814 
3815 void RSUniRenderVisitor::UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode& node)
3816 {
3817     if (!node.IsLeashWindow()) {
3818         return;
3819     }
3820     auto& property = node.GetMutableRenderProperties();
3821     auto& geoPtr = (property.GetBoundsGeometry());
3822     if (geoPtr == nullptr) {
3823         return;
3824     }
3825     auto absMatrix = geoPtr->GetAbsMatrix();
3826     bool isScale = false;
3827     if (RSUifirstManager::Instance().GetUiFirstType() == UiFirstCcmType::MULTI) {
3828         isScale = (!ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_X), 1.f, EPSILON_SCALE) ||
3829             !ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_Y), 1.f, EPSILON_SCALE));
3830     } else {
3831         bool getMinMaxScales = false;
3832         // scaleFactors[0]-minimum scaling factor, scaleFactors[1]-maximum scaling factor
3833         Drawing::scalar scaleFactors[2];
3834         getMinMaxScales = absMatrix.GetMinMaxScales(scaleFactors);
3835         if (getMinMaxScales) {
3836             isScale = !ROSEN_EQ(scaleFactors[0], 1.f, EPSILON_SCALE) || !ROSEN_EQ(scaleFactors[1], 1.f, EPSILON_SCALE);
3837         }
3838         if (!getMinMaxScales) {
3839             RS_LOGD("getMinMaxScales fail, node:%{public}s %{public}" PRIu64 "", node.GetName().c_str(), node.GetId());
3840             const auto& dstRect = node.GetDstRect();
3841             float dstRectWidth = dstRect.GetWidth();
3842             float dstRectHeight = dstRect.GetHeight();
3843             float boundsWidth = property.GetBoundsWidth();
3844             float boundsHeight = property.GetBoundsHeight();
3845             isScale =
3846                 !ROSEN_EQ(std::min(dstRectWidth, dstRectHeight), std::min(boundsWidth, boundsHeight), EPSILON_SCALE) ||
3847                 !ROSEN_EQ(std::max(dstRectWidth, dstRectHeight), std::max(boundsWidth, boundsHeight), EPSILON_SCALE);
3848         }
3849     }
3850     node.SetIsScaleInPreFrame(node.IsScale());
3851     node.SetIsScale(isScale);
3852 }
3853 
3854 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
3855 {
3856     RS_TRACE_NAME_FMT("RSUniRender::PrepareRootRenderNode:node[%" PRIu64 "] pid[%d] subTreeDirty[%d]",
3857         node.GetId(), ExtractPid(node.GetId()), node.IsSubTreeDirty());
3858     bool dirtyFlag = dirtyFlag_;
3859     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3860     auto prepareClipRect = prepareClipRect_;
3861 
3862     auto nodeParent = (node.GetParent().lock());
3863     const auto& property = node.GetRenderProperties();
3864     bool geoDirty = property.IsGeoDirty();
3865     auto& geoPtr = (property.GetBoundsGeometry());
3866     auto prevAlpha = curAlpha_;
3867     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
3868 
3869     if (curSurfaceDirtyManager_ == nullptr) {
3870         RS_LOGE("RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
3871         return;
3872     }
3873     dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
3874         *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
3875 
3876     if (nodeParent == curSurfaceNode_) {
3877         const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
3878         const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
3879         Drawing::Matrix gravityMatrix;
3880         (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
3881             RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
3882             rootWidth, rootHeight, gravityMatrix);
3883         // Only Apply gravityMatrix when rootNode is dirty
3884         if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
3885             geoPtr->ConcatMatrix(gravityMatrix);
3886         }
3887     }
3888 
3889     if (geoPtr != nullptr) {
3890         parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3891     }
3892 
3893     node.EnableWindowKeyFrame(false);
3894 
3895     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
3896     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
3897         node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
3898     PostPrepare(node, !isSubTreeNeedPrepare);
3899 
3900     curAlpha_ = prevAlpha;
3901     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3902     dirtyFlag_ = dirtyFlag;
3903     prepareClipRect_ = prepareClipRect;
3904 }
3905 
3906 void RSUniRenderVisitor::SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams>& renderThreadParams)
3907 {
3908     if (!renderThreadParams) {
3909         RS_LOGE("RSUniRenderVisitor::SetUniRenderThreadParam renderThreadParams is nullptr");
3910         return;
3911     }
3912     renderThreadParams->isPartialRenderEnabled_ = isPartialRenderEnabled_;
3913     renderThreadParams->isRegionDebugEnabled_ = isRegionDebugEnabled_;
3914     renderThreadParams->isDirtyRegionDfxEnabled_ = isDirtyRegionDfxEnabled_;
3915     renderThreadParams->isDisplayDirtyDfxEnabled_ = isDisplayDirtyDfxEnabled_;
3916     renderThreadParams->isOpaqueRegionDfxEnabled_ = isOpaqueRegionDfxEnabled_;
3917     renderThreadParams->isVisibleRegionDfxEnabled_ = isVisibleRegionDfxEnabled_;
3918     renderThreadParams->isAllSurfaceVisibleDebugEnabled_ = isAllSurfaceVisibleDebugEnabled_;
3919     renderThreadParams->isTargetDirtyRegionDfxEnabled_ = isTargetDirtyRegionDfxEnabled_;
3920     renderThreadParams->dirtyRegionDebugType_ = dirtyRegionDebugType_;
3921     renderThreadParams->isOpDropped_ = isOpDropped_;
3922     renderThreadParams->isDirtyAlignEnabled_ = isDirtyAlignEnabled_;
3923     renderThreadParams->isStencilPixelOcclusionCullingEnabled_ = isStencilPixelOcclusionCullingEnabled_;
3924     renderThreadParams->isCrossNodeOffscreenOn_ = isCrossNodeOffscreenOn_;
3925     renderThreadParams->isUIFirstDebugEnable_ = isUIFirstDebugEnable_;
3926     renderThreadParams->dfxTargetSurfaceNames_ = std::move(dfxTargetSurfaceNames_);
3927     renderThreadParams->isVirtualDirtyEnabled_ = isVirtualDirtyEnabled_;
3928     renderThreadParams->isVirtualDirtyDfxEnabled_ = isVirtualDirtyDfxEnabled_;
3929     renderThreadParams->isExpandScreenDirtyEnabled_ = isExpandScreenDirtyEnabled_;
3930     renderThreadParams->advancedDirtyType_ = advancedDirtyType_;
3931     renderThreadParams->hasDisplayHdrOn_ = hasDisplayHdrOn_;
3932     renderThreadParams->hasMirrorDisplay_ = hasMirrorDisplay_;
3933     renderThreadParams->isForceCommitLayer_ |=
3934         RSPointerWindowManager::Instance().IsNeedForceCommitByPointer();
3935 }
3936 
3937 void RSUniRenderVisitor::SendRcdMessage(RSDisplayRenderNode& node)
3938 {
3939     if (RoundCornerDisplayManager::CheckRcdRenderEnable(screenInfo_) &&
3940         RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
3941         using rcd_msg = RSSingleton<RsMessageBus>;
3942         uint32_t left = 0; // render region
3943         uint32_t top = 0;
3944         uint32_t width = screenInfo_.width;
3945         uint32_t height = screenInfo_.height;
3946         if (!screenInfo_.activeRect.IsEmpty()) {
3947             left = static_cast<uint32_t>(std::max(0, screenInfo_.activeRect.GetLeft()));
3948             top = static_cast<uint32_t>(std::max(0, screenInfo_.activeRect.GetTop()));
3949             width = static_cast<uint32_t>(std::max(0, screenInfo_.activeRect.GetWidth()));
3950             height = static_cast<uint32_t>(std::max(0, screenInfo_.activeRect.GetHeight()));
3951         }
3952         rcd_msg::GetInstance().SendMsg<NodeId, uint32_t, uint32_t, uint32_t, uint32_t>(TOPIC_RCD_DISPLAY_SIZE,
3953             node.GetId(), left, top, width, height);
3954         rcd_msg::GetInstance().SendMsg<NodeId, ScreenRotation>(TOPIC_RCD_DISPLAY_ROTATION,
3955             node.GetId(), node.GetScreenRotation());
3956         rcd_msg::GetInstance().SendMsg<NodeId, int>(TOPIC_RCD_DISPLAY_NOTCH,
3957             node.GetId(), RSSystemParameters::GetHideNotchStatus());
3958     }
3959 }
3960 
3961 void RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode()
3962 {
3963     static auto unpairNode = [](const std::weak_ptr<RSRenderNode>& wptr) {
3964         auto sptr = wptr.lock();
3965         if (sptr == nullptr) {
3966             return;
3967         }
3968         // make sure parent regenerates ChildrenDrawable
3969         auto parent = sptr->GetParent().lock();
3970         if (parent == nullptr) {
3971             return;
3972         }
3973         parent->AddDirtyType(RSModifierType::CHILDREN);
3974         parent->ApplyModifiers();
3975         // avoid changing the paired status or unpairedShareTransitions_
3976         auto param = sptr->GetSharedTransitionParam();
3977         if (param == nullptr) {
3978             ROSEN_LOGE("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: param is null");
3979             return;
3980         }
3981         param->paired_ = false;
3982         SharedTransitionParam::unpairedShareTransitions_.clear();
3983     };
3984     auto unpairedShareTransitions = std::move(SharedTransitionParam::unpairedShareTransitions_);
3985     for (auto& [id, wptr] : unpairedShareTransitions) {
3986         auto sharedTransitionParam = wptr.lock();
3987         // If the unpaired share transition is already deal with, do nothing
3988         if (!sharedTransitionParam) {
3989             continue;
3990         }
3991         sharedTransitionParam->ResetRelation();
3992         if (!sharedTransitionParam->paired_) {
3993             continue;
3994         }
3995         ROSEN_LOGD("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: mark %s as unpaired",
3996             sharedTransitionParam->Dump().c_str());
3997         sharedTransitionParam->paired_ = false;
3998         unpairNode(sharedTransitionParam->inNode_);
3999         unpairNode(sharedTransitionParam->outNode_);
4000     }
4001 }
4002 
4003 NodeId RSUniRenderVisitor::FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)
4004 {
4005     if (node == nullptr) {
4006         return INVALID_NODEID;
4007     }
4008     auto nodeParent = node->GetParent().lock();
4009     if (nodeParent == nullptr) {
4010         return INVALID_NODEID;
4011     }
4012     if (nodeParent->GetType() == RSRenderNodeType::DISPLAY_NODE) {
4013         return node->GetId();
4014     } else {
4015         return FindInstanceChildOfDisplay(nodeParent);
4016     }
4017 }
4018 
4019 void RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr>& surfaces)
4020 {
4021     // Debug dirtyregion of show current refreshRation
4022     if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
4023         if (curDisplayNode_ == nullptr) {
4024             RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate  curDisplayNode is nullptr");
4025             return;
4026         }
4027         RectI tempRect = {100, 100, 500, 200};   // setDirtyRegion for RealtimeRefreshRate
4028         bool surfaceNodeSet = false;
4029         bool needMapAbsRect = true;
4030         auto windowContainer = curDisplayNode_->GetWindowContainer();
4031         if (windowContainer) {
4032             if (!ROSEN_EQ(windowContainer->GetRenderProperties().GetScaleX(), 1.0f, EPSILON_SCALE) ||
4033                 !ROSEN_EQ(windowContainer->GetRenderProperties().GetScaleY(), 1.0f, EPSILON_SCALE)) {
4034                 needMapAbsRect = false;
4035             }
4036         }
4037         for (auto surface : surfaces) {
4038             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
4039             if (surfaceNode == nullptr) {
4040                 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate surfaceNode is nullptr");
4041                 continue;
4042             }
4043             if (surfaceNode->GetName().find(RELIABLE_GESTURE_BACK_SURFACE_NAME) != std::string::npos) {
4044                 // refresh rate rect for mainwindow
4045                 auto& geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
4046                 if (!geoPtr) {
4047                     break;
4048                 }
4049                 if (needMapAbsRect) {
4050                     tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
4051                 }
4052                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
4053                 surfaceNodeSet = true;
4054                 break;
4055             }
4056         }
4057         if (!surfaceNodeSet) {
4058             auto &geoPtr = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
4059             if (!geoPtr) {
4060                 return;
4061             }
4062             if (needMapAbsRect) {
4063                 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
4064             }
4065             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
4066         }
4067     }
4068 }
4069 
4070 void RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay() const
4071 {
4072     if (!screenManager_ || !curDisplayNode_) {
4073         RS_LOGE(
4074             "RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay screenmanager or displaynode is nullptr");
4075         return;
4076     }
4077 
4078     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
4079     if (screenManager_->GetScreenType(curDisplayNode_->GetScreenId(), screenType) != SUCCESS) {
4080         RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay get screen type failed.");
4081         return;
4082     }
4083 
4084     if (screenType != EXTERNAL_TYPE_SCREEN) {
4085         return;
4086     }
4087 
4088     RectI dirtyRectTop, dirtyRectBottom;
4089     if (RSSingleton<RoundCornerDisplayManager>::GetInstance().HandleRoundCornerDirtyRect(
4090             curDisplayNode_->GetId(), dirtyRectTop, RoundCornerDisplayManager::RCDLayerType::TOP)) {
4091         RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay global merge topRcdNode dirty "
4092                 "%{public}s, global dirty %{public}s, add rect %{public}s",
4093             std::to_string(curDisplayNode_->GetScreenId()).c_str(),
4094             curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
4095             dirtyRectTop.ToString().c_str());
4096         curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRectTop);
4097     }
4098     if (RSSingleton<RoundCornerDisplayManager>::GetInstance().HandleRoundCornerDirtyRect(
4099             curDisplayNode_->GetId(), dirtyRectBottom, RoundCornerDisplayManager::RCDLayerType::BOTTOM)) {
4100         RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay global merge bottomRcdNode dirty "
4101                 "%{public}s, global dirty %{public}s, add rect %{public}s",
4102             std::to_string(curDisplayNode_->GetScreenId()).c_str(),
4103             curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
4104             dirtyRectBottom.ToString().c_str());
4105         curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRectBottom);
4106     }
4107 }
4108 
4109 void RSUniRenderVisitor::CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode& node)
4110 {
4111     bool hasAnim = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
4112     if (!node.IsScale() || hasAnim || curCornerRadius_.IsZero() || curAlpha_ < 1) {
4113         node.SetGpuOverDrawBufferOptimizeNode(false);
4114         return;
4115     }
4116 
4117     for (auto& child : *(node.GetChildren())) {
4118         if (!child || !(child->IsInstanceOf<RSSurfaceRenderNode>() &&
4119             RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashOrMainWindow())) {
4120             continue;
4121         }
4122         auto rootNode = child->GetFirstChild();
4123         if (!rootNode) {
4124             break;
4125         }
4126         auto canvasNode = rootNode->GetFirstChild();
4127         if (!canvasNode) {
4128             break;
4129         }
4130         const auto& surfaceProperties = node.GetRenderProperties();
4131         const auto& canvasProperties = canvasNode->GetRenderProperties();
4132         if (canvasProperties.GetAlpha() >= 1
4133             && canvasProperties.GetBackgroundColor().GetAlpha() >= MAX_ALPHA
4134             && canvasProperties.GetFrameWidth() == surfaceProperties.GetFrameWidth()
4135             && canvasProperties.GetFrameHeight() == surfaceProperties.GetFrameHeight()) {
4136             node.SetGpuOverDrawBufferOptimizeNode(true);
4137             node.SetOverDrawBufferNodeCornerRadius(curCornerRadius_);
4138             return;
4139         }
4140     }
4141 
4142     node.SetGpuOverDrawBufferOptimizeNode(false);
4143 }
4144 
4145 void RSUniRenderVisitor::SetHdrWhenMultiDisplayChange()
4146 {
4147     auto mainThread = RSMainThread::Instance();
4148     if (!mainThread->GetMultiDisplayChange()) {
4149         return;
4150     }
4151     auto isMultiDisplay = mainThread->GetMultiDisplayStatus();
4152     RS_LOGI("RSUniRenderVisitor::SetHdrWhenMultiDisplayChange closeHdrStatus: %{public}d.", isMultiDisplay);
4153     RS_TRACE_NAME_FMT("RSUniRenderVisitor::SetHdrWhenMultiDisplayChange closeHdrStatus: %d", isMultiDisplay);
4154     RSLuminanceControl::Get().ForceCloseHdr(CLOSEHDR_SCENEID::MULTI_DISPLAY, isMultiDisplay);
4155 }
4156 
4157 void RSUniRenderVisitor::TryNotifyUIBufferAvailable()
4158 {
4159     for (auto& id : uiBufferAvailableId_) {
4160         const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
4161         auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
4162         if (surfaceNode) {
4163             surfaceNode->NotifyUIBufferAvailable();
4164         }
4165     }
4166     uiBufferAvailableId_.clear();
4167 }
4168 
4169 void RSUniRenderVisitor::CollectSelfDrawingNodeRectInfo(RSSurfaceRenderNode& node)
4170 {
4171     auto& monitor = SelfDrawingNodeMonitor::GetInstance();
4172     if (!monitor.IsListeningEnabled()) {
4173         return;
4174     }
4175 
4176     if (!node.IsSelfDrawingType()) {
4177         return;
4178     }
4179     auto rect = node.GetRenderProperties().GetBoundsGeometry()->GetAbsRect();
4180     std::string nodeName = node.GetName();
4181     monitor.InsertCurRectMap(node.GetId(), nodeName, rect);
4182 }
4183 } // namespace Rosen
4184 } // namespace OHOS
4185