• 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 #include "common/rs_common_def.h"
22 #include "common/rs_common_hook.h"
23 #include "common/rs_obj_abs_geometry.h"
24 #include "common/rs_optional_trace.h"
25 #include "common/rs_singleton.h"
26 #include "feature/dirty/rs_uni_dirty_compute_util.h"
27 #include "feature/hwc/rs_uni_hwc_compute_util.h"
28 #include "feature/occlusion_culling/rs_occlusion_handler.h"
29 #ifdef RS_ENABLE_OVERLAY_DISPLAY
30 #include "feature/overlay_display/rs_overlay_display_manager.h"
31 #endif
32 #include "common/rs_special_layer_manager.h"
33 #include "display_engine/rs_luminance_control.h"
34 #include "feature/drm/rs_drm_util.h"
35 #include "feature/opinc/rs_opinc_cache.h"
36 #include "feature/opinc/rs_opinc_manager.h"
37 #include "feature/hpae/rs_hpae_manager.h"
38 #include "feature/uifirst/rs_sub_thread_manager.h"
39 #include "feature/uifirst/rs_uifirst_manager.h"
40 #include "feature/hdr/rs_hdr_util.h"
41 #include "memory/rs_tag_tracker.h"
42 #include "monitor/self_drawing_node_monitor.h"
43 #include "params/rs_screen_render_params.h"
44 #include "pipeline/render_thread/rs_base_render_util.h"
45 #include "pipeline/render_thread/rs_uni_render_util.h"
46 #include "pipeline/render_thread/rs_uni_render_virtual_processor.h"
47 #include "pipeline/rs_base_render_node.h"
48 #include "pipeline/rs_screen_render_node.h"
49 #include "pipeline/rs_effect_render_node.h"
50 #include "pipeline/rs_logical_display_render_node.h"
51 #include "pipeline/rs_paint_filter_canvas.h"
52 #include "pipeline/rs_pointer_window_manager.h"
53 #include "pipeline/hardware_thread/rs_realtime_refresh_rate_manager.h"
54 #include "pipeline/rs_root_render_node.h"
55 #include "pipeline/rs_surface_render_node.h"
56 #include "pipeline/hwc/rs_uni_hwc_visitor.h"
57 #include "platform/common/rs_log.h"
58 #include "platform/common/rs_system_properties.h"
59 #include "property/rs_properties_painter.h"
60 #include "render/rs_effect_luminance_manager.h"
61 #include "system/rs_system_parameters.h"
62 #include "hgm_core.h"
63 #include "metadata_helper.h"
64 #include <v1_0/buffer_handle_meta_key_type.h>
65 #include <v1_0/cm_color_space.h>
66 
67 #include "feature_cfg/graphic_feature_param_manager.h"
68 #include "feature/round_corner_display/rs_round_corner_display_manager.h"
69 #include "feature/round_corner_display/rs_message_bus.h"
70 
71 #include "rs_profiler.h"
72 #ifdef SUBTREE_PARALLEL_ENABLE
73 #include "rs_parallel_manager.h"
74 #endif
75 
76 #ifdef RS_PROFILER_ENABLED
77 #include "rs_profiler_capture_recorder.h"
78 #endif
79 
80 // blur predict
81 #include "rs_frame_blur_predict.h"
82 
83 #undef LOG_TAG
84 #define LOG_TAG "RSUniRenderVisitor"
85 
86 namespace OHOS {
87 namespace Rosen {
88 namespace {
89 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
90 constexpr int EXPAND_ONE_PIX = 1;
91 constexpr int MAX_ALPHA = 255;
92 constexpr int TRACE_LEVEL_THREE = 3;
93 constexpr float EPSILON_SCALE = 0.00001f;
94 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
95 constexpr uint64_t INPUT_HWC_LAYERS = 3;
96 constexpr int TRACE_LEVEL_PRINT_NODEID = 6;
97 
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)98 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
99 {
100     if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
101         auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
102         const auto& property = rootNode->GetRenderProperties();
103         if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
104             return true;
105         }
106     }
107     return false;
108 }
109 
CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)110 bool CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
111 {
112     if (child != nullptr && child->IsInstanceOf<RSCanvasRenderNode>()) {
113         auto canvasRenderNode = child->ReinterpretCastTo<RSCanvasRenderNode>();
114         const auto& property = canvasRenderNode->GetRenderProperties();
115         if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0) {
116             return true;
117         }
118     }
119     return false;
120 }
121 
IsFirstFrameReadyToDraw(const RSSurfaceRenderNode & node)122 bool IsFirstFrameReadyToDraw(const RSSurfaceRenderNode& node)
123 {
124     bool result = false;
125     auto sortedChildren = node.GetSortedChildren();
126     if (node.IsScbScreen()) {
127         for (const auto& child : *sortedChildren) {
128             result = CheckScbReadyToDraw(child);
129         }
130         return result;
131     }
132     for (auto& child : *sortedChildren) {
133         result = CheckRootNodeReadyToDraw(child);
134         // when appWindow has abilityComponent node
135         if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
136             for (const auto& surfaceNodeChild : *child->GetSortedChildren()) {
137                 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
138             }
139         }
140     }
141     return result;
142 }
143 
VisibleDataToString(const VisibleData & val)144 std::string VisibleDataToString(const VisibleData& val)
145 {
146     std::stringstream ss;
147     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
148     for (const auto& v : val) {
149         auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(v.first);
150         auto name = surfaceNode ? surfaceNode->GetName() : "";
151         ss << "[" << name << ", " << v.first << ", " << v.second << "], ";
152     }
153     return ss.str();
154 }
155 
156 } // namespace
157 
158 bool RSUniRenderVisitor::isLastFrameRotating_ = false;
159 
RSUniRenderVisitor()160 RSUniRenderVisitor::RSUniRenderVisitor()
161     : hwcVisitor_(std::make_unique<RSUniHwcVisitor>(*this)),
162       curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
163 {
164     PartialRenderOptionInit();
165     auto mainThread = RSMainThread::Instance();
166     renderEngine_ = mainThread->GetRenderEngine();
167     hasMirrorDisplay_ = mainThread->HasMirrorDisplay();
168     // when occlusion enabled is false, subTree do not skip, but not influence visible region
169     isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
170     isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
171     RSTagTracker::UpdateReleaseResourceEnabled(RSSystemProperties::GetReleaseResourceEnabled());
172 #ifdef DDGR_ENABLE_FEATURE_OPINC
173     autoCacheEnable_ = RSOpincManager::Instance().GetOPIncSwitch();
174 #endif
175     isScreenRotationAnimating_ = RSSystemProperties::GetCacheEnabledForRotation();
176     isFirstFrameAfterScreenRotation_ = !isScreenRotationAnimating_ && isLastFrameRotating_;
177     isLastFrameRotating_ = isScreenRotationAnimating_;
178 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
179     if (renderEngine_ && renderEngine_->GetRenderContext()) {
180         auto subThreadManager = RSSubThreadManager::Instance();
181         subThreadManager->Start(renderEngine_->GetRenderContext().get());
182     }
183 #endif
184     isUIFirstDebugEnable_ = RSSystemProperties::GetUIFirstDebugEnabled();
185     isCrossNodeOffscreenOn_ = RSSystemProperties::GetCrossNodeOffScreenStatus();
186     isDumpRsTreeDetailEnabled_ = RSSystemProperties::GetDumpRsTreeDetailEnabled();
187     screenManager_ = CreateOrGetScreenManager();
188 }
189 
~RSUniRenderVisitor()190 RSUniRenderVisitor::~RSUniRenderVisitor() {}
191 
PartialRenderOptionInit()192 void RSUniRenderVisitor::PartialRenderOptionInit()
193 {
194     isPartialRenderEnabled_ = DirtyRegionParam::IsDirtyRegionEnable();
195     isAdvancedDirtyRegionEnabled_ = DirtyRegionParam::IsAdvancedDirtyRegionEnable();
196     isDirtyAlignEnabled_ = DirtyRegionParam::IsTileBasedAlignEnable();
197 
198     if (RSSystemProperties::GetStencilPixelOcclusionCullingEnabled() == StencilPixelOcclusionCullingType::DEFAULT) {
199         isStencilPixelOcclusionCullingEnabled_ =
200             OcclusionCullingParam::IsStencilPixelOcclusionCullingEnable();
201     } else {
202         isStencilPixelOcclusionCullingEnabled_ =
203             RSSystemProperties::GetStencilPixelOcclusionCullingEnabled() != StencilPixelOcclusionCullingType::DISABLED;
204     }
205 
206     partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
207     isPartialRenderEnabled_ &= (partialRenderType_ > PartialRenderType::DISABLED);
208 
209     isCompleteRenderEnabled_ = (partialRenderType_ == PartialRenderType::SET_DAMAGE_BUT_COMPLETE_RENDER);
210     dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
211     surfaceRegionDebugType_ = RSSystemProperties::GetSurfaceRegionDfxType();
212     isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_) &&
213         (surfaceRegionDebugType_ == SurfaceRegionDebugType::DISABLED);
214     isTargetUIFirstDfxEnabled_ = RSSystemProperties::GetTargetUIFirstDfxEnabled(dfxUIFirstSurfaceNames_);
215     isRegionDebugEnabled_ = (dirtyRegionDebugType_ != DirtyRegionDebugType::DISABLED) ||
216         (surfaceRegionDebugType_ != SurfaceRegionDebugType::DISABLED) || (dfxTargetSurfaceNames_.size() > 0);
217     isVisibleRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::VISIBLE_REGION);
218     isOpaqueRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::OPAQUE_REGION);
219     isAllSurfaceVisibleDebugEnabled_ = RSSystemProperties::GetAllSurfaceVisibleDebugEnabled();
220     isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
221         (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
222     isDisplayDirtyDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
223         (dirtyRegionDebugType_ == DirtyRegionDebugType::DISPLAY_DIRTY);
224     isMergedDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
225         (dirtyRegionDebugType_ == DirtyRegionDebugType::MERGED_DIRTY);
226     isOpDropped_ = isPartialRenderEnabled_ &&
227         (partialRenderType_ != PartialRenderType::SET_DAMAGE) && !isRegionDebugEnabled_;
228     isVirtualDirtyDfxEnabled_ = RSSystemProperties::GetVirtualDirtyDebugEnabled();
229     isVirtualDirtyEnabled_ = RSSystemProperties::GetVirtualDirtyEnabled() &&
230         (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) && !isRegionDebugEnabled_;
231     isExpandScreenDirtyEnabled_ = RSSystemProperties::GetExpandScreenDirtyEnabled();
232     advancedDirtyType_ = isAdvancedDirtyRegionEnabled_ ?
233         RSSystemProperties::GetAdvancedDirtyRegionEnabled() : AdvancedDirtyRegionType::DISABLED;
234     isDirtyAlignEnabled_ &= RSSystemProperties::GetDirtyAlignEnabled() != DirtyAlignType::DISABLED;
235     if (isStencilPixelOcclusionCullingEnabled_) {
236         // SPOC relies on dirty region alignment; when SPOC is enabled, dirty region alignment must also be enabled
237         isDirtyAlignEnabled_ = true;
238     }
239 }
240 
MergeRemovedChildDirtyRegion(RSRenderNode & node,bool needMap)241 void RSUniRenderVisitor::MergeRemovedChildDirtyRegion(RSRenderNode& node, bool needMap)
242 {
243     RectI dirtyRect = RSSystemProperties::GetOptimizeParentNodeRegionEnabled() ?
244         node.GetRemovedChildrenRect() : node.GetChildrenRect();
245     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curScreenDirtyManager_;
246     if (dirtyManager == nullptr || dirtyRect.IsEmpty()) {
247         node.ResetHasRemovedChild();
248         return;
249     }
250 
251     // [planning] merge removed child's rect instead
252     if (needMap) {
253         if (auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry()) {
254             dirtyRect = geoPtr->MapRect(dirtyRect.ConvertTo<float>(), node.GetOldAbsMatrix());
255         }
256         if (!node.HasChildrenOutOfRect()) {
257             dirtyRect = dirtyRect.IntersectRect(node.GetOldClipRect());
258         }
259     } else {
260         dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
261     }
262     dirtyManager->MergeDirtyRect(dirtyRect);
263     RS_OPTIONAL_TRACE_NAME_FMT("MergeRemovedChildDirtyRegion NodeId:%" PRIu64 ", dirty rect:%s",
264         node.GetId(), dirtyRect.ToString().c_str());
265     if (dirtyManager->IsTargetForDfx()) {
266         // since childRect includes multiple rects, defaultly marked as canvas_node
267         dirtyManager->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
268             DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
269     }
270     node.ResetHasRemovedChild();
271 }
272 
CheckColorSpace(RSSurfaceRenderNode & node)273 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
274 {
275     if (!node.IsAppWindow()) {
276         return;
277     }
278     if (!curScreenNode_) {
279         RS_LOGD("CheckColorSpace: curScreenNode_ is nullptr");
280         return;
281     }
282     GraphicColorGamut gamut = node.GetColorSpace();
283     if (gamut != GRAPHIC_COLOR_GAMUT_SRGB) {
284         curScreenNode_->UpdateColorSpace(gamut);
285         RS_LOGD("CheckColorSpace: node(%{public}s) set new colorgamut %{public}d",
286             node.GetName().c_str(), static_cast<int>(gamut));
287     }
288 }
289 
CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode & node)290 void RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode& node)
291 {
292     if (!node.IsOnTheTree()) {
293         RS_LOGD("CheckColorSpaceWithSelfDrawingNode node(%{public}s) is not on the tree",
294             node.GetName().c_str());
295         return;
296     }
297     if (!node.IsHardwareForcedDisabled()) {
298         RS_LOGD("CheckColorSpaceWithSelfDrawingNode node(%{public}s) is hardware-enabled",
299             node.GetName().c_str());
300         return;
301     }
302     if (curScreenNode_ == nullptr) {
303         RS_LOGD("CheckColorSpaceWithSelfDrawingNode curScreenNode_ is nullptr");
304         return;
305     }
306     // currently, P3 is the only supported wide color gamut, this may be modified later.
307     node.UpdateColorSpaceWithMetadata();
308     auto appSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetInstanceRootNode());
309     if (ColorGamutParam::SkipOccludedNodeDuringColorGamutCollection() && appSurfaceNode
310         && appSurfaceNode->IsMainWindowType() && appSurfaceNode->GetVisibleRegion().IsEmpty() && GetIsOpDropped()) {
311         RS_LOGD("CheckColorSpaceWithSelfDrawingNode node(%{public}s) failed to set new color "
312                 "gamut because the window is blocked", node.GetName().c_str());
313         return;
314     }
315 
316     GraphicColorGamut gamut = node.GetColorSpace();
317     if (gamut != GRAPHIC_COLOR_GAMUT_SRGB) {
318         curScreenNode_->UpdateColorSpace(gamut);
319         RS_LOGD("CheckColorSpaceWithSelfDrawingNode node(%{public}s) set new colorgamut %{public}d",
320             node.GetName().c_str(), static_cast<int>(gamut));
321     }
322 }
323 
UpdateColorSpaceAfterHwcCalc(RSScreenRenderNode & node)324 void RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc(RSScreenRenderNode& node)
325 {
326     auto colorSpace = node.GetColorSpace();
327     const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
328     for (const auto& selfDrawingNode : selfDrawingNodes) {
329         if (!selfDrawingNode) {
330             RS_LOGD("UpdateColorSpaceAfterHwcCalc selfDrawingNode is nullptr");
331             continue;
332         }
333         auto ancestorNode = selfDrawingNode->GetAncestorScreenNode().lock();
334         if (!ancestorNode) {
335             RS_LOGD("UpdateColorSpaceAfterHwcCalc ancestorNode is nullptr");
336             continue;
337         }
338         auto ancestorScreenNode = ancestorNode->ReinterpretCastTo<RSScreenRenderNode>();
339         if (ancestorScreenNode != nullptr && node.GetId() == ancestorScreenNode->GetId()) {
340             CheckColorSpaceWithSelfDrawingNode(*selfDrawingNode);
341         }
342     }
343 }
344 
IsScreenSupportedWideColorGamut(ScreenId id,const sptr<RSScreenManager> & screenManager)345 bool IsScreenSupportedWideColorGamut(ScreenId id, const sptr<RSScreenManager>& screenManager)
346 {
347     std::vector<ScreenColorGamut> supportedColorGamut;
348     if (screenManager->GetScreenSupportedColorGamuts(id, supportedColorGamut) != SUCCESS) {
349         return false;
350     }
351     for (auto item : supportedColorGamut) {
352         if (item == ScreenColorGamut::COLOR_GAMUT_DCI_P3 || item == ScreenColorGamut::COLOR_GAMUT_DISPLAY_P3) {
353             return true;
354         }
355     }
356     return false;
357 }
358 
HandleColorGamuts(RSScreenRenderNode & node)359 void RSUniRenderVisitor::HandleColorGamuts(RSScreenRenderNode& node)
360 {
361     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
362     if (screenManager_->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
363         RS_LOGD("HandleColorGamuts get screen type failed.");
364         return;
365     }
366 
367     if (screenType == VIRTUAL_TYPE_SCREEN) {
368         ScreenColorGamut screenColorGamut;
369         if (screenManager_->GetScreenColorGamut(node.GetScreenId(), screenColorGamut) != SUCCESS) {
370             RS_LOGD("HandleColorGamuts get screen color gamut failed.");
371             return;
372         }
373         node.SetColorSpace(static_cast<GraphicColorGamut>(screenColorGamut));
374         return;
375     } else if (ColorGamutParam::DisableP3OnWiredExtendedScreen() &&
376         !RSMainThread::Instance()->HasWiredMirrorDisplay() && node.GetScreenId() != 0) {
377         // Current PC external screen do not support P3.
378         // The wired extended screen is fixed to sRGB color space.
379         node.SetColorSpace(GRAPHIC_COLOR_GAMUT_SRGB);
380         return;
381     }
382     std::vector<ScreenColorGamut> mode;
383     int32_t ret = screenManager_->GetScreenSupportedColorGamuts(node.GetScreenId(), mode);
384     if (ret != SUCCESS) {
385         RS_LOGD("HandleColorGamuts GetScreenSupportedColorGamuts failed, ret=%{public}d", ret);
386         mode = std::vector<ScreenColorGamut>{GRAPHIC_COLOR_GAMUT_SRGB};
387     }
388     node.SelectBestGamut(mode);
389 
390     if (RSMainThread::Instance()->HasWiredMirrorDisplay() && !MultiScreenParam::IsMirrorDisplayCloseP3()) {
391         std::shared_ptr<RSScreenRenderNode> mirrorNode = node.GetMirrorSource().lock();
392         if (!mirrorNode) {
393             return;
394         }
395         std::vector<ScreenColorGamut> mode;
396         int32_t ret = screenManager_->GetScreenSupportedColorGamuts(node.GetScreenId(), mode);
397         if (ret != SUCCESS) {
398             RS_LOGD("HandleColorGamuts GetScreenSupportedColorGamuts failed, errorCode=%{public}d",
399                 ret);
400             return;
401         }
402         bool isSupportedDisplayP3 =
403             std::any_of(mode.begin(), mode.end(), [](const auto& gamut) { return gamut == COLOR_GAMUT_DISPLAY_P3; });
404         if (isSupportedDisplayP3) {
405             // wired mirror and mirror support P3, mirror gamut = main gamut
406             node.SetColorSpace(mirrorNode->GetColorSpace());
407         }
408     }
409 }
410 
CheckPixelFormat(RSSurfaceRenderNode & node)411 void RSUniRenderVisitor::CheckPixelFormat(RSSurfaceRenderNode& node)
412 {
413     if (hasFingerprint_) {
414         RS_LOGD("CheckPixelFormat hasFingerprint is true.");
415         return;
416     }
417     if (!curScreenNode_) {
418         RS_LOGE("CheckPixelFormat curScreenNode is null");
419         return;
420     }
421     if (node.GetFingerprint()) {
422         hasFingerprint_ = true;
423         curScreenNode_->SetPixelFormat(GRAPHIC_PIXEL_FMT_RGBA_1010102);
424         RS_LOGD("CheckPixelFormat newPixelFormate_ is set 1010102 for fingerprint.");
425         return;
426     }
427     if (!RSSystemProperties::GetHdrImageEnabled()) {
428         RS_LOGD("CheckPixelFormat HdrImageEnabled false");
429         return;
430     }
431     if (curScreenNode_->GetForceCloseHdr()) {
432         RS_LOGD("CheckPixelFormat curScreenNode_ forceclosehdr.");
433         return;
434     }
435     if (node.GetHDRPresent() || node.IsHdrEffectColorGamut()) {
436         RS_LOGD("CheckPixelFormat HDRService SetHDRPresent true, surfaceNode: %{public}" PRIu64 "",
437             node.GetId());
438         curScreenNode_->SetHasUniRenderHdrSurface(true);
439         if (node.GetHDRPresent()) {
440             curScreenNode_->CollectHdrStatus(HdrStatus::HDR_PHOTO);
441         }
442         if (node.IsHdrEffectColorGamut()) {
443             curScreenNode_->CollectHdrStatus(HdrStatus::HDR_EFFECT);
444         }
445         RSHdrUtil::SetHDRParam(*curScreenNode_, node, true);
446     }
447 }
448 
HandlePixelFormat(RSScreenRenderNode & node)449 void RSUniRenderVisitor::HandlePixelFormat(RSScreenRenderNode& node)
450 {
451     if (!curScreenNode_) {
452         RS_LOGE("HandlePixelFormat curScreenNode is null");
453         return;
454     }
455     SetHdrWhenMultiDisplayChange();
456     RS_LOGD("HDRSwitch isHdrImageEnabled: %{public}d, isHdrVideoEnabled: %{public}d",
457         RSSystemProperties::GetHdrImageEnabled(), RSSystemProperties::GetHdrVideoEnabled());
458     ScreenId screenId = node.GetScreenId();
459     bool hasUniRenderHdrSurface = node.GetHasUniRenderHdrSurface();
460     if ((RSLuminanceControl::Get().IsCloseHardwareHdr() && !drmNodes_.empty()) || node.GetForceCloseHdr()) {
461         // Disable hdr when drm videos exist to avoid flicker
462         RSLuminanceControl::Get().SetHdrStatus(screenId, HdrStatus::NO_HDR);
463     } else {
464         RSLuminanceControl::Get().SetHdrStatus(screenId, node.GetDisplayHdrStatus());
465     }
466     bool isHdrOn = RSLuminanceControl::Get().IsHdrOn(screenId);
467     rsHdrCollection_->HandleHdrState(isHdrOn);
468     float brightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
469     float displayHeadroom =
470         RSLuminanceControl::Get().GetDisplayNits(screenId) / RSLuminanceControl::Get().GetSdrDisplayNits(screenId);
471     RSEffectLuminanceManager::GetInstance().SetDisplayHeadroom(node.GetScreenNodeId(), displayHeadroom);
472     RS_TRACE_NAME_FMT("HDR:%d, in Unirender:%d, brightnessRatio:%f, screenId:%" PRIu64 ", status:%d", isHdrOn,
473         hasUniRenderHdrSurface, brightnessRatio, screenId, node.GetDisplayHdrStatus());
474     RS_LOGD("HandlePixelFormat HDRService isHdrOn:%{public}d hasUniRenderHdrSurface:%{public}d "
475         "brightnessRatio:%{public}f screenId:%{public}" PRIu64 " status:%{public}d", isHdrOn, hasUniRenderHdrSurface,
476         brightnessRatio, screenId, node.GetDisplayHdrStatus());
477     if ((!hasUniRenderHdrSurface && !RSLuminanceControl::Get().IsCloseHardwareHdr()) || node.GetForceCloseHdr()) {
478         isHdrOn = false;
479     }
480     node.SetHDRPresent(isHdrOn);
481     hasDisplayHdrOn_ |= isHdrOn;
482     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
483     if (screenManager_->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
484         RS_LOGD("HandlePixelFormat get screen type failed.");
485         return;
486     }
487 
488     RSHdrUtil::HandleVirtualScreenHDRStatus(node, screenManager_);
489 
490     if (screenType == VIRTUAL_TYPE_SCREEN) {
491         auto pixelFormat = node.GetPixelFormat();
492         if (screenManager_->GetPixelFormat(node.GetScreenId(), pixelFormat) != SUCCESS) {
493             RS_LOGD("HandlePixelFormat get screen color gamut failed.");
494         } else {
495             node.SetPixelFormat(pixelFormat);
496         }
497     }
498 }
499 
ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode & node)500 void RSUniRenderVisitor::ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode& node)
501 {
502     // record current frame mainwindow or leashwindow node
503     if (node.IsMainWindowType() || node.IsLeashWindow()) {
504         curMainAndLeashWindowNodesIds_.push(node.GetId());
505         RSMainThread::Instance()->GetRSVsyncRateReduceManager().PushWindowNodeId(node.GetId());
506         curScreenNode_->RecordMainAndLeashSurfaces(node.shared_from_this());
507     }
508     // only reset for instance node
509     if (curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetId()) {
510         return;
511     }
512     if (auto directParent = node.GetParent().lock()) {
513         if (auto parentInstance = directParent->GetInstanceRootNode()) {
514             // in case leashwindow is not directParent
515             auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
516             if (surfaceParent && (surfaceParent->IsLeashOrMainWindow())) {
517                 curSurfaceNode_ = surfaceParent;
518                 curSurfaceDirtyManager_ = surfaceParent->GetDirtyManager();
519                 filterInGlobal_ = surfaceParent->IsTransparent();
520                 return;
521             }
522             curSurfaceNode_ = nullptr;
523             curSurfaceDirtyManager_ = nullptr;
524             filterInGlobal_ = true;
525         }
526     }
527 }
528 
IsHardwareComposerEnabled()529 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
530 {
531     return !hwcVisitor_->isHardwareForcedDisabled_;
532 }
533 
MarkHardwareForcedDisabled()534 void RSUniRenderVisitor::MarkHardwareForcedDisabled()
535 {
536     hwcVisitor_->isHardwareForcedDisabled_ = true;
537 }
538 
DealWithSpecialLayer(RSSurfaceRenderNode & node)539 void RSUniRenderVisitor::DealWithSpecialLayer(RSSurfaceRenderNode& node)
540 {
541     if (node.IsCloneCrossNode()) {
542         auto sourceNode = node.GetSourceCrossNode().lock();
543         auto sourceSurface = sourceNode ? sourceNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
544         if (sourceSurface == nullptr) {
545             return;
546         }
547         UpdateSpecialLayersRecord(*sourceSurface);
548     } else {
549         UpdateSpecialLayersRecord(node);
550     }
551     UpdateBlackListRecord(node);
552     node.UpdateVirtualScreenWhiteListInfo(screenWhiteList_);
553 }
554 
UpdateBlackListRecord(RSSurfaceRenderNode & node)555 void RSUniRenderVisitor::UpdateBlackListRecord(RSSurfaceRenderNode& node)
556 {
557     if (!hasMirrorDisplay_ || !screenManager_) {
558         return;
559     }
560     std::unordered_set<uint64_t> virtualScreens = screenManager_->GetBlackListVirtualScreenByNode(node.GetId());
561     if (node.IsLeashWindow()) {
562         const auto& leashVirtualScreens = screenManager_->GetBlackListVirtualScreenByNode(node.GetLeashPersistentId());
563         virtualScreens.insert(leashVirtualScreens.begin(), leashVirtualScreens.end());
564     }
565     if (virtualScreens.empty()) {
566         node.UpdateBlackListStatus(INVALID_SCREEN_ID, false);
567         return;
568     }
569     for (const auto& screenId : virtualScreens) {
570         node.UpdateBlackListStatus(screenId, true);
571     }
572 }
573 
UpdateSpecialLayersRecord(RSSurfaceRenderNode & node)574 void RSUniRenderVisitor::UpdateSpecialLayersRecord(RSSurfaceRenderNode& node)
575 {
576     if (node.ShouldPaint() == false) {
577         return;
578     }
579     auto specialLayerMgr = node.GetMultableSpecialLayerMgr();
580     if (specialLayerMgr.Find(SpecialLayerType::HAS_SECURITY)) {
581         curLogicalDisplayNode_->AddSecurityLayer(node.IsLeashWindow() ? node.GetLeashPersistentId() : node.GetId());
582         curLogicalDisplayNode_->AddSecurityVisibleLayer(node.GetId());
583     }
584     if (specialLayerMgr.Find(SpecialLayerType::HAS_PROTECTED)) {
585         screenManager_->SetScreenHasProtectedLayer(curLogicalDisplayNode_->GetScreenId(), true);
586         RS_TRACE_NAME_FMT("SetScreenHasProtectedLayer: %d", curLogicalDisplayNode_->GetScreenId());
587     }
588     auto specialLayerType = specialLayerMgr.Get();
589     if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
590         specialLayerType &= ~SpecialLayerType::HAS_SKIP;
591     }
592     curLogicalDisplayNode_->GetMultableSpecialLayerMgr().AddIds((specialLayerType >> SPECIAL_TYPE_NUM), node.GetId());
593     if (node.IsSpecialLayerChanged()) {
594         curLogicalDisplayNode_->SetDisplaySpecialSurfaceChanged(true);
595     }
596 }
597 
UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode & node)598 void RSUniRenderVisitor::UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode& node)
599 {
600     if (!node.IsMainWindowType()) {
601         return;
602     }
603     auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
604     if (!geoPtr) {
605         return;
606     }
607     if (RSUniRenderUtil::GetRotationDegreeFromMatrix(geoPtr->GetAbsMatrix()) % RS_ROTATION_90 != 0) {
608         node.SetIsRotating(true);
609     }
610 }
611 
IsSubTreeOccluded(RSRenderNode & node) const612 bool RSUniRenderVisitor::IsSubTreeOccluded(RSRenderNode& node) const
613 {
614     if (!isOcclusionEnabled_) {
615         return false;
616     }
617     // step1. apply occlusion info for surfacenode and skip fully covered subtree
618     if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
619         auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
620         if (surfaceNode.IsMainWindowType()) {
621             RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::IsSubTreeOccluded node[%s]"
622                 "name:[%s] visibleRegionIsEmpty[%d]",
623                 std::to_string(node.GetId()).c_str(), surfaceNode.GetName().c_str(),
624                 surfaceNode.GetVisibleRegion().IsEmpty());
625             auto isOccluded = hasMirrorDisplay_ ?
626                 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
627             isOccluded = isOccluded && (!RSUifirstManager::Instance().IsSubTreeNeedPrepareForSnapshot(surfaceNode));
628             if (isOccluded && curSurfaceDirtyManager_) {
629                 curSurfaceDirtyManager_->Clear();
630             }
631             surfaceNode.AccumulateDirtyInOcclusion(isOccluded);
632             return isOccluded;
633         }
634     }
635     // step2.1 For partial visible surface, intersected region->rects in surface
636     // step2.2 check if clean subtree in occlusion rects
637     return false;
638 }
639 
ResetDisplayDirtyRegion()640 void RSUniRenderVisitor::ResetDisplayDirtyRegion()
641 {
642     if (!curScreenDirtyManager_) {
643         return;
644     }
645     if (curScreenNode_ == nullptr || screenManager_ == nullptr) {
646         return;
647     }
648     bool ret = CheckScreenPowerChange() ||
649         CheckCurtainScreenUsingStatusChange() ||
650         curScreenDirtyManager_->GetEnabledChanged() ||
651         IsWatermarkFlagChanged() ||
652         zoomStateChange_ ||
653         isCompleteRenderEnabled_ ||
654         curScreenNode_->GetIsLuminanceStatusChange() ||
655         IsFirstFrameOfOverdrawSwitch() ||
656         IsFirstFrameOfDrawingCacheDfxSwitch() ||
657         IsAccessibilityConfigChanged() ||
658         curScreenNode_->HasMirroredScreenChanged() ||
659         screenManager_->CheckPSurfaceChanged(curScreenNode_->GetScreenId());
660 
661 #ifdef RS_ENABLE_OVERLAY_DISPLAY
662     // if overlay display status changed, ......
663     ret = ret || RSOverlayDisplayManager::Instance().CheckStatusChanged();
664 #endif
665     if (ret) {
666         curScreenDirtyManager_->ResetDirtyAsSurfaceSize();
667         RS_LOGD("ResetDisplayDirtyRegion on");
668     }
669 }
670 
IsAccessibilityConfigChanged() const671 bool RSUniRenderVisitor::IsAccessibilityConfigChanged() const
672 {
673     return RSMainThread::Instance()->IsAccessibilityConfigChanged();
674 }
675 
CheckScreenPowerChange() const676 bool RSUniRenderVisitor::CheckScreenPowerChange() const
677 {
678     if (!RSMainThread::Instance()->GetScreenPowerOnChanged()) {
679         return false;
680     }
681     RS_LOGD("CheckScreenPowerChange changed");
682     return true;
683 }
684 
CheckCurtainScreenUsingStatusChange() const685 bool RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange() const
686 {
687     if (!RSMainThread::Instance()->IsCurtainScreenUsingStatusChanged()) {
688         return false;
689     }
690     RS_LOGD("CheckCurtainScreenUsingStatusChange changed");
691     return true;
692 }
693 
CheckLuminanceStatusChange(ScreenId id)694 bool RSUniRenderVisitor::CheckLuminanceStatusChange(ScreenId id)
695 {
696     // ExchangeLuminanceChangingStatus will be reset false after called in one frame
697     // Use isLuminanceStatusChange_ if need call this function multiple times in one frame
698     if (!RSMainThread::Instance()->ExchangeLuminanceChangingStatus(id)) {
699         return false;
700     }
701     curScreenNode_->SetIsLuminanceStatusChange(true);
702     RS_LOGD("CheckLuminanceStatusChange changed");
703     return true;
704 }
705 
IsFirstFrameOfDrawingCacheDfxSwitch() const706 bool RSUniRenderVisitor::IsFirstFrameOfDrawingCacheDfxSwitch() const
707 {
708     return RSMainThread::Instance()->IsFirstFrameOfDrawingCacheDFXSwitch();
709 }
710 
IsFirstFrameOfOverdrawSwitch() const711 bool RSUniRenderVisitor::IsFirstFrameOfOverdrawSwitch() const
712 {
713     if (!RSMainThread::Instance()->IsFirstFrameOfOverdrawSwitch()) {
714         return false;
715     }
716     RS_LOGD("IsFirstFrameOfOverdrawSwitch");
717     return true;
718 }
719 
IsWatermarkFlagChanged() const720 bool RSUniRenderVisitor::IsWatermarkFlagChanged() const
721 {
722     if (RSMainThread::Instance()->IsWatermarkFlagChanged()) {
723         RS_LOGD("FirstOrLastFrameOfWatermark");
724         return true;
725     } else {
726         return false;
727     }
728 }
729 
UpdateDisplayZoomState()730 void RSUniRenderVisitor::UpdateDisplayZoomState()
731 {
732     if (!curScreenNode_) {
733         zoomStateChange_ = false;
734         return;
735     }
736     auto scale = curScreenNode_->GetRenderProperties().GetScale();
737     bool curZoomState = scale.x_ > 1.f || scale.y_ > 1.f;
738     curScreenNode_->UpdateZoomState(curZoomState);
739     zoomStateChange_ = curZoomState || curScreenNode_->IsZoomStateChange();
740 }
741 
UpdateVirtualDisplayInfo(RSLogicalDisplayRenderNode & node)742 void RSUniRenderVisitor::UpdateVirtualDisplayInfo(RSLogicalDisplayRenderNode& node)
743 {
744     // only for virtual screen
745     if (!node.IsMirrorDisplay()) {
746         node.ClearSecurityLayerList();
747         node.ClearSecurityVisibleLayerList();
748         return;
749     }
750     auto mirrorNode = node.GetMirrorSource().lock();
751     if (mirrorNode == nullptr || screenManager_ == nullptr) {
752         return;
753     }
754 
755     UpdateVirtualDisplaySecurityExemption(node, *mirrorNode);
756     UpdateVirtualDisplayVisibleRectSecurity(node, *mirrorNode);
757 }
758 
UpdateVirtualDisplaySecurityExemption(RSLogicalDisplayRenderNode & node,RSLogicalDisplayRenderNode & mirrorNode)759 void RSUniRenderVisitor::UpdateVirtualDisplaySecurityExemption(RSLogicalDisplayRenderNode& node,
760     RSLogicalDisplayRenderNode& mirrorNode)
761 {
762     auto securityExemptionList = screenManager_->GetVirtualScreenSecurityExemptionList(node.GetScreenId());
763     if (securityExemptionList.size() == 0) {
764         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:false",
765             node.GetId());
766         node.SetSecurityExemption(false);
767         return;
768     }
769     auto securityLayerList = mirrorNode.GetSecurityLayerList();
770     for (const auto& exemptionLayer : securityExemptionList) {
771         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64
772             " securityExemption nodeId %{public}" PRIu64 ".", node.GetId(), exemptionLayer);
773     }
774     for (const auto& secLayer : securityLayerList) {
775         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64
776             " securityLayer nodeId %{public}" PRIu64 ".", mirrorNode.GetId(), secLayer);
777     }
778     bool isSecurityExemption = false;
779     if (securityExemptionList.size() >= securityLayerList.size()) {
780         isSecurityExemption = true;
781         for (const auto& secLayer : securityLayerList) {
782             if (std::find(securityExemptionList.begin(), securityExemptionList.end(), secLayer) ==
783                 securityExemptionList.end()) {
784                 isSecurityExemption = false;
785                 break;
786             }
787         }
788     }
789     RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:%{public}d",
790         node.GetId(), isSecurityExemption);
791     node.SetSecurityExemption(isSecurityExemption);
792 }
793 
UpdateVirtualDisplayVisibleRectSecurity(RSLogicalDisplayRenderNode & node,RSLogicalDisplayRenderNode & mirrorNode)794 void RSUniRenderVisitor::UpdateVirtualDisplayVisibleRectSecurity(RSLogicalDisplayRenderNode& node,
795     RSLogicalDisplayRenderNode& mirrorNode)
796 {
797     if (!curScreenNode_->GetScreenInfo().enableVisibleRect) {
798         return;
799     }
800     auto rect = screenManager_->GetMirrorScreenVisibleRect(node.GetScreenId());
801     RectI visibleRect(rect.x, rect.y, rect.w, rect.h);
802     auto securityVisibleLayerList = mirrorNode.GetSecurityVisibleLayerList();
803     bool hasSecLayerInVisibleRect = false;
804     for (const auto& secLayerId : securityVisibleLayerList) {
805         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
806             RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode(secLayerId));
807         if (surfaceNode == nullptr) {
808             continue;
809         }
810         const auto& dstRect = surfaceNode->GetDstRect();
811         if (dstRect.Intersect(visibleRect)) {
812             hasSecLayerInVisibleRect = true;
813             break;
814         }
815     }
816     RS_LOGD("%{public}s: hasSecLayerInVisibleRect:%{public}d.", __func__, hasSecLayerInVisibleRect);
817     node.SetHasSecLayerInVisibleRect(hasSecLayerInVisibleRect);
818 }
819 
UpdateCurFrameInfoDetail(RSRenderNode & node,bool subTreeSkipped,bool isPostPrepare)820 void RSUniRenderVisitor::UpdateCurFrameInfoDetail(RSRenderNode& node, bool subTreeSkipped, bool isPostPrepare)
821 {
822     if (GetDumpRsTreeDetailEnabled()) {
823         auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
824         curFrameInfoDetail.curFrameVsyncId = HgmCore::Instance().GetVsyncId();
825         curFrameInfoDetail.curFrameSubTreeSkipped = subTreeSkipped;
826         if (isPostPrepare) {
827             curFrameInfoDetail.curFramePostPrepareSeqNum = IncreasePostPrepareSeq();
828         } else {
829             curFrameInfoDetail.curFramePrepareSeqNum = IncreasePrepareSeq();
830         }
831     }
832 }
833 
QuickPrepareScreenRenderNode(RSScreenRenderNode & node)834 void RSUniRenderVisitor::QuickPrepareScreenRenderNode(RSScreenRenderNode& node)
835 {
836     RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "QuickPrepareScreenRenderNode nodeId[%llu]", node.GetId());
837     UpdateCurFrameInfoDetail(node);
838     // 0. init display info
839     RS_TRACE_NAME("RSUniRender:QuickPrepareScreenRenderNode " + std::to_string(node.GetScreenId()));
840     if (!InitScreenInfo(node)) {
841         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
842         return;
843     }
844     UpdateDisplayZoomState();
845     SendRcdMessage(node);
846     ancestorNodeHasAnimation_ = false;
847     dirtyFlag_ = isDirty_ || zoomStateChange_ || curScreenDirtyManager_->IsActiveSurfaceRectChanged() ||
848         curScreenDirtyManager_->IsSurfaceRectChanged() || node.IsDirty();
849     if (dirtyFlag_) {
850         RS_TRACE_NAME_FMT("need recalculate dirty region");
851         RS_LOGD("need recalculate dirty region");
852     }
853     prepareClipRect_ = curScreenNode_->GetScreenRect();
854     hasAccumulatedClip_ = false;
855 
856     globalShouldPaint_ = true;
857     curAlpha_ = 1.0f;
858     globalZOrder_ = 0.0f;
859     appWindowZOrder_ = 0;
860     hasSkipLayer_ = false;
861     hwcVisitor_->curZOrderForHwcEnableByFilter_ = 0;
862     node.GetHwcRecorder().SetZOrderForHwcEnableByFilter(hwcVisitor_->curZOrderForHwcEnableByFilter_++);
863     if (!(RSMainThread::Instance()->IsRequestedNextVSync())) {
864         RS_OPTIONAL_TRACE_NAME_FMT("do not request next vsync");
865         needRequestNextVsync_ = false;
866     }
867 
868     rsScreenNodeChildNum_ = 0;
869     RSHdrUtil::LuminanceChangeSetDirty(node);
870     QuickPrepareChildren(node);
871     TryNotifyUIBufferAvailable();
872 
873     PostPrepare(node);
874     UpdateCompositeType(node);
875     hwcVisitor_->UpdateHwcNodeEnable();
876     UpdateSurfaceDirtyAndGlobalDirty();
877     UpdateSurfaceOcclusionInfo();
878     if (needRecalculateOcclusion_) {
879         // Callback for registered self drawing surfacenode
880         RSMainThread::Instance()->SurfaceOcclusionCallback();
881     }
882     curScreenNode_->UpdatePartialRenderParams();
883     curScreenNode_->SetFingerprint(hasFingerprint_);
884     curScreenNode_->UpdateScreenRenderParams();
885     UpdateColorSpaceAfterHwcCalc(node);
886     RSHdrUtil::UpdatePixelFormatAfterHwcCalc(node);
887 
888 #ifdef SUBTREE_PARALLEL_ENABLE
889     RSParallelManager::Singleton().HitPolicy(node);
890 #endif
891 
892     HandleColorGamuts(node);
893     HandlePixelFormat(node);
894     if (UNLIKELY(!SharedTransitionParam::unpairedShareTransitions_.empty())) {
895         ProcessUnpairedSharedTransitionNode();
896     }
897     node.HandleCurMainAndLeashSurfaceNodes();
898     layerNum_ += node.GetSurfaceCountForMultiLayersPerf();
899     node.RenderTraceDebug();
900     curScreenNode_->ResetMirroredScreenChangedFlag();
901     PrepareForMultiScreenViewDisplayNode(node);
902     node.ResetDirtyFlag();
903     RS_TRACE_NAME_FMT("RSUniRenderVisitor::QuickPrepareScreenRenderNode childNumber: %d", rsScreenNodeChildNum_);
904     RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
905 }
906 
InitLogicalDisplayInfo(RSLogicalDisplayRenderNode & node)907 bool RSUniRenderVisitor::InitLogicalDisplayInfo(RSLogicalDisplayRenderNode& node)
908 {
909     curLogicalDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSLogicalDisplayRenderNode>();
910     curLogicalDisplayNode_->SetDisplaySpecialSurfaceChanged(false);
911     curLogicalDisplayNode_->GetMultableSpecialLayerMgr().Set(HAS_GENERAL_SPECIAL, false);
912     curLogicalDisplayNode_->SetCompositeType(curScreenNode_->GetCompositeType());
913     curLogicalDisplayNode_->SetHasCaptureWindow(false);
914     occlusionSurfaceOrder_ = TOP_OCCLUSION_SURFACES_NUM;
915     auto mirrorSourceNode = curLogicalDisplayNode_->GetMirrorSource().lock();
916     auto mirrorSourceScreenNode = mirrorSourceNode ?
917         std::static_pointer_cast<RSScreenRenderNode>(mirrorSourceNode->GetParent().lock()) : nullptr;
918     if (mirrorSourceScreenNode) {
919         curScreenNode_->SetIsMirrorScreen(true);
920         curScreenNode_->SetMirrorSource(mirrorSourceScreenNode);
921     } else {
922         curScreenNode_->SetIsMirrorScreen(false);
923         curScreenNode_->ResetMirrorSource();
924     }
925     curScreenNode_->GetLogicalDisplayNodeDrawables().push_back(curLogicalDisplayNode_->GetRenderDrawable());
926     return true;
927 }
928 
QuickPrepareLogicalDisplayRenderNode(RSLogicalDisplayRenderNode & node)929 void RSUniRenderVisitor::QuickPrepareLogicalDisplayRenderNode(RSLogicalDisplayRenderNode& node)
930 {
931     RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID,
932         "QuickPrepareLogicalDisplayRenderNode nodeId[%llu]", node.GetId());
933     RS_TRACE_NAME("RSUniRender:QuickPrepareLogicalDisplayRenderNode " + std::to_string(node.GetScreenId()));
934     UpdateCurFrameInfoDetail(node);
935     if (!InitLogicalDisplayInfo(node)) {
936         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
937         return;
938     }
939     // 0. check ......
940     auto dirtyManager = curScreenDirtyManager_;
941     if (!dirtyManager) {
942         RS_LOGE("QuickPrepareLogicalDisplayRenderNode dirtyManager is nullptr");
943         return;
944     }
945     UpdateVirtualDisplayInfo(node);
946     auto dirtyFlag = dirtyFlag_;
947     displayNodeRotationChanged_ = node.IsRotationChanged();
948     dirtyFlag_ |= displayNodeRotationChanged_;
949     auto prevAlpha = curAlpha_;
950     auto curCornerRadius = curCornerRadius_;
951     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
952     auto preGlobalShouldPaint = globalShouldPaint_;
953     globalShouldPaint_ &= node.ShouldPaint();
954     CheckFilterCacheNeedForceClearOrSave(node);
955     RectI prepareClipRect = prepareClipRect_;
956     bool hasAccumulatedClip = hasAccumulatedClip_;
957     dirtyFlag_ =
958         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
959     node.UpdateCurCornerRadius(curCornerRadius_);
960     node.UpdateRotation();
961     RSUifirstManager::Instance().PreStatusProcess(displayNodeRotationChanged_ || isScreenRotationAnimating_);
962 
963     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
964     QuickPrepareChildren(node);
965 
966     PostPrepare(node);
967     prepareClipRect_ = prepareClipRect;
968     hasAccumulatedClip_ = hasAccumulatedClip;
969     dirtyFlag_ = dirtyFlag;
970     curAlpha_ = prevAlpha;
971     curCornerRadius_ = curCornerRadius;
972     globalShouldPaint_ = preGlobalShouldPaint;
973     node.UpdateOffscreenRenderParams(node.IsRotationChanged());
974     node.RenderTraceDebug();
975     RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
976 }
977 
CheckFilterCacheNeedForceClearOrSave(RSRenderNode & node)978 void RSUniRenderVisitor::CheckFilterCacheNeedForceClearOrSave(RSRenderNode& node)
979 {
980     if (!node.HasBlurFilter()) {
981         return;
982     }
983     bool rotationChanged = curLogicalDisplayNode_ ?
984         curLogicalDisplayNode_->IsRotationChanged() || curLogicalDisplayNode_->IsLastRotationChanged() : false;
985     bool rotationStatusChanged = curLogicalDisplayNode_ ?
986         curLogicalDisplayNode_->GetPreRotationStatus() != curLogicalDisplayNode_->GetCurRotationStatus() : false;
987     node.CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
988 }
989 
PrepareForSkippedCrossNode(RSSurfaceRenderNode & surfaceNode)990 void RSUniRenderVisitor::PrepareForSkippedCrossNode(RSSurfaceRenderNode& surfaceNode)
991 {
992     // 1. Find the actual surface node of which the coordinates must be recalculated.
993     auto sourceNode = surfaceNode.GetSourceCrossNode().lock();
994     auto sourceSurface = sourceNode ? sourceNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
995     RSSurfaceRenderNode& nodeRef = sourceSurface ? *sourceSurface : surfaceNode;
996     auto geoPtr = nodeRef.GetRenderProperties().GetBoundsGeometry();
997     if (!geoPtr) {
998         return;
999     }
1000     // 2. Get the AbsMatrix under current display node. Concatenate current parent matrix and nodeRef relative matrix.
1001     Drawing::Matrix nodeAbsMatrix = geoPtr->GetMatrix();
1002     if (nodeRef.GetGlobalPositionEnabled()) {
1003         nodeAbsMatrix.PostTranslate(-curScreenNode_->GetScreenOffsetX(), -curScreenNode_->GetScreenOffsetY());
1004     }
1005     if (auto parent = surfaceNode.GetParent().lock()) {
1006         auto parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
1007         nodeAbsMatrix.PostConcat(parentGeoPtr ? parentGeoPtr->GetAbsMatrix() : Drawing::Matrix());
1008     }
1009     // 3. Get the conversion matrix from first display coordinate system to current display coordinate system.
1010     // 3.1 Invert AbsMatrix under first display.
1011     // 3.2 Apply AbsMatrix under second display.
1012     Drawing::Matrix conversionMatrix;
1013     if (!geoPtr->GetAbsMatrix().Invert(conversionMatrix)) {
1014         curScreenDirtyManager_->ResetDirtyAsSurfaceSize();
1015         RS_LOGW("Cross-Node matrix inverting for %{public}s failed, set full screen dirty.", nodeRef.GetName().c_str());
1016         return;
1017     }
1018     conversionMatrix.PostConcat(nodeAbsMatrix);
1019 
1020     // 4. record this surface node and its position on second display, for global dirty region conversion.
1021     curScreenNode_->RecordMainAndLeashSurfaces(nodeRef.shared_from_this());
1022     nodeRef.UpdateCrossNodeSkipDisplayConversionMatrices(curScreenNode_->GetId(), conversionMatrix);
1023     RectI surfaceRect =
1024         geoPtr->MapRect(nodeRef.GetOldDirty().ConvertTo<float>(), conversionMatrix)
1025             .IntersectRect(curScreenNode_->GetScreenRect());
1026     curScreenNode_->UpdateSurfaceNodePos(nodeRef.GetId(), surfaceRect);
1027     curScreenNode_->AddSurfaceNodePosByDescZOrder(nodeRef.GetId(), surfaceRect);
1028     // 5. record all children surface nodes and their position on second display, for global dirty region conversion.
1029     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
1030     nodeRef.GetAllSubSurfaceNodes(allSubSurfaceNodes);
1031     for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
1032         if (auto childPtr = subSurfaceNode.lock()) {
1033             curScreenNode_->RecordMainAndLeashSurfaces(childPtr);
1034             childPtr->SetFirstLevelCrossNode(nodeRef.IsFirstLevelCrossNode());
1035             childPtr->UpdateCrossNodeSkipDisplayConversionMatrices(curScreenNode_->GetId(), conversionMatrix);
1036             RectI childSurfaceRect = geoPtr->MapRect(
1037                 childPtr->GetOldDirty().ConvertTo<float>(), conversionMatrix)
1038                     .IntersectRect(curScreenNode_->GetScreenRect());
1039             curScreenNode_->UpdateSurfaceNodePos(childPtr->GetId(), childSurfaceRect);
1040             curScreenNode_->AddSurfaceNodePosByDescZOrder(childPtr->GetId(), childSurfaceRect);
1041         }
1042     }
1043 }
1044 
CheckSkipAndPrepareForCrossNode(RSSurfaceRenderNode & node)1045 bool RSUniRenderVisitor::CheckSkipAndPrepareForCrossNode(RSSurfaceRenderNode& node)
1046 {
1047     auto sourceRenderNode = node.GetSourceCrossNode().lock();
1048     RSSurfaceRenderNode::SharedPtr sourceNode = sourceRenderNode ?
1049         sourceRenderNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1050     // CloneCrossNode must have a source node.
1051     if (node.IsCloneCrossNode() && sourceNode == nullptr) {
1052         RS_LOGE("QuickPrepareSurfaceRenderNode source node of clone node %{public}"
1053             PRIu64 " is null", node.GetId());
1054         return true;
1055     }
1056 
1057     // skip CrossNode not on first display
1058     if (CheckSkipCrossNode(node)) {
1059         // when skip cloneCrossNode prepare, we need switch to record sourceNode dirty info
1060         PrepareForSkippedCrossNode(node);
1061         return true;
1062     }
1063 
1064     // when prepare CloneCrossNode on first display, we need switch to prepare sourceNode.
1065     if (node.IsCloneCrossNode()) {
1066         isSwitchToSourceCrossNodePrepare_ = true;
1067         sourceNode->SetCurCloneNodeParent(node.GetParent().lock());
1068         sourceNode->SetFirstLevelCrossNode(true);
1069         sourceNode->QuickPrepare(shared_from_this());
1070         sourceNode->SetCurCloneNodeParent(nullptr);
1071         isSwitchToSourceCrossNodePrepare_ = false;
1072         return true;
1073     }
1074     return false;
1075 }
1076 
CheckIfSkipDrawInVirtualScreen(RSSurfaceRenderNode & node)1077 bool RSUniRenderVisitor::CheckIfSkipDrawInVirtualScreen(RSSurfaceRenderNode& node)
1078 {
1079     //if node special layer type is skip drawing, return true
1080     if (node.GetSpecialLayerMgr().Find(SpecialLayerType::SKIP) ||
1081         allBlackList_.find(node.GetId()) != allBlackList_.end() ||
1082         allBlackList_.find(node.GetLeashPersistentId()) != allBlackList_.end()) {
1083         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::CheckIfSkipDrawInVirtualScreen:[%{public}s] "
1084             "nodeid:[%{public}" PRIu64 "], set isSkipDrawInVirtualScreen_ true", node.GetName().c_str(), node.GetId());
1085         return true;
1086     }
1087     return false;
1088 }
1089 
QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode & node)1090 void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
1091 {
1092     RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "QuickPrepareSurfaceRenderNode nodeId[%llu]", node.GetId());
1093     UpdateCurFrameInfoDetail(node);
1094     RS_TRACE_NAME_FMT("RSUniRender::QuickPrepare:[%s] nodeId[%" PRIu64 "] pid[%d] nodeType[%u]"
1095         " subTreeDirty[%d], crossDisplay:[%d]", node.GetName().c_str(), node.GetId(), ExtractPid(node.GetId()),
1096         static_cast<uint>(node.GetSurfaceNodeType()), node.IsSubTreeDirty(), node.IsFirstLevelCrossNode());
1097     RS_LOGD("RSUniRender::QuickPrepareSurfaceRenderNode:[%{public}s] nodeid:[%{public}" PRIu64 "] pid:[%{public}d] "
1098         "nodeType:[%{public}d] subTreeDirty[%{public}d] crossDisplay[%{public}d]", node.GetName().c_str(), node.GetId(),
1099         ExtractPid(node.GetId()), static_cast<int>(node.GetSurfaceNodeType()), node.IsSubTreeDirty(),
1100         node.IsFirstLevelCrossNode());
1101 
1102     if (PrepareForCloneNode(node)) {
1103         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1104         return;
1105     }
1106 
1107     // AppWindow is traversed in reverse order
1108     // Prepare operation will be executed first when the node is at the top level
1109     // The value of appWindowZOrder_ decreases from 0 to negative
1110     if (node.IsAppWindow()) {
1111         node.SetAppWindowZOrder(appWindowZOrder_--);
1112     }
1113 
1114     // avoid cross node subtree visited twice or more
1115     DealWithSpecialLayer(node);
1116     if (CheckSkipAndPrepareForCrossNode(node)) {
1117         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1118         return;
1119     }
1120     // 0. init curSurface info and check node info
1121     auto curCornerRadius = curCornerRadius_;
1122     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
1123     if (!BeforeUpdateSurfaceDirtyCalc(node)) {
1124         RS_LOGE("QuickPrepareSurfaceRenderNode BeforeUpdateSurfaceDirtyCalc fail");
1125         RSUifirstManager::Instance().DisableUifirstNode(node);
1126         node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1127         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1128         return;
1129     }
1130 
1131     if (curSurfaceDirtyManager_ == nullptr) {
1132         RS_LOGE("QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
1133             node.GetName().c_str());
1134         node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1135         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1136         return;
1137     }
1138     curSurfaceDirtyManager_->SetAdvancedDirtyRegionType(advancedDirtyType_);
1139 
1140     // 1. Update matrix and collect dirty region
1141     auto dirtyFlag = dirtyFlag_;
1142     auto prepareClipRect = prepareClipRect_;
1143     bool hasAccumulatedClip = hasAccumulatedClip_;
1144     auto prevAlpha = curAlpha_;
1145     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1146     node.SetGlobalAlpha(curAlpha_);
1147     auto preGlobalShouldPaint = globalShouldPaint_;
1148     globalShouldPaint_ &= node.ShouldPaint();
1149     node.SetSelfAndParentShouldPaint(globalShouldPaint_);
1150     CheckFilterCacheNeedForceClearOrSave(node);
1151     MarkFilterInForegroundFilterAndCheckNeedForceClearCache(node);
1152     node.CheckContainerDirtyStatusAndUpdateDirty(curContainerDirty_);
1153     node.ClearCrossNodeSkipDisplayConversionMatrices();
1154     auto& screenInfo = curScreenNode_->GetScreenInfo();
1155     node.SetPreparedDisplayOffsetX(screenInfo.offsetX);
1156     node.SetPreparedDisplayOffsetY(screenInfo.offsetY);
1157     if (node.GetGlobalPositionEnabled()) {
1158         parentSurfaceNodeMatrix_.Translate(-screenInfo.offsetX, -screenInfo.offsetY);
1159     }
1160 
1161     dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
1162         *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix);
1163     auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
1164     if (!geoPtr) {
1165         node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1166         globalShouldPaint_ = preGlobalShouldPaint;
1167         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1168         return;
1169     }
1170     parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
1171     if (!AfterUpdateSurfaceDirtyCalc(node)) {
1172         RS_LOGE("QuickPrepareSurfaceRenderNode AfterUpdateSurfaceDirtyCalc fail");
1173         RSUifirstManager::Instance().DisableUifirstNode(node);
1174         node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1175         globalShouldPaint_ = preGlobalShouldPaint;
1176         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1177         return;
1178     }
1179     bool isDimmingOn = RSLuminanceControl::Get().IsDimmingOn(curScreenNode_->GetScreenId());
1180     if (isDimmingOn) {
1181         bool hasHdrPresent = node.GetHDRPresent();
1182         bool hasHdrVideo = node.GetVideoHdrStatus() != HdrStatus::NO_HDR;
1183         RS_LOGD("HDRDiming IsDimmingOn: %{public}d, GetHDRPresent: %{public}d, GetHdrVideo: %{public}d",
1184             isDimmingOn, hasHdrPresent, hasHdrVideo);
1185         if (hasHdrPresent || hasHdrVideo) {
1186             node.SetContentDirty(); // HDR content is dirty on Dimming status.
1187         }
1188     }
1189 #ifdef SUBTREE_PARALLEL_ENABLE
1190     const bool isInFocusSurface = isInFocusSurface_;
1191     isInFocusSurface_ = node.IsFocusedNode(currentFocusedNodeId_) ||
1192         node.IsFocusedNode(focusedLeashWindowId_) || isInFocusSurface_;
1193 #endif
1194     CollectSelfDrawingNodeRectInfo(node);
1195     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1196     // Initialize the handler of control-level occlusion culling.
1197     InitializeOcclusionHandler(node);
1198     bool preIsSkipDraw = isSkipDrawInVirtualScreen_;
1199     isSkipDrawInVirtualScreen_ = isSkipDrawInVirtualScreen_ || CheckIfSkipDrawInVirtualScreen(node);
1200     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_, IsSubTreeOccluded(node)) ||
1201         ForcePrepareSubTree();
1202     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1203         node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
1204     if (curSurfaceDirtyManager_ == nullptr) {
1205         RS_LOGE("QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager "
1206             "is set to nullptr by QuickPrepareChildren", node.GetName().c_str());
1207         node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1208         globalShouldPaint_ = preGlobalShouldPaint;
1209         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1210         return;
1211     }
1212     if (!node.IsFirstLevelCrossNode()) {
1213         curSurfaceDirtyManager_->ClipDirtyRectWithinSurface();
1214     }
1215     auto dirtyRect = node.GetDirtyManager()->GetCurrentFrameDirtyRegion();
1216     RS_LOGD("QuickPrepare [%{public}s, %{public}" PRIu64 "] DirtyRect[%{public}d, %{public}d, %{public}d, %{public}d]",
1217         node.GetName().c_str(), node.GetId(), dirtyRect.GetLeft(), dirtyRect.GetTop(), dirtyRect.GetWidth(),
1218         dirtyRect.GetHeight());
1219 
1220     RSUifirstManager::Instance().RecordDirtyRegionMatrix(node, geoPtr->GetAbsMatrix());
1221 
1222     if (node.IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()) {
1223         CheckIsGpuOverDrawBufferOptimizeNode(node);
1224     }
1225     PostPrepare(node, !isSubTreeNeedPrepare);
1226     if (node.IsHardwareEnabledTopSurface() && node.shared_from_this()) {
1227         RSUniHwcComputeUtil::UpdateHwcNodeProperty(node.shared_from_this()->ReinterpretCastTo<RSSurfaceRenderNode>());
1228     }
1229     CalculateOpaqueAndTransparentRegion(node);
1230     curAlpha_ = prevAlpha;
1231     globalShouldPaint_ = preGlobalShouldPaint;
1232     prepareClipRect_ = prepareClipRect;
1233     hasAccumulatedClip_ = hasAccumulatedClip;
1234     dirtyFlag_ = dirtyFlag;
1235     isSkipDrawInVirtualScreen_ = preIsSkipDraw;
1236     PrepareForUIFirstNode(node);
1237     PrepareForCrossNode(node);
1238 #ifdef SUBTREE_PARALLEL_ENABLE
1239     if (node.GetSubThreadAssignable() || !isInFocusSurface_) {
1240         node.ClearSubtreeParallelNodes();
1241     }
1242     isInFocusSurface_ = isInFocusSurface;
1243 #endif
1244     node.UpdateInfoForClonedNode(clonedSourceNodeId_);
1245     node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1246     ResetCurSurfaceInfoAsUpperSurfaceParent(node);
1247     curCornerRadius_ = curCornerRadius;
1248     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
1249 
1250     // [Attention] Only used in PC window resize scene now
1251     windowKeyFrameNodeInf_.PrepareRootNodeOffscreen(node);
1252 
1253     node.RenderTraceDebug();
1254     node.SetNeedOffscreen(isScreenRotationAnimating_);
1255     if (node.NeedUpdateDrawableBehindWindow()) {
1256         node.UpdateDrawableBehindWindow();
1257         node.SetOldNeedDrawBehindWindow(node.NeedDrawBehindWindow());
1258     }
1259     if (node.IsUIBufferAvailable()) {
1260         uiBufferAvailableId_.emplace_back(node.GetId());
1261     }
1262     HandleTunnelLayerId(node);
1263     PrepareForMultiScreenViewSurfaceNode(node);
1264     RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1265 }
1266 
PrepareForMultiScreenViewSurfaceNode(RSSurfaceRenderNode & node)1267 void RSUniRenderVisitor::PrepareForMultiScreenViewSurfaceNode(RSSurfaceRenderNode& node)
1268 {
1269     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1270     auto sourceNode = nodeMap.GetRenderNode<RSScreenRenderNode>(node.GetSourceDisplayRenderNodeId());
1271     if (!sourceNode) {
1272         return;
1273     }
1274     node.SetContentDirty();
1275     sourceNode->SetTargetSurfaceRenderNodeId(node.GetId());
1276     auto sourceNodeDrawable = sourceNode->GetRenderDrawable();
1277     if (!sourceNodeDrawable) {
1278         return;
1279     }
1280     RS_TRACE_NAME_FMT("PrepareForMultiScreenViewSurfaceNode surfaceNodeId: %llu sourceVirtualDisplayId: %llu",
1281         node.GetId(), node.GetSourceDisplayRenderNodeId());
1282     node.SetSourceDisplayRenderNodeDrawable(sourceNodeDrawable);
1283 }
1284 
PrepareForMultiScreenViewDisplayNode(RSScreenRenderNode & node)1285 void RSUniRenderVisitor::PrepareForMultiScreenViewDisplayNode(RSScreenRenderNode& node)
1286 {
1287     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1288     auto targetNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(node.GetTargetSurfaceRenderNodeId());
1289     if (!targetNode) {
1290         return;
1291     }
1292     auto targetRenderNodeDrawable = targetNode->GetRenderDrawable();
1293     if (!targetRenderNodeDrawable) {
1294         return;
1295     }
1296     RS_TRACE_NAME_FMT("PrepareForMultiScreenViewDisplayNode screenNodeId: %llu targetSurfaceRenderNodeId: %llu",
1297         node.GetId(), node.GetTargetSurfaceRenderNodeId());
1298     node.SetTargetSurfaceRenderNodeDrawable(targetRenderNodeDrawable);
1299 }
1300 
PrepareForCloneNode(RSSurfaceRenderNode & node)1301 bool RSUniRenderVisitor::PrepareForCloneNode(RSSurfaceRenderNode& node)
1302 {
1303     if (!node.IsCloneNode() || !node.IsLeashOrMainWindow()) {
1304         return false;
1305     }
1306     RS_LOGD("PrepareForCloneNode %{public}s is cloneNode", node.GetName().c_str());
1307     node.SetIsClonedNodeOnTheTree(false);
1308     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1309     auto clonedNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(node.GetClonedNodeId());
1310     if (clonedNode == nullptr) {
1311         RS_LOGE("PrepareForCloneNode clonedNode is nullptr");
1312         return false;
1313     }
1314     if (!clonedNode->IsMainWindowType()) {
1315         return false;
1316     }
1317     auto clonedNodeRenderDrawable = clonedNode->GetRenderDrawable();
1318     if (clonedNodeRenderDrawable == nullptr) {
1319         RS_LOGE("PrepareForCloneNode clonedNodeRenderDrawable is nullptr");
1320         return false;
1321     }
1322     node.SetIsClonedNodeOnTheTree(clonedNode->IsOnTheTree());
1323     clonedSourceNodeId_ = node.GetClonedNodeId();
1324     node.SetClonedNodeRenderDrawable(clonedNodeRenderDrawable);
1325     node.UpdateRenderParams();
1326     node.AddToPendingSyncList();
1327     return true;
1328 }
1329 
PrepareForCrossNode(RSSurfaceRenderNode & node)1330 void RSUniRenderVisitor::PrepareForCrossNode(RSSurfaceRenderNode& node)
1331 {
1332     if (isCrossNodeOffscreenOn_ == CrossNodeOffScreenRenderDebugType::DISABLED) {
1333         return;
1334     }
1335     if (curLogicalDisplayNode_ == nullptr) {
1336         RS_LOGE("%{public}s curScreenNode_ is nullptr", __func__);
1337         return;
1338     }
1339     if (curScreenNode_->IsFirstVisitCrossNodeDisplay() && node.IsCrossNode()) {
1340         // check surface cache condition, not support ratation, transparent filter situation.
1341         bool needCacheSurface = node.QuerySubAssignable(curLogicalDisplayNode_->IsRotationChanged());
1342         if (needCacheSurface) {
1343             node.SetHwcChildrenDisabledState();
1344             RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " children disabled by crossNode",
1345                 node.GetName().c_str(), node.GetId());
1346         }
1347         node.SetNeedCacheSurface(needCacheSurface);
1348     }
1349 }
1350 
CheckSkipCrossNode(RSSurfaceRenderNode & node)1351 bool RSUniRenderVisitor::CheckSkipCrossNode(RSSurfaceRenderNode& node)
1352 {
1353     if (!node.IsCrossNode() || isSwitchToSourceCrossNodePrepare_) {
1354         return false;
1355     }
1356     if (curScreenNode_ == nullptr) {
1357         RS_LOGE("%{public}s curScreenNode_ is nullptr", __func__);
1358         return false;
1359     }
1360     node.SetCrossNodeOffScreenStatus(isCrossNodeOffscreenOn_);
1361     curScreenNode_->SetHasChildCrossNode(true);
1362     if (node.HasVisitedCrossNode()) {
1363         RS_OPTIONAL_TRACE_NAME_FMT("%s cross node[%s] skip", __func__, node.GetName().c_str());
1364         return true;
1365     }
1366     curScreenNode_->SetIsFirstVisitCrossNodeDisplay(true);
1367     node.SetCrossNodeVisitedStatus(true);
1368     // If there are n source cross screen nodes, they will enter n times. size of hasVisitedCrossNodeIds_.() is n.
1369     hasVisitedCrossNodeIds_.push_back(node.GetId());
1370     return false;
1371 }
1372 
ResetCrossNodesVisitedStatus()1373 void RSUniRenderVisitor::ResetCrossNodesVisitedStatus()
1374 {
1375     if (hasVisitedCrossNodeIds_.empty()) {
1376         return;
1377     }
1378     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1379     for (NodeId& nodeId : hasVisitedCrossNodeIds_) {
1380         auto visitedNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(nodeId);
1381         if (!visitedNode) {
1382             RS_LOGE("%{public}s visitedNode is nullptr NodeId[%{public}" PRIu64 "]", __func__, nodeId);
1383             continue;
1384         }
1385         RS_LOGD("%{public}s NodeId[%{public}" PRIu64 "]", __func__, nodeId);
1386         visitedNode->SetCrossNodeVisitedStatus(false);
1387     }
1388     hasVisitedCrossNodeIds_.clear();
1389 }
1390 
GetSurfaceTransparentFilterRegion(const RSSurfaceRenderNode & surfaceNode) const1391 Occlusion::Region RSUniRenderVisitor::GetSurfaceTransparentFilterRegion(const RSSurfaceRenderNode& surfaceNode) const
1392 {
1393     Occlusion::Region surfaceTransparentFilterRegion;
1394     if (!surfaceNode.IsTransparent()) {
1395         return surfaceTransparentFilterRegion;
1396     }
1397     if (auto surfaceDirtyManager = surfaceNode.GetDirtyManager()) {
1398         auto& filterList = surfaceDirtyManager->GetFilterCollector().GetFilterDirtyRegionInfoList(false);
1399         std::for_each(filterList.begin(), filterList.end(), [&](const FilterDirtyRegionInfo& filterInfo) {
1400             surfaceTransparentFilterRegion.OrSelf(filterInfo.filterDirty_);
1401         });
1402     }
1403     return surfaceTransparentFilterRegion;
1404 }
1405 
CollectTopOcclusionSurfacesInfo(RSSurfaceRenderNode & node,bool isParticipateInOcclusion)1406 void RSUniRenderVisitor::CollectTopOcclusionSurfacesInfo(RSSurfaceRenderNode& node, bool isParticipateInOcclusion)
1407 {
1408     if (!isStencilPixelOcclusionCullingEnabled_ || occlusionSurfaceOrder_ <= DEFAULT_OCCLUSION_SURFACE_ORDER ||
1409         node.IsFirstLevelCrossNode()) {
1410         return;
1411     }
1412     if (curLogicalDisplayNode_ == nullptr) {
1413         RS_LOGE("%s: curLogicalDisplayNode_ is nullptr", __func__);
1414         return;
1415     }
1416     auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1417     if (!parent || !parent->IsLeashWindow()) {
1418         return;
1419     }
1420     auto stencilVal = occlusionSurfaceOrder_ * OCCLUSION_ENABLE_SCENE_NUM;
1421     // When the transparent blur region overlaps with the collected opaque regions,
1422     // the underlying applications beneath the transparent blur cannot participate in occlusion culling.
1423     if (occlusionSurfaceOrder_ < TOP_OCCLUSION_SURFACES_NUM && node.IsTransparent() &&
1424         !GetSurfaceTransparentFilterRegion(node).And(
1425             curLogicalDisplayNode_->GetTopSurfaceOpaqueRegion()).IsEmpty()) {
1426         RS_OPTIONAL_TRACE_NAME_FMT("%s: %s's transparent filter terminate spoc, current occlusion surface "
1427             "order: %" PRId16, "", __func__, node.GetName().c_str(), occlusionSurfaceOrder_);
1428         occlusionSurfaceOrder_ = DEFAULT_OCCLUSION_SURFACE_ORDER;
1429     }
1430     auto opaqueRegionRects = node.GetOpaqueRegion().GetRegionRects();
1431     if (!isParticipateInOcclusion || opaqueRegionRects.empty()) {
1432         ++stencilVal;
1433         RS_OPTIONAL_TRACE_NAME_FMT("%s: %s set stencil[%d]", __func__,
1434             node.GetName().c_str(), static_cast<int>(stencilVal));
1435         parent->SetStencilVal(stencilVal);
1436         return;
1437     }
1438     parent->SetStencilVal(stencilVal);
1439     if (occlusionSurfaceOrder_ > 0) {
1440         auto maxOpaqueRect = std::max_element(opaqueRegionRects.begin(), opaqueRegionRects.end(),
1441             [](Occlusion::Rect a, Occlusion::Rect b) ->bool { return a.Area() < b.Area(); });
1442         RS_OPTIONAL_TRACE_NAME_FMT("%s: record name[%s] rect[%s] stencil[%d]", __func__,
1443             node.GetName().c_str(), maxOpaqueRect->GetRectInfo().c_str(), static_cast<int>(stencilVal));
1444         curLogicalDisplayNode_->RecordTopSurfaceOpaqueRects(*maxOpaqueRect);
1445         --occlusionSurfaceOrder_;
1446     }
1447 }
1448 
PrepareForUIFirstNode(RSSurfaceRenderNode & node)1449 CM_INLINE void RSUniRenderVisitor::PrepareForUIFirstNode(RSSurfaceRenderNode& node)
1450 {
1451     RSUifirstManager::Instance().MarkSubHighPriorityType(node);
1452     if (isTargetUIFirstDfxEnabled_) {
1453         auto isTargetUIFirstDfxSurface = CheckIfSurfaceForUIFirstDFX(node.GetName());
1454         if (!node.isTargetUIFirstDfxEnabled_ && isTargetUIFirstDfxSurface) {
1455             RS_LOGD("UIFirstDFX Name[%{public}s] ID[%{public}" PRIu64 "] OpenDebug",
1456                 node.GetName().c_str(), node.GetId());
1457         }
1458         node.isTargetUIFirstDfxEnabled_ = isTargetUIFirstDfxSurface;
1459     }
1460     RSUifirstManager::Instance().UpdateUifirstNodes(node, ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation());
1461     RSUifirstManager::Instance().RecordScreenRect(node, curScreenNode_->GetScreenRect());
1462 }
1463 
UpdateNodeVisibleRegion(RSSurfaceRenderNode & node)1464 void RSUniRenderVisitor::UpdateNodeVisibleRegion(RSSurfaceRenderNode& node)
1465 {
1466     if (!curScreenNode_) {
1467         RS_LOGE("UpdateNodeVisibleRegion curScreenNode is nullptr");
1468         return;
1469     }
1470     // occlusion - 0. Calculate node visible region considering accumulated opaque region of upper surface nodes.
1471     if (!curScreenNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) {
1472         RS_LOGD("UpdateNodeVisibleRegion NodeName: %{public}s, NodeId: %{public}" PRIu64
1473             " not paticipate in occlusion when cross node in expand screen", node.GetName().c_str(), node.GetId());
1474         return;
1475     }
1476     Occlusion::Rect selfDrawRect = node.GetSurfaceOcclusionRect(true);
1477     Occlusion::Region selfDrawRegion { selfDrawRect };
1478     needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.CheckIfOcclusionChanged() ||
1479         node.IsBehindWindowOcclusionChanged();
1480     if (needRecalculateOcclusion_) {
1481         Occlusion::Region subResult = selfDrawRegion.Sub(accumulatedOcclusionRegion_);
1482         node.SetVisibleRegion(subResult);
1483         node.SetVisibleRegionBehindWindow(subResult.Sub(accumulatedOcclusionRegionBehindWindow_));
1484         Occlusion::Region subResultWithoutSkipLayer = selfDrawRegion.Sub(occlusionRegionWithoutSkipLayer_);
1485         node.SetVisibleRegionInVirtual(subResultWithoutSkipLayer);
1486     }
1487     RS_OPTIONAL_TRACE_NAME_FMT_LEVEL(TRACE_LEVEL_THREE,
1488         "RSUniRenderVisitor::UpdateNodeVisibleRegion name[%s] visibleRegion[%s] "
1489         "visibleRegionBehindWindow[%s]",
1490         node.GetName().c_str(), node.GetVisibleRegion().GetRegionInfo().c_str(),
1491         node.GetVisibleRegionBehindWindow().GetRegionInfo().c_str());
1492 }
1493 
CalculateOpaqueAndTransparentRegion(RSSurfaceRenderNode & node)1494 CM_INLINE void RSUniRenderVisitor::CalculateOpaqueAndTransparentRegion(RSSurfaceRenderNode& node)
1495 {
1496     if (!curScreenNode_) {
1497         RS_LOGE("CalculateOpaqueAndTransparentRegion curScreenNode is nullptr");
1498         return;
1499     }
1500     // occlusion - 1. Only non-cross-screen main window surface node participate in occlusion.
1501     if ((!curScreenNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) ||
1502         !node.IsMainWindowType()) {
1503         RS_LOGD("CalculateOpaqueAndTransparentRegion Node: %{public}s, NodeId: %{public}" PRIu64
1504             " not paticipate in occlusion", node.GetName().c_str(), node.GetId());
1505         return;
1506     }
1507 
1508     // occlusion - 2. Calculate opaque/transparent region based on round corner, container window, etc.
1509     auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1510     auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
1511         (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
1512     node.CheckAndUpdateOpaqueRegion(curScreenNode_->GetScreenRect(), curLogicalDisplayNode_->GetRotation(), isFocused);
1513     // occlusion - 3. Accumulate opaque region to occlude lower surface nodes (with/without special layer).
1514     hasSkipLayer_ = hasSkipLayer_ || node.GetSpecialLayerMgr().Find(SpecialLayerType::SKIP);
1515     auto mainThread = RSMainThread::Instance();
1516     node.SetOcclusionInSpecificScenes(mainThread->GetIsRegularAnimation());
1517     bool occlusionInAnimation = node.GetOcclusionInSpecificScenes() || !ancestorNodeHasAnimation_;
1518     bool isParticipateInOcclusion = node.CheckParticipateInOcclusion() &&
1519         occlusionInAnimation && !isAllSurfaceVisibleDebugEnabled_ && !node.IsAttractionAnimation();
1520     CollectTopOcclusionSurfacesInfo(node, isParticipateInOcclusion);
1521     if (isParticipateInOcclusion) {
1522         RS_OPTIONAL_TRACE_NAME_FMT("Occlusion: surface node[%s] participate in occlusion with opaque region: [%s]",
1523             node.GetName().c_str(), node.GetOpaqueRegion().GetRegionInfo().c_str());
1524         accumulatedOcclusionRegion_.OrSelf(node.GetOpaqueRegion());
1525         if (node.NeedDrawBehindWindow()) {
1526             accumulatedOcclusionRegionBehindWindow_.OrSelf(Occlusion::Region(Occlusion::Rect(node.GetFilterRect())));
1527         }
1528         if (IsValidInVirtualScreen(node)) {
1529             occlusionRegionWithoutSkipLayer_.OrSelf(node.GetOpaqueRegion());
1530         }
1531     }
1532     needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.CheckIfOcclusionChanged();
1533     node.SetOcclusionInSpecificScenes(false);
1534     CollectOcclusionInfoForWMS(node);
1535     RSMainThread::Instance()->GetRSVsyncRateReduceManager().CollectSurfaceVsyncInfo(
1536         curScreenNode_->GetScreenInfo(), node);
1537 }
1538 
CollectOcclusionInfoForWMS(RSSurfaceRenderNode & node)1539 void RSUniRenderVisitor::CollectOcclusionInfoForWMS(RSSurfaceRenderNode& node)
1540 {
1541     if (!node.IsMainWindowType()) {
1542         return;
1543     }
1544     // collect mainWindow occlusion visibleLevel
1545     Occlusion::Region selfDrawRegion { node.GetSurfaceOcclusionRect(true) };
1546     auto visibleLevel = GetRegionVisibleLevel(node.GetVisibleRegion(), selfDrawRegion);
1547 
1548     // wms default all visible about sefdrawing node and AbilityComponent node
1549     auto instanceNode = node.GetInstanceRootNode() ?
1550         node.GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1551     if (instanceNode == nullptr) {
1552         return;
1553     }
1554     if ((node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
1555          !instanceNode->GetVisibleRegion().IsEmpty()) || node.IsAbilityComponent()) {
1556         dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1557             WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1558         return;
1559     }
1560     dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1561         node.GetVisibleLevelForWMS(visibleLevel)));
1562 }
1563 
SurfaceOcclusionCallbackToWMS()1564 void RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS()
1565 {
1566     if (RSSystemParameters::GetOcclusionCallBackToWMSDebugType()) {
1567         allDstCurVisVec_.clear();
1568         const auto& curAllSurfaces = curScreenNode_->GetAllMainAndLeashSurfaces();
1569         for (const auto& surfacePtr : curAllSurfaces) {
1570             if (surfacePtr == nullptr) {
1571                 continue;
1572             }
1573             const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*surfacePtr);
1574             if (surfaceNode.IsMainWindowType()) {
1575                 allDstCurVisVec_.emplace_back(std::make_pair(surfacePtr->GetId(),
1576                     WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1577             }
1578         }
1579     }
1580     if (allDstCurVisVec_ != allLastVisVec_) {
1581         RSMainThread::Instance()->SurfaceOcclusionChangeCallback(allDstCurVisVec_);
1582         HILOG_COMM_INFO("OcclusionInfo %{public}s", VisibleDataToString(allDstCurVisVec_).c_str());
1583         allLastVisVec_ = std::move(allDstCurVisVec_);
1584     }
1585 }
1586 
GetRegionVisibleLevel(const Occlusion::Region & visibleRegion,const Occlusion::Region & selfDrawRegion)1587 RSVisibleLevel RSUniRenderVisitor::GetRegionVisibleLevel(const Occlusion::Region& visibleRegion,
1588     const Occlusion::Region& selfDrawRegion)
1589 {
1590     if (visibleRegion.IsEmpty()) {
1591         return RSVisibleLevel::RS_INVISIBLE;
1592     } else if (visibleRegion.Area() == selfDrawRegion.Area()) {
1593         return RSVisibleLevel::RS_ALL_VISIBLE;
1594     } else if (static_cast<uint>(visibleRegion.Area()) <
1595         (static_cast<uint>(selfDrawRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
1596         return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
1597     }
1598     return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
1599 }
1600 
QuickPrepareEffectRenderNode(RSEffectRenderNode & node)1601 void RSUniRenderVisitor::QuickPrepareEffectRenderNode(RSEffectRenderNode& node)
1602 {
1603     RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "CheckCacheTypeAndDraw nodeId[%llu]", node.GetId());
1604     UpdateCurFrameInfoDetail(node);
1605     // 0. check current node need to tranverse
1606     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curScreenDirtyManager_;
1607     if (!dirtyManager) {
1608         RS_LOGE("QuickPrepareEffectRenderNode dirtyManager is nullptr");
1609         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1610         return;
1611     }
1612     auto dirtyFlag = dirtyFlag_;
1613     auto prevAlpha = curAlpha_;
1614     auto curCornerRadius = curCornerRadius_;
1615     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1616     UpdateRotationStatusForEffectNode(node);
1617     CheckFilterCacheNeedForceClearOrSave(node);
1618     MarkFilterInForegroundFilterAndCheckNeedForceClearCache(node);
1619     RectI prepareClipRect = prepareClipRect_;
1620     bool hasAccumulatedClip = hasAccumulatedClip_;
1621     dirtyFlag_ =
1622         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1623     node.UpdateCurCornerRadius(curCornerRadius_);
1624     // 1. Recursively traverse child nodes
1625     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1626     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
1627     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1628         node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1629 
1630     PostPrepare(node, !isSubTreeNeedPrepare);
1631     prepareClipRect_ = prepareClipRect;
1632     hasAccumulatedClip_ = hasAccumulatedClip;
1633     dirtyFlag_ = dirtyFlag;
1634     curAlpha_ = prevAlpha;
1635     curCornerRadius_ = curCornerRadius;
1636     node.RenderTraceDebug();
1637     RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1638 }
1639 
MarkFilterInForegroundFilterAndCheckNeedForceClearCache(RSRenderNode & node)1640 void RSUniRenderVisitor::MarkFilterInForegroundFilterAndCheckNeedForceClearCache(RSRenderNode& node)
1641 {
1642     node.MarkFilterInForegroundFilterAndCheckNeedForceClearCache(offscreenCanvasNodeId_);
1643 }
1644 
UpdateDrawingCacheInfoBeforeChildren(RSCanvasRenderNode & node)1645 void RSUniRenderVisitor::UpdateDrawingCacheInfoBeforeChildren(RSCanvasRenderNode& node)
1646 {
1647     if (!isDrawingCacheEnabled_) {
1648         return;
1649     }
1650     node.UpdateDrawingCacheInfoBeforeChildren(isScreenRotationAnimating_);
1651     if (node.GetDrawingCacheType() == RSDrawingCacheType::FOREGROUND_FILTER_CACHE) {
1652         offscreenCanvasNodeId_ = node.GetId();
1653     }
1654 }
1655 
UpdateOffscreenCanvasNodeId(RSCanvasRenderNode & node)1656 void RSUniRenderVisitor::UpdateOffscreenCanvasNodeId(RSCanvasRenderNode& node)
1657 {
1658     if (node.IsForegroundFilterEnable()) {
1659         offscreenCanvasNodeId_ = node.GetId();
1660     }
1661 }
1662 
QuickPrepareCanvasRenderNode(RSCanvasRenderNode & node)1663 void RSUniRenderVisitor::QuickPrepareCanvasRenderNode(RSCanvasRenderNode& node)
1664 {
1665     RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "QuickPrepareCanvasRenderNode nodeId[%llu]", node.GetId());
1666     UpdateCurFrameInfoDetail(node);
1667     // 0. check current node need to traverse
1668     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curScreenDirtyManager_;
1669     auto dirtyFlag = dirtyFlag_;
1670     auto prevAlpha = curAlpha_;
1671     auto curCornerRadius = curCornerRadius_;
1672     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1673     auto preGlobalShouldPaint = globalShouldPaint_;
1674     auto preOffscreenCanvasNodeId = offscreenCanvasNodeId_;
1675     globalShouldPaint_ &= node.ShouldPaint();
1676     CheckFilterCacheNeedForceClearOrSave(node);
1677     bool isAccessibilityConfigChanged = IsAccessibilityConfigChanged();
1678     if (isAccessibilityConfigChanged) {
1679         node.SetIsAccessibilityConfigChanged(true);
1680     }
1681     UpdateDrawingCacheInfoBeforeChildren(node);
1682     UpdateOffscreenCanvasNodeId(node);
1683     MarkFilterInForegroundFilterAndCheckNeedForceClearCache(node);
1684     node.SetIsAccessibilityConfigChanged(false);
1685     // The opinc state needs to be reset in the following cases:
1686     // 1. subtree is dirty
1687     // 2. content is dirty
1688     // 3. the node is marked as a node group
1689     // 4. the node is marked as a root node of opinc and the high-contrast state change
1690     auto isSelfDirty = node.IsSubTreeDirty() || node.IsContentDirty() ||
1691         node.GetNodeGroupType() > RSRenderNode::NodeGroupType::NONE ||
1692         (node.GetOpincCache().OpincGetRootFlag() && isAccessibilityConfigChanged);
1693     node.GetOpincCache().OpincQuickMarkStableNode(unchangeMarkInApp_, unchangeMarkEnable_, isSelfDirty);
1694     node.UpdateOpincParam();
1695     RectI prepareClipRect = prepareClipRect_;
1696     bool hasAccumulatedClip = hasAccumulatedClip_;
1697 
1698     if (!dirtyManager) {
1699         RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1700         return;
1701     }
1702     dirtyFlag_ =
1703         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1704 
1705     // update prepare clip before children
1706     hwcVisitor_->UpdatePrepareClip(node);
1707     node.UpdateCurCornerRadius(curCornerRadius_);
1708 
1709     bool isCurrOffscreen = hwcVisitor_->UpdateIsOffscreen(node);
1710     hwcVisitor_->UpdateForegroundColorValid(node);
1711 
1712     node.GetHwcRecorder().UpdatePositionZ(node.GetRenderProperties().GetPositionZ());
1713     if (node.GetHwcRecorder().GetZorderChanged() && curSurfaceNode_) {
1714         curSurfaceNode_->SetNeedCollectHwcNode(true);
1715     }
1716 
1717     // 1. Recursively traverse child nodes if above curSurfaceNode and subnode need draw
1718     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1719     bool isOpincSubTreeDirty = RSOpincManager::Instance().IsOpincSubTreeDirty(node, autoCacheEnable_);
1720     bool isSubTreeNeedPrepare = !curSurfaceNode_ || node.IsSubTreeNeedPrepare(filterInGlobal_) ||
1721         ForcePrepareSubTree() || isOpincSubTreeDirty;
1722     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1723         node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1724 
1725     PostPrepare(node, !isSubTreeNeedPrepare);
1726     prepareClipRect_ = prepareClipRect;
1727     hasAccumulatedClip_ = hasAccumulatedClip;
1728     dirtyFlag_ = dirtyFlag;
1729     curAlpha_ = prevAlpha;
1730     curCornerRadius_ = curCornerRadius;
1731     node.GetOpincCache().OpincUpdateRootFlag(unchangeMarkEnable_,
1732         RSOpincManager::Instance().OpincGetNodeSupportFlag(node));
1733     node.UpdateOpincParam();
1734     offscreenCanvasNodeId_ = preOffscreenCanvasNodeId;
1735 #ifdef SUBTREE_PARALLEL_ENABLE
1736     // used in subtree, add node into parallel list
1737     node.UpdateSubTreeParallelNodes();
1738 #endif
1739     // [Attention] Only used in PC window resize scene now
1740     NodeId linedRootNodeId = node.GetLinkedRootNodeId();
1741     if (UNLIKELY(linedRootNodeId != INVALID_NODEID)) {
1742         windowKeyFrameNodeInf_.UpdateLinkedNodeId(node.GetId(), linedRootNodeId);
1743     }
1744 
1745     globalShouldPaint_ = preGlobalShouldPaint;
1746 
1747     hwcVisitor_->RestoreIsOffscreen(isCurrOffscreen);
1748 
1749     node.RenderTraceDebug();
1750     RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1751 }
1752 
UpdateRotationStatusForEffectNode(RSEffectRenderNode & node)1753 void RSUniRenderVisitor::UpdateRotationStatusForEffectNode(RSEffectRenderNode& node)
1754 {
1755      // folding/expanding screen force invalidate cache.
1756     node.SetFoldStatusChanged(doAnimate_ &&
1757         curScreenNode_->GetScreenId() != node.GetCurrentAttachedScreenId());
1758     node.SetCurrentAttachedScreenId(curScreenNode_->GetScreenId());
1759     node.SetRotationChanged(curLogicalDisplayNode_->IsRotationChanged());
1760 }
1761 
IsLeashAndHasMainSubNode(RSRenderNode & node) const1762 bool RSUniRenderVisitor::IsLeashAndHasMainSubNode(RSRenderNode& node) const
1763 {
1764     if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1765         return false;
1766     }
1767     const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1768     if (!surfaceNode.IsLeashWindow()) {
1769         return false;
1770     }
1771     // check leashWindow surface has first level mainwindow node
1772     auto children = node.GetSortedChildren();
1773     auto iter = std::find_if((*children).begin(), (*children).end(),
1774         [](const std::shared_ptr<RSRenderNode>& node) {
1775         if (node && node->GetType() == RSRenderNodeType::SURFACE_NODE) {
1776             const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*node);
1777             return surfaceNode.IsMainWindowType();
1778         }
1779         return false;
1780     });
1781     return iter != (*children).end();
1782 }
1783 
NeedPrepareChindrenInReverseOrder(RSRenderNode & node) const1784 bool RSUniRenderVisitor::NeedPrepareChindrenInReverseOrder(RSRenderNode& node) const
1785 {
1786     if ((!curSurfaceNode_ && node.GetType() != RSRenderNodeType::RS_NODE)) {
1787         return true;
1788     }
1789     return IsLeashAndHasMainSubNode(node);
1790 }
1791 
QuickPrepareChildren(RSRenderNode & node)1792 void RSUniRenderVisitor::QuickPrepareChildren(RSRenderNode& node)
1793 {
1794     if (UNLIKELY(node.HasRemovedChild())) {
1795         MergeRemovedChildDirtyRegion(node, true);
1796     }
1797     if (node.LastFrameSubTreeSkipped() && curSurfaceDirtyManager_) {
1798         node.ForceMergeSubTreeDirtyRegion(*curSurfaceDirtyManager_, prepareClipRect_);
1799     }
1800     // Collect prepared node into the control-level occlusion culling handler.
1801     CollectNodeForOcclusion(node);
1802     bool animationBackup = ancestorNodeHasAnimation_;
1803     ancestorNodeHasAnimation_ = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
1804     node.ResetChildRelevantFlags();
1805     node.ResetChildUifirstSupportFlag();
1806 #ifdef SUBTREE_PARALLEL_ENABLE
1807     node.ClearSubtreeParallelNodes();
1808     node.ResetRepaintBoundaryInfo();
1809 #endif
1810     auto children = node.GetSortedChildren();
1811     if (NeedPrepareChindrenInReverseOrder(node)) {
1812         auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
1813         curFrameInfoDetail.curFrameReverseChildren = true;
1814         RS_LOGD("%{public}s NeedPrepareChindrenInReverseOrder nodeId: %{public}" PRIu64,
1815             __func__, node.GetId());
1816         std::for_each(
1817             (*children).rbegin(), (*children).rend(), [this, &node](const std::shared_ptr<RSRenderNode>& child) {
1818             if (!child) {
1819                 return;
1820             }
1821             rsScreenNodeChildNum_++;
1822             auto containerDirty = curContainerDirty_;
1823             curDirty_ = child->IsDirty();
1824             curContainerDirty_ = curContainerDirty_ || child->IsDirty();
1825             child->SetFirstLevelCrossNode(node.IsFirstLevelCrossNode() || child->IsCrossNode());
1826             child->GetHwcRecorder().SetZOrderForHwcEnableByFilter(hwcVisitor_->curZOrderForHwcEnableByFilter_++);
1827             child->QuickPrepare(shared_from_this());
1828 #ifdef SUBTREE_PARALLEL_ENABLE
1829             node.MergeSubtreeParallelNodes(*child);
1830 #endif
1831             curContainerDirty_ = containerDirty;
1832         });
1833     } else {
1834         auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
1835         curFrameInfoDetail.curFrameReverseChildren = false;
1836         std::for_each(
1837             (*children).begin(), (*children).end(), [this, &node](const std::shared_ptr<RSRenderNode>& child) {
1838             if (!child) {
1839                 return;
1840             }
1841             rsScreenNodeChildNum_++;
1842             curDirty_ = child->IsDirty();
1843             child->SetFirstLevelCrossNode(node.IsFirstLevelCrossNode() || child->IsCrossNode());
1844             child->GetHwcRecorder().SetZOrderForHwcEnableByFilter(hwcVisitor_->curZOrderForHwcEnableByFilter_++);
1845             child->QuickPrepare(shared_from_this());
1846 #ifdef SUBTREE_PARALLEL_ENABLE
1847             node.MergeSubtreeParallelNodes(*child);
1848 #endif
1849         });
1850     }
1851     ancestorNodeHasAnimation_ = animationBackup;
1852     node.ResetGeoUpdateDelay();
1853 }
1854 
1855 // Used to collect prepared node into the control-level occlusion culling handler.
CollectNodeForOcclusion(RSRenderNode & node)1856 inline void RSUniRenderVisitor::CollectNodeForOcclusion(RSRenderNode& node)
1857 {
1858     if (curOcclusionHandler_) {
1859         curOcclusionHandler_->CollectNode(node);
1860     }
1861 }
1862 
RegisterHpaeCallback(RSRenderNode & node)1863 void RSUniRenderVisitor::RegisterHpaeCallback(RSRenderNode& node)
1864 {
1865 #if defined(ROSEN_OHOS) && defined(ENABLE_HPAE_BLUR)
1866     RSHpaeManager::GetInstance().RegisterHpaeCallback(node, screenInfo_.phyWidth, screenInfo_.phyHeight);
1867 #endif
1868 }
1869 
UpdateCompositeType(RSScreenRenderNode & node)1870 void RSUniRenderVisitor::UpdateCompositeType(RSScreenRenderNode& node)
1871 {
1872     // 5. check compositeType
1873     auto mirrorNode = node.GetMirrorSource().lock();
1874     switch (node.GetScreenInfo().state) {
1875         case ScreenState::SOFTWARE_OUTPUT_ENABLE:
1876             node.SetCompositeType(mirrorNode ?
1877                 CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1878                 CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1879             break;
1880         case ScreenState::HDI_OUTPUT_ENABLE:
1881             node.SetCompositeType(node.IsForceSoftComposite() ?
1882                 CompositeType::SOFTWARE_COMPOSITE :
1883                 CompositeType::UNI_RENDER_COMPOSITE);
1884             break;
1885         default:
1886             break;
1887     }
1888 }
1889 
InitScreenInfo(RSScreenRenderNode & node)1890 bool RSUniRenderVisitor::InitScreenInfo(RSScreenRenderNode& node)
1891 {
1892     // 1 init curScreen and curScreenDirtyManager
1893     hasFingerprint_ = false;
1894     curScreenDirtyManager_ = node.GetDirtyManager();
1895     curScreenNode_ = node.shared_from_this()->ReinterpretCastTo<RSScreenRenderNode>();
1896     if (!curScreenDirtyManager_ || !curScreenNode_) {
1897         RS_LOGE("InitScreenInfo dirtyMgr or node ptr is nullptr");
1898         return false;
1899     }
1900 #ifdef RS_ENABLE_PREFETH
1901     __builtin_prefetch(curScreenNode_.get(), 0, 1);
1902 #endif
1903     curScreenDirtyManager_->SetAdvancedDirtyRegionType(advancedDirtyType_);
1904     curScreenDirtyManager_->Clear();
1905     hwcVisitor_->transparentHwcCleanFilter_.clear();
1906     hwcVisitor_->transparentHwcDirtyFilter_.clear();
1907     node.SetHasChildCrossNode(false);
1908     node.SetIsFirstVisitCrossNodeDisplay(false);
1909     node.SetHasUniRenderHdrSurface(false);
1910     node.SetIsLuminanceStatusChange(false);
1911     node.SetPixelFormat(GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888);
1912     node.SetExistHWCNode(false);
1913     CheckLuminanceStatusChange(curScreenNode_->GetScreenId());
1914 
1915     // 2 init screenManager info
1916     auto screenInfo = screenManager_->QueryScreenInfo(node.GetScreenId());
1917     node.SetScreenRect(screenInfo.activeRect.IsEmpty() ? RectI{0, 0, screenInfo.width, screenInfo.height} :
1918         screenInfo.activeRect);
1919     node.SetScreenInfo(std::move(screenInfo));
1920     curScreenDirtyManager_->SetSurfaceSize(
1921         curScreenNode_->GetScreenInfo().width, curScreenNode_->GetScreenInfo().height);
1922     curScreenDirtyManager_->SetActiveSurfaceRect(curScreenNode_->GetScreenInfo().activeRect);
1923     screenManager_->SetScreenHasProtectedLayer(node.GetScreenId(), false);
1924     allBlackList_ = screenManager_->GetAllBlackList();
1925     allWhiteList_ = screenManager_->GetAllWhiteList();
1926     screenWhiteList_ = screenManager_->GetScreenWhiteList();
1927     node.GetLogicalDisplayNodeDrawables().clear();
1928 
1929     // 3 init Occlusion info
1930     needRecalculateOcclusion_ = false;
1931     accumulatedOcclusionRegion_.Reset();
1932     accumulatedOcclusionRegionBehindWindow_.Reset();
1933     occlusionRegionWithoutSkipLayer_.Reset();
1934     if (!curMainAndLeashWindowNodesIds_.empty()) {
1935         std::queue<NodeId>().swap(curMainAndLeashWindowNodesIds_);
1936     }
1937 
1938     // 4. check isHardwareForcedDisabled
1939     auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1940     if (geoPtr == nullptr) {
1941         RS_LOGE("InitScreenInfo geoPtr is nullptr");
1942         return false;
1943     }
1944     if (geoPtr->IsNeedClientCompose()) {
1945         hwcVisitor_->isHardwareForcedDisabled_ = true;
1946         RS_OPTIONAL_TRACE_FMT("hwc debug: id:%" PRIu64 " disabled by screenNode rotation", node.GetId());
1947     }
1948 
1949     // init hdr
1950     node.ResetDisplayHdrStatus();
1951     node.SetColorSpace(GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB);
1952 
1953     // [Attention] Only used in PC window resize scene now
1954     windowKeyFrameNodeInf_.ClearLinkedNodeInfo();
1955 
1956     return true;
1957 }
1958 
BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1959 CM_INLINE bool RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1960 {
1961     // 1. init and record surface info
1962     if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1963         curLogicalDisplayNode_->SetHasCaptureWindow(true);
1964     }
1965     node.UpdateUIFirstFrameGravity();
1966     if (node.IsMainWindowType() || node.IsLeashWindow()) {
1967         // if firstLevelNode has attration animation,
1968         // subsurface with main window type, set attraction animation flag to skip filter cache occlusion
1969         auto firstLevelNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
1970             node.GetFirstLevelNode());
1971         node.SetAttractionAnimation(firstLevelNode != nullptr &&
1972             firstLevelNode->GetRenderProperties().IsAttractionValid());
1973         node.SetStencilVal(Drawing::Canvas::INVALID_STENCIL_VAL);
1974         // UpdateCurCornerRadius must process before curSurfaceNode_ update
1975         node.UpdateCurCornerRadius(curCornerRadius_);
1976         curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1977         // dirty manager should not be overrode by cross node in expand screen
1978         curSurfaceDirtyManager_ = (!curScreenNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) ?
1979             std::make_shared<RSDirtyRegionManager>() : node.GetDirtyManager();
1980         if (!curSurfaceDirtyManager_ || !curSurfaceNode_) {
1981             RS_LOGE("BeforeUpdateSurfaceDirtyCalc %{public}s has invalid "
1982                 "SurfaceDirtyManager or node ptr", node.GetName().c_str());
1983             return false;
1984         }
1985         curSurfaceDirtyManager_->Clear();
1986         auto& screenInfo = curScreenNode_->GetScreenInfo();
1987         curSurfaceDirtyManager_->SetSurfaceSize(screenInfo.width, screenInfo.height);
1988         curSurfaceDirtyManager_->SetActiveSurfaceRect(screenInfo.activeRect);
1989         filterInGlobal_ = curSurfaceNode_->IsTransparent();
1990         // update surfaceNode contentDirty and subTreeDirty flag for UIFirst purging policy
1991         RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1992         curSurfaceNode_->UpdateSurfaceCacheContentStaticFlag(IsAccessibilityConfigChanged());
1993         curSurfaceNode_->UpdateSurfaceSubTreeDirtyFlag();
1994     } else if (node.IsAbilityComponent()) {
1995         if (auto nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>()) {
1996             RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(nodePtr);
1997             nodePtr->UpdateSurfaceCacheContentStaticFlag(IsAccessibilityConfigChanged());
1998         }
1999     }
2000     // 2. update surface info and CheckIfOcclusionReusable
2001     node.SetAncestorScreenNode(curScreenNode_); // set for boot animation
2002     node.UpdateAncestorScreenNodeInRenderParams();
2003     node.CleanDstRectChanged();
2004     // [planning] check node isDirty can be optimized.
2005     needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.IsDirty() ||
2006         node.CheckIfOcclusionReusable(preMainAndLeashWindowNodesIds_);
2007     if (autoCacheEnable_ && node.IsAppWindow()) {
2008         node.GetOpincCache().OpincSetInAppStateStart(unchangeMarkInApp_);
2009     }
2010     // 3. check pixelFormat and update RelMatrix
2011     CheckPixelFormat(node);
2012     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
2013         node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
2014     }
2015     // 4. collect cursors and check for null
2016     RSPointerWindowManager::Instance().CollectAllHardCursor(node, curScreenNode_, curLogicalDisplayNode_);
2017     return true;
2018 }
2019 
AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)2020 CM_INLINE bool RSUniRenderVisitor::AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
2021 {
2022     // 1. Update surfaceNode info and AppWindow gravity
2023     const auto& property = node.GetRenderProperties();
2024     if (node.IsAppWindow()) {
2025         boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
2026         frameGravity_ = property.GetFrameGravity();
2027     }
2028     auto& geoPtr = property.GetBoundsGeometry();
2029     if (geoPtr == nullptr) {
2030         return false;
2031     }
2032     hwcVisitor_->UpdateCrossInfoForProtectedHwcNode(node);
2033     hwcVisitor_->UpdateDstRect(node, geoPtr->GetAbsRect(), prepareClipRect_);
2034     node.UpdatePositionZ();
2035     if (node.IsHardwareEnabledType() && node.GetZorderChanged() && curSurfaceNode_) {
2036         curSurfaceNode_->SetNeedCollectHwcNode(true);
2037     }
2038     UpdateSurfaceRenderNodeScale(node);
2039     UpdateSurfaceRenderNodeRotate(node);
2040     if (node.IsLeashWindow()) {
2041         curScreenNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
2042         curScreenNode_->AddSurfaceNodePosByDescZOrder(node.GetId(), node.GetOldDirtyInSurface());
2043     }
2044     // 2. Update Occlusion info before children preparation
2045     if (node.IsLeashOrMainWindow()) {
2046         UpdateNodeVisibleRegion(node);
2047     }
2048     // 3. Update HwcNode Info for appNode
2049     UpdateHwcNodeInfoForAppNode(node);
2050     if (node.IsHardwareEnabledTopSurface()) {
2051         hwcVisitor_->UpdateTopSurfaceSrcRect(node, geoPtr->GetAbsMatrix(), geoPtr->GetAbsRect());
2052         RSPointerWindowManager::CheckHardCursorValid(node);
2053     }
2054     // 4. Update color gamut for appNode
2055     if (!ColorGamutParam::SkipOccludedNodeDuringColorGamutCollection() ||
2056         !node.GetVisibleRegion().IsEmpty() || !GetIsOpDropped()) {
2057         CheckColorSpace(node);
2058     }
2059     return true;
2060 }
2061 
UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode & node)2062 void RSUniRenderVisitor::UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode& node)
2063 {
2064     // app node
2065     if (node.GetNeedCollectHwcNode()) {
2066         node.ResetChildHardwareEnabledNodes();
2067         node.SetExistTransparentHardwareEnabledNode(false);
2068     }
2069     // hwc node
2070     if (node.IsHardwareEnabledType() && curSurfaceNode_) {
2071         if (curSurfaceNode_->GetNeedCollectHwcNode()) {
2072             curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
2073         }
2074         auto& geo = node.GetRenderProperties().GetBoundsGeometry();
2075         if (geo == nullptr) {
2076             return;
2077         }
2078         hwcVisitor_->UpdateHwcNodeInfo(node, geo->GetAbsMatrix(), geo->GetAbsRect());
2079     }
2080 }
2081 
ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode> & hwcNodePtr,bool & ancoHasGpu)2082 void RSUniRenderVisitor::ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr, bool& ancoHasGpu)
2083 {
2084     if (hwcNodePtr == nullptr) {
2085         return;
2086     }
2087     auto alpha = hwcNodePtr->GetGlobalAlpha();
2088     RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 "src %{public}s dst %{public}s "
2089         "alpha:%{public}.2f", hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(),
2090         hwcNodePtr->GetSrcRect().ToString().c_str(), hwcNodePtr->GetDstRect().ToString().c_str(), alpha);
2091     if (ROSEN_EQ(alpha, 0.0f)) {
2092         return;
2093     }
2094 
2095     if (!hwcNodePtr->GetRSSurfaceHandler() || !hwcNodePtr->GetRSSurfaceHandler()->GetBuffer()) {
2096         RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 " handler or buffer is null, skip",
2097             hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2098         return;
2099     }
2100     if (hwcNodePtr->IsHardwareForcedDisabled()) {
2101         RS_OPTIONAL_TRACE_NAME_FMT("ProcessAncoNode: name:%s id:%" PRIu64 " hardware forced disabled",
2102             hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2103     }
2104     ancoHasGpu = (ancoHasGpu || hwcNodePtr->IsHardwareForcedDisabled());
2105 }
2106 
UpdateAncoNodeHWCDisabledState(std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>> & ancoNodes)2107 void RSUniRenderVisitor::UpdateAncoNodeHWCDisabledState(
2108     std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>>& ancoNodes)
2109 {
2110     bool ancoHasGpu = false;
2111     for (auto hwcNodePtr : ancoNodes) {
2112         ProcessAncoNode(hwcNodePtr, ancoHasGpu);
2113     }
2114     if (ancoHasGpu) {
2115         for (const auto& hwcNodePtr : ancoNodes) {
2116             RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by anco has gpu",
2117                 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2118             hwcNodePtr->SetHardwareForcedDisabledState(true);
2119         }
2120     }
2121 }
2122 
PrevalidateHwcNode()2123 void RSUniRenderVisitor::PrevalidateHwcNode()
2124 {
2125     if (!RSUniHwcPrevalidateUtil::GetInstance().IsPrevalidateEnable()) {
2126         RS_LOGD_IF(DEBUG_PREVALIDATE, "PrevalidateHwcNode prevalidate close");
2127         hwcVisitor_->PrintHiperfCounterLog("counter2", static_cast<uint64_t>(0));
2128         return;
2129     }
2130     auto& curMainAndLeashSurfaces = curScreenNode_->GetAllMainAndLeashSurfaces();
2131     std::vector<RequestLayerInfo> prevalidLayers;
2132     uint32_t curFps = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(curScreenNode_->GetScreenId());
2133     uint32_t zOrder = static_cast<uint32_t>(globalZOrder_);
2134     // add surfaceNode layer
2135     RSUniHwcPrevalidateUtil::GetInstance().CollectSurfaceNodeLayerInfo(
2136         prevalidLayers, curMainAndLeashSurfaces, curFps, zOrder, curScreenNode_->GetScreenInfo());
2137     RS_TRACE_NAME_FMT("PrevalidateHwcNode hwcLayer: %u", prevalidLayers.size());
2138     if (prevalidLayers.size() == 0) {
2139         RS_LOGI_IF(DEBUG_PREVALIDATE, "PrevalidateHwcNode no hardware layer");
2140         hwcVisitor_->PrintHiperfCounterLog("counter2", INPUT_HWC_LAYERS);
2141         RSHpaeOfflineProcessor::GetOfflineProcessor().CheckAndPostClearOfflineResourceTask();
2142         return;
2143     }
2144     // add display layer
2145     RequestLayerInfo screenLayer;
2146     if (RSUniHwcPrevalidateUtil::GetInstance().CreateScreenNodeLayerInfo(
2147         zOrder++, curScreenNode_, curScreenNode_->GetScreenInfo(), curFps, screenLayer)) {
2148         prevalidLayers.emplace_back(screenLayer);
2149     }
2150     // add rcd layer
2151     RequestLayerInfo rcdLayer;
2152     if (RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
2153         auto rcdSurface = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curScreenNode_->GetRcdSurfaceNodeTop());
2154         if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(
2155             rcdSurface, curScreenNode_->GetScreenInfo(), curFps, rcdLayer)) {
2156             prevalidLayers.emplace_back(rcdLayer);
2157         }
2158         rcdSurface = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curScreenNode_->GetRcdSurfaceNodeBottom());
2159         if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(
2160             rcdSurface, curScreenNode_->GetScreenInfo(), curFps, rcdLayer)) {
2161             prevalidLayers.emplace_back(rcdLayer);
2162         }
2163     }
2164     hwcVisitor_->PrintHiperfCounterLog("counter2", static_cast<uint64_t>(prevalidLayers.size()));
2165     std::map<uint64_t, RequestCompositionType> strategy;
2166     if (!RSUniHwcPrevalidateUtil::GetInstance().PreValidate(
2167         curScreenNode_->GetScreenInfo().id, prevalidLayers, strategy)) {
2168         RS_LOGI_IF(DEBUG_PREVALIDATE, "PrevalidateHwcNode prevalidate failed");
2169         return;
2170     }
2171     {
2172         auto iter = std::find_if(strategy.begin(), strategy.end(),
2173             [](const auto& elem) { return elem.second == RequestCompositionType::OFFLINE_DEVICE; });
2174         if (iter == strategy.end()) {
2175             RSHpaeOfflineProcessor::GetOfflineProcessor().CheckAndPostClearOfflineResourceTask();
2176         }
2177     }
2178     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2179     for (auto it : strategy) {
2180         RS_LOGD_IF(DEBUG_PREVALIDATE, "PrevalidateHwcNode id: %{public}" PRIu64 ","
2181             " result: %{public}d", it.first, it.second);
2182         if (it.second == RequestCompositionType::DEVICE) {
2183             continue;
2184         }
2185         auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(it.first);
2186         if (node == nullptr) {
2187             continue;
2188         }
2189         if (it.second == RequestCompositionType::DEVICE_VSCF) {
2190             node->SetArsrTag(false);
2191             continue;
2192         }
2193         if (it.second == RequestCompositionType::OFFLINE_DEVICE &&
2194             RSHpaeOfflineProcessor::GetOfflineProcessor().IsRSHpaeOfflineProcessorReady()) {
2195             node->SetDeviceOfflineEnable(true);
2196             continue;
2197         }
2198         if (node->IsInFixedRotation() || node->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2199             continue;
2200         }
2201         RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by preValidate",
2202             node->GetName().c_str(), node->GetId());
2203         hwcVisitor_->PrintHiperfLog(node, "preValidate");
2204         node->SetHardwareForcedDisabledState(true);
2205         if (node->GetRSSurfaceHandler()) {
2206             node->GetRSSurfaceHandler()->SetGlobalZOrder(-1.f);
2207         }
2208         hwcVisitor_->Statistics().UpdateHwcDisabledReasonForDFX(node->GetId(),
2209             HwcDisabledReasons::DISABLED_BY_PREVALIDATE, node->GetName());
2210     }
2211 }
2212 
UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode> & node)2213 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode>& node)
2214 {
2215     const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
2216     if (hwcNodes.empty() || !curScreenNode_) {
2217         return;
2218     }
2219     std::vector<std::shared_ptr<RSSurfaceRenderNode>> topLayers;
2220     for (auto hwcNode : hwcNodes) {
2221         auto hwcNodePtr = hwcNode.lock();
2222         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2223             continue;
2224         }
2225         auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
2226         if (hwcNodePtr->IsLayerTop()) {
2227             topLayers.emplace_back(hwcNodePtr);
2228             if (hasMirrorDisplay_ && hwcNodePtr->GetRSSurfaceHandler() &&
2229                 hwcNodePtr->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2230                 !(node->GetVisibleRegion().IsEmpty()) && curScreenDirtyManager_) {
2231                 // merge hwc top node dst rect for virtual screen dirty, in case the main display node skip
2232                 curScreenDirtyManager_->MergeHwcDirtyRect(hwcNodePtr->GetDstRect());
2233             }
2234             continue;
2235         }
2236         if (((curScreenNode_->GetHasUniRenderHdrSurface() && !RSHdrUtil::GetRGBA1010108Enabled()) ||
2237             !drmNodes_.empty() || hasFingerprint_) &&
2238             !hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2239             RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64
2240                 " disabled by Having UniRenderHdrSurface/DRM node",
2241                 node->GetName().c_str(), node->GetId());
2242             hwcVisitor_->PrintHiperfLog(node, "uniRender HDR");
2243             hwcNodePtr->SetHardwareForcedDisabledState(true);
2244             // DRM will force HDR to use unirender
2245             curScreenNode_->SetHasUniRenderHdrSurface(curScreenNode_->GetHasUniRenderHdrSurface() ||
2246                 RSHdrUtil::CheckIsHdrSurface(*hwcNodePtr) != HdrStatus::NO_HDR);
2247             hwcVisitor_->Statistics().UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
2248                 HwcDisabledReasons::DISABLED_BY_RENDER_HDR_SURFACE, hwcNodePtr->GetName());
2249         }
2250         UpdateHwcNodeDirtyRegionForApp(node, hwcNodePtr);
2251         hwcNodePtr->SetCalcRectInPrepare(false);
2252         surfaceHandler->SetGlobalZOrder(hwcNodePtr->IsHardwareForcedDisabled() &&
2253             !hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED) ? -1.f : globalZOrder_++);
2254         auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(hwcNodePtr->GetStagingRenderParams().get());
2255         if (stagingSurfaceParams->GetIsHwcEnabledBySolidLayer()) {
2256             surfaceHandler->SetGlobalZOrder(globalZOrder_++);
2257         }
2258         auto transform = RSUniHwcComputeUtil::GetLayerTransform(*hwcNodePtr, curScreenNode_->GetScreenInfo());
2259         hwcNodePtr->UpdateHwcNodeLayerInfo(transform);
2260     }
2261     curScreenNode_->SetDisplayGlobalZOrder(globalZOrder_);
2262     if (!topLayers.empty()) {
2263         UpdateTopLayersDirtyStatus(topLayers);
2264     }
2265 }
2266 
UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode> & pointWindow)2267 void RSUniRenderVisitor::UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode>& pointWindow)
2268 {
2269     if (!pointWindow->IsHardwareEnabledTopSurface()) {
2270         pointWindow->SetHardCursorStatus(false);
2271         RSPointerWindowManager::Instance().SetIsPointerEnableHwc(false);
2272         return;
2273     }
2274     std::shared_ptr<RSSurfaceHandler> pointSurfaceHandler = pointWindow->GetMutableRSSurfaceHandler();
2275     if (pointSurfaceHandler) {
2276         // globalZOrder_  is screenNode layer, point window must be at the top.
2277         pointSurfaceHandler->SetGlobalZOrder(static_cast<float>(TopLayerZOrder::POINTER_WINDOW));
2278         if (!curScreenNode_) {
2279             return;
2280         }
2281         bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curScreenNode_->GetScreenId());
2282         if (isHardCursor) {
2283             // Set the highest z-order for hardCursor
2284             pointSurfaceHandler->SetGlobalZOrder(static_cast<float>(TopLayerZOrder::POINTER_WINDOW));
2285         }
2286         pointWindow->SetHardwareForcedDisabledState(true);
2287         RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by pointWindow and pointSurfaceHandler",
2288             pointWindow->GetName().c_str(), pointWindow->GetId());
2289         bool isMirrorMode = RSPointerWindowManager::Instance().HasMirrorDisplay();
2290         RSPointerWindowManager::Instance().SetIsPointerEnableHwc(isHardCursor && !isMirrorMode);
2291         auto transform = RSUniHwcComputeUtil::GetLayerTransform(*pointWindow, curScreenNode_->GetScreenInfo());
2292         pointWindow->SetHardCursorStatus(isHardCursor);
2293         pointWindow->UpdateHwcNodeLayerInfo(transform, isHardCursor);
2294         if (isHardCursor) {
2295             RSPointerWindowManager::Instance().UpdatePointerDirtyToGlobalDirty(pointWindow, curScreenNode_);
2296         }
2297     }
2298 }
2299 
UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & topLayers)2300 void RSUniRenderVisitor::UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& topLayers)
2301 {
2302     for (const auto& topLayer : topLayers) {
2303         std::shared_ptr<RSSurfaceHandler> topLayerSurfaceHandler = topLayer->GetMutableRSSurfaceHandler();
2304         if (topLayerSurfaceHandler) {
2305             if (topLayer->GetTopLayerZOrder() == 0) {
2306                 topLayerSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 1);
2307             } else {
2308                 topLayerSurfaceHandler->SetGlobalZOrder(static_cast<float>(topLayer->GetTopLayerZOrder()));
2309             }
2310             topLayer->SetCalcRectInPrepare(false);
2311             bool hwcDisabled = !IsHardwareComposerEnabled() || !topLayer->ShouldPaint() ||
2312                 curScreenNode_->GetHasUniRenderHdrSurface() || !drmNodes_.empty();
2313             topLayer->SetHardwareForcedDisabledState(hwcDisabled);
2314             if (hwcDisabled) {
2315                 RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by toplayers dirty status, "
2316                     "IsHardwareComposerEnabled[%d],TopLayerShouldPaint[%d],HasUniRenderHdrSurface[%d],DrmNodeEmpty[%d]",
2317                     topLayer->GetName().c_str(), topLayer->GetId(), IsHardwareComposerEnabled(),
2318                     topLayer->ShouldPaint(), curScreenNode_->GetHasUniRenderHdrSurface(), drmNodes_.empty());
2319             }
2320             auto transform = RSUniHwcComputeUtil::GetLayerTransform(*topLayer, curScreenNode_->GetScreenInfo());
2321             topLayer->UpdateHwcNodeLayerInfo(transform);
2322         }
2323     }
2324 }
2325 
UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode> & appNode,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2326 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode>& appNode,
2327     std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2328 {
2329     // if current frame hwc enable status not equal with last frame
2330     // or current frame do gpu composition and has buffer consumed,
2331     // we need merge hwc node dst rect to dirty region.
2332     if (!hwcNode->IsHardwareForcedDisabled() != hwcNode->GetIsLastFrameHwcEnabled()) {
2333         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
2334         return;
2335     }
2336     if (!hwcNode->GetRSSurfaceHandler()) {
2337         return;
2338     }
2339     if (hwcNode->IsHardwareForcedDisabled() && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
2340         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetOldDirtyInSurface());
2341     }
2342     if (hasMirrorDisplay_ && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2343         !appNode->GetVisibleRegion().IsEmpty()) {
2344         // merge hwc node dst rect for virtual screen dirty, in case the main display node skip
2345         curScreenDirtyManager_->MergeHwcDirtyRect(hwcNode->GetDstRect());
2346     }
2347 }
2348 
UpdateSurfaceDirtyAndGlobalDirty()2349 void RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty()
2350 {
2351     UpdateDisplayDirtyAndExtendVisibleRegion();
2352     auto& curMainAndLeashSurfaces = curScreenNode_->GetAllMainAndLeashSurfaces();
2353     // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
2354     Occlusion::Region accumulatedDirtyRegion;
2355     bool hasMainAndLeashSurfaceDirty = false;
2356     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2357         [this, &accumulatedDirtyRegion, &hasMainAndLeashSurfaceDirty](RSBaseRenderNode::SharedPtr& nodePtr) {
2358         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2359         if (!surfaceNode) {
2360             RS_LOGE("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surfaceNode is nullptr");
2361             return;
2362         }
2363         accumulatedDirtyRegion.OrSelf(curScreenNode_->GetDisappearedSurfaceRegionBelowCurrent(surfaceNode->GetId()));
2364         auto dirtyManager = surfaceNode->GetDirtyManager();
2365         RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
2366         // 0. update hwc node dirty region and create layer
2367         UpdateHwcNodeDirtyRegionAndCreateLayer(surfaceNode);
2368         // cal done node dirtyRegion for uifirst
2369         RSUifirstManager::Instance().MergeOldDirtyToDirtyManager(surfaceNode);
2370         UpdatePointWindowDirtyStatus(surfaceNode);
2371         // 1. calculate abs dirtyrect and update partialRenderParams
2372         // currently only sync visible region info
2373         surfaceNode->UpdatePartialRenderParams();
2374         // 2. check surface node dirtyrect need merge into displayDirtyManager
2375         CheckMergeSurfaceDirtysForDisplay(surfaceNode);
2376         // 3. check merge transparent filter when it intersects with pre-dirty.
2377         CheckMergeFilterDirtyWithPreDirty(dirtyManager, accumulatedDirtyRegion, surfaceNode->IsTransparent() ?
2378             FilterDirtyType::TRANSPARENT_SURFACE_FILTER : FilterDirtyType::OPAQUE_SURFACE_FILTER);
2379         // 4. for cross-display node, process its filter (which is not collected during prepare).
2380         CollectFilterInCrossDisplayWindow(surfaceNode, accumulatedDirtyRegion);
2381         // 5. accumulate dirty region of this surface.
2382         AccumulateSurfaceDirtyRegion(surfaceNode, accumulatedDirtyRegion);
2383         hasMainAndLeashSurfaceDirty |=
2384             dirtyManager && dirtyManager->IsCurrentFrameDirty() &&
2385             surfaceNode->GetVisibleRegion().IsIntersectWith(dirtyManager->GetCurrentFrameDirtyRegion());
2386     });
2387     curScreenNode_->SetMainAndLeashSurfaceDirty(hasMainAndLeashSurfaceDirty);
2388     CheckMergeDebugRectforRefreshRate(curMainAndLeashSurfaces);
2389     CheckMergeScreenDirtyByRoundCornerDisplay();
2390     CheckMergeFilterDirtyWithPreDirty(curScreenDirtyManager_, accumulatedDirtyRegion, CONTAINER_FILTER);
2391     ResetDisplayDirtyRegion();
2392     if (curScreenDirtyManager_) {
2393         curScreenDirtyManager_->ClipDirtyRectWithinSurface();
2394         if (curScreenDirtyManager_->IsActiveSurfaceRectChanged()) {
2395             RS_TRACE_NAME_FMT("ActiveSurfaceRectChanged, form %s to %s",
2396                 curScreenDirtyManager_->GetLastActiveSurfaceRect().ToString().c_str(),
2397                 curScreenDirtyManager_->GetActiveSurfaceRect().ToString().c_str());
2398             curScreenDirtyManager_->MergeDirtyRect(curScreenDirtyManager_->GetSurfaceRect());
2399         }
2400     }
2401     UpdateIfHwcNodesHaveVisibleRegion(curMainAndLeashSurfaces);
2402     curScreenNode_->ClearCurrentSurfacePos();
2403     std::swap(preMainAndLeashWindowNodesIds_, curMainAndLeashWindowNodesIds_);
2404 
2405 #ifdef RS_PROFILER_ENABLED
2406     RS_PROFILER_SET_DIRTY_REGION(accumulatedDirtyRegion);
2407 #endif
2408 }
2409 
CheckMergeFilterDirtyWithPreDirty(const std::shared_ptr<RSDirtyRegionManager> & dirtyManager,const Occlusion::Region & accumulatedDirtyRegion,FilterDirtyType filterDirtyType)2410 void RSUniRenderVisitor::CheckMergeFilterDirtyWithPreDirty(const std::shared_ptr<RSDirtyRegionManager>& dirtyManager,
2411     const Occlusion::Region& accumulatedDirtyRegion, FilterDirtyType filterDirtyType)
2412 {
2413     if (UNLIKELY(dirtyManager == nullptr)) {
2414         return;
2415     }
2416     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2417     auto update = [&] (const FilterDirtyRegionInfo& filterInfo) {
2418         auto filterNode = nodeMap.GetRenderNode<RSRenderNode>(filterInfo.id_);
2419         if (!filterNode) {
2420             return;
2421         }
2422         Occlusion::Region belowDirtyToConsider;
2423         // for transparent surface filter or container filter, accumulated surface dirty should be considered.
2424         belowDirtyToConsider.OrSelf(filterDirtyType != FilterDirtyType::OPAQUE_SURFACE_FILTER ?
2425             accumulatedDirtyRegion : Occlusion::Region());
2426         // for filter in surface, accumulated dirty within surface should be considered.
2427         belowDirtyToConsider.OrSelf(filterDirtyType != FilterDirtyType::CONTAINER_FILTER ?
2428             filterInfo.belowDirty_ : Occlusion::Region());
2429         if (filterNode->GetRenderProperties().GetBackgroundFilter() ||
2430             filterNode->GetRenderProperties().GetNeedDrawBehindWindow()) {
2431             // backgroundfilter affected by below dirty
2432             filterNode->UpdateFilterCacheWithBelowDirty(
2433                 filterInfo.isBackgroundFilterClean_ ? accumulatedDirtyRegion : belowDirtyToConsider, false);
2434         }
2435         if (filterNode->GetRenderProperties().GetFilter()) {
2436             // foregroundfilter affected by below dirty
2437             filterNode->UpdateFilterCacheWithBelowDirty(belowDirtyToConsider, true);
2438         }
2439         bool isIntersect = belowDirtyToConsider.IsIntersectWith(Occlusion::Rect(filterNode->GetFilterRect()));
2440         filterNode->PostPrepareForBlurFilterNode(*dirtyManager, needRequestNextVsync_);
2441         RsFrameBlurPredict::GetInstance().PredictDrawLargeAreaBlur(*filterNode);
2442         if (isIntersect) {
2443             RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeFilterDirtyWithPreDirty [%" PRIu64 "] type %d intersects below dirty"
2444                 " Add %s to dirty.", filterInfo.id_, filterDirtyType, filterInfo.filterDirty_.GetRegionInfo().c_str());
2445             dirtyManager->MergeDirtyRect(filterInfo.filterDirty_.GetBound().ToRectI());
2446         } else {
2447             dirtyManager->GetFilterCollector().CollectFilterDirtyRegionInfo(filterInfo, true);
2448         }
2449     };
2450     auto& filtersToUpdate = dirtyManager->GetFilterCollector().GetFilterDirtyRegionInfoList(false);
2451     std::for_each(filtersToUpdate.begin(), filtersToUpdate.end(), update);
2452     filtersToUpdate.clear();
2453 }
2454 
UpdateIfHwcNodesHaveVisibleRegion(std::vector<RSBaseRenderNode::SharedPtr> & curMainAndLeashSurfaces)2455 void RSUniRenderVisitor::UpdateIfHwcNodesHaveVisibleRegion(
2456     std::vector<RSBaseRenderNode::SharedPtr>& curMainAndLeashSurfaces)
2457 {
2458     bool needForceUpdateHwcNodes = false;
2459     bool hasVisibleHwcNodes = false;
2460     for (auto& nodePtr : curMainAndLeashSurfaces) {
2461         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2462         if (!surfaceNode) {
2463             RS_LOGD("[%{public}s]: surfaceNode is nullptr", __func__);
2464             continue;
2465         }
2466         if (surfaceNode->GetVisibleRegion().IsEmpty()) {
2467             continue;
2468         }
2469         const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2470         if (hwcNodes.empty()) {
2471             continue;
2472         }
2473         UpdateHwcNodesIfVisibleForApp(surfaceNode, hwcNodes, hasVisibleHwcNodes, needForceUpdateHwcNodes);
2474         if (needForceUpdateHwcNodes) {
2475             break;
2476         }
2477     }
2478     curScreenNode_->SetNeedForceUpdateHwcNodes(needForceUpdateHwcNodes, hasVisibleHwcNodes);
2479 }
2480 
UpdateHwcNodesIfVisibleForApp(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & hwcNodes,bool & hasVisibleHwcNodes,bool & needForceUpdateHwcNodes)2481 void RSUniRenderVisitor::UpdateHwcNodesIfVisibleForApp(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2482     const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes,
2483     bool& hasVisibleHwcNodes, bool& needForceUpdateHwcNodes)
2484 {
2485     for (auto& hwcNode : hwcNodes) {
2486         auto hwcNodePtr = hwcNode.lock();
2487         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2488             continue;
2489         }
2490         if (hwcNodePtr->IsHardwareForcedDisabled() || hwcNodePtr->GetRSSurfaceHandler() == nullptr) {
2491             continue;
2492         }
2493         if (surfaceNode->GetVisibleRegion().IsEmpty()) {
2494             continue;
2495         }
2496 
2497         // 1.hwcNode moving to extended screen 2.hwcNode is crossNode
2498         // 3. sufaceNode is top layer 4. In drm Scene
2499         if (hwcNodePtr->GetHwcGlobalPositionEnabled() ||
2500             hwcNodePtr->IsHwcCrossNode() ||
2501             surfaceNode->IsLayerTop() ||
2502             surfaceNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2503             hwcNodePtr->HwcSurfaceRecorder().SetLastFrameHasVisibleRegion(true); // visible Region
2504             needForceUpdateHwcNodes = true;
2505             continue;
2506         }
2507 
2508         auto visibleRegion = surfaceNode->GetVisibleRegion();
2509         visibleRegion.MakeBound();
2510         auto visibleRectI = visibleRegion.GetBound().ToRectI();
2511         auto widthRatio = curScreenNode_->GetScreenInfo().GetRogWidthRatio();
2512         auto heightRatio = curScreenNode_->GetScreenInfo().GetRogHeightRatio();
2513         visibleRectI.left_ = static_cast<int>(std::round(visibleRectI.left_ * widthRatio));
2514         visibleRectI.top_ = static_cast<int>(std::round(visibleRectI.top_ * heightRatio));
2515         visibleRectI.width_ = static_cast<int>(std::round(visibleRectI.width_ * widthRatio));
2516         visibleRectI.height_ = static_cast<int>(std::round(visibleRectI.height_ * heightRatio));
2517         auto newRegionRect = Occlusion::Rect(visibleRectI, true);
2518         newRegionRect.Expand(EXPAND_ONE_PIX, EXPAND_ONE_PIX, EXPAND_ONE_PIX, EXPAND_ONE_PIX);
2519         Occlusion::Rect dstRect(hwcNodePtr->GetDstRect());
2520         if (newRegionRect.IsIntersect(dstRect)) {
2521             hwcNodePtr->HwcSurfaceRecorder().SetLastFrameHasVisibleRegion(true); // visible Region
2522             hasVisibleHwcNodes = true;
2523             if (hwcNodePtr->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
2524                 needForceUpdateHwcNodes = true;
2525             }
2526         } else {
2527             hwcNodePtr->HwcSurfaceRecorder().SetLastFrameHasVisibleRegion(false); // invisible Region
2528         }
2529     }
2530 }
2531 
UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,std::vector<RectI> & hwcRects)2532 void RSUniRenderVisitor::UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,
2533     std::vector<RectI>& hwcRects)
2534 {
2535     if (!hwcNode || !hwcNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2536         return;
2537     }
2538     auto instanceNode = hwcNode->GetInstanceRootNode() ?
2539         hwcNode->GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
2540     if (!instanceNode) {
2541         hwcNode->SetCornerRadiusInfoForDRM({});
2542         return;
2543     }
2544     auto instanceAbsRect = instanceNode->GetAbsDrawRect();
2545     auto instanceCornerRadius = instanceNode->GetGlobalCornerRadius();
2546     if (instanceAbsRect.IsEmpty() || instanceCornerRadius.IsZero() ||
2547         ROSEN_EQ(instanceNode->GetRenderProperties().GetBoundsWidth(), 0.0f)) {
2548         hwcNode->SetCornerRadiusInfoForDRM({});
2549         return;
2550     }
2551     auto hwcGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2552     if (!hwcGeo) {
2553         hwcNode->SetCornerRadiusInfoForDRM({});
2554         return;
2555     }
2556     auto hwcAbsRect = hwcGeo->MapRect(hwcNode->GetSelfDrawRect(), hwcNode->GetTotalMatrix());
2557     hwcAbsRect = hwcAbsRect.IntersectRect(instanceAbsRect);
2558     if (hwcAbsRect.IsEmpty()) {
2559         hwcNode->SetCornerRadiusInfoForDRM({});
2560         return;
2561     }
2562     auto ratio = static_cast<float>(instanceAbsRect.GetWidth()) /
2563         instanceNode->GetRenderProperties().GetBoundsWidth();
2564     std::vector<float> ratioVector = { 0.0f, 0.0f, 0.0f, 0.0f };
2565     bool isIntersectWithRoundCorner =
2566         CheckIfRoundCornerIntersectDRM(ratio, ratioVector, instanceCornerRadius, instanceAbsRect, hwcAbsRect);
2567     // store radius information when drm overlaps with other hwc nodes
2568     if (isIntersectWithRoundCorner) {
2569         for (const auto& rect : hwcRects) {
2570             if (hwcAbsRect.Intersect(rect)) {
2571                 std::vector<float> drmCornerRadiusInfo = {
2572                     static_cast<float>(hwcAbsRect.GetLeft()), static_cast<float>(hwcAbsRect.GetTop()),
2573                     static_cast<float>(hwcAbsRect.GetWidth()), static_cast<float>(hwcAbsRect.GetHeight()),
2574                     // get corner radius num by index 0, 1, 2, 3
2575                     instanceCornerRadius[0] * ratioVector[0], instanceCornerRadius[1] * ratioVector[1],
2576                     instanceCornerRadius[2] * ratioVector[2], instanceCornerRadius[3] * ratioVector[3]};
2577                 hwcNode->SetCornerRadiusInfoForDRM(drmCornerRadiusInfo);
2578                 return;
2579             }
2580         }
2581     }
2582     hwcNode->SetCornerRadiusInfoForDRM({});
2583 }
2584 
CheckIfRoundCornerIntersectDRM(const float & ratio,std::vector<float> & ratioVector,const Vector4f & instanceCornerRadius,const RectI & instanceAbsRect,const RectI & hwcAbsRect)2585 bool RSUniRenderVisitor::CheckIfRoundCornerIntersectDRM(const float& ratio, std::vector<float>& ratioVector,
2586     const Vector4f& instanceCornerRadius, const RectI& instanceAbsRect, const RectI& hwcAbsRect)
2587 {
2588     auto maxRadius = *std::max_element(std::begin(instanceCornerRadius.data_),
2589         std::end(instanceCornerRadius.data_)) * ratio;
2590     bool isIntersectWithRoundCorner = false;
2591     static const std::vector<UIPoint> offsetVecs = { UIPoint { 0, 0 }, UIPoint { 1, 0 },
2592         UIPoint { 0, 1 }, UIPoint { 1, 1 } };
2593     UIPoint offset { instanceAbsRect.GetWidth() - maxRadius, instanceAbsRect.GetHeight() - maxRadius };
2594     UIPoint anchorPoint { instanceAbsRect.GetLeft(), instanceAbsRect.GetTop() };
2595     // if round corners intersect drm, update ratioVectors
2596     for (size_t i = 0; i < offsetVecs.size(); i++) {
2597         auto res = anchorPoint + offset * offsetVecs[i];
2598         if (RectI(res.x_, res.y_, maxRadius, maxRadius).Intersect(hwcAbsRect)) {
2599             isIntersectWithRoundCorner = true;
2600             ratioVector[i] = ratio;
2601         }
2602     }
2603     return isIntersectWithRoundCorner;
2604 }
2605 
UpdateSurfaceOcclusionInfo()2606 void RSUniRenderVisitor::UpdateSurfaceOcclusionInfo()
2607 {
2608     allDstCurVisVec_.insert(allDstCurVisVec_.end(), dstCurVisVec_.begin(), dstCurVisVec_.end());
2609     dstCurVisVec_.clear();
2610 }
2611 
CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode & surfaceNode) const2612 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode& surfaceNode) const
2613 {
2614     // surfaceNode is transparent
2615     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2616     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2617     Occlusion::Region visibleRegion = hasMirrorDisplay_ ?
2618         surfaceNode.GetVisibleRegionInVirtual() : surfaceNode.GetVisibleRegion();
2619     if (surfaceNode.IsMainWindowType() && !visibleRegion.IsIntersectWith(dirtyRect)) {
2620         return;
2621     }
2622     if (surfaceNode.IsTransparent()) {
2623         RectI transparentDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2624         if (!transparentDirtyRect.IsEmpty()) {
2625             RS_LOGD("CheckMergeDisplayDirtyByTransparent global merge transparent dirty "
2626                 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2627                 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2628                 transparentDirtyRect.ToString().c_str());
2629             curScreenNode_->GetDirtyManager()->MergeDirtyRect(transparentDirtyRect);
2630         }
2631     }
2632     // surfaceNode has transparent regions
2633     CheckMergeDisplayDirtyByTransparentRegions(surfaceNode);
2634 }
2635 
CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode & surfaceNode) const2636 void RSUniRenderVisitor::CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode& surfaceNode) const
2637 {
2638     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2639     if (surfaceNode.GetZorderChanged()) {
2640         RS_LOGD("CheckMergeDisplayDirtyByZorderChanged global merge GetZorderChanged "
2641             "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2642             curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2643             oldDirtyInSurface.ToString().c_str());
2644         curScreenNode_->GetDirtyManager()->MergeDirtyRect(oldDirtyInSurface);
2645     }
2646 }
2647 
CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode & surfaceNode) const2648 void RSUniRenderVisitor::CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode& surfaceNode) const
2649 {
2650     bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curScreenNode_->GetScreenId());
2651     if (isHardCursor && surfaceNode.IsHardwareEnabledTopSurface() && surfaceNode.GetHardCursorStatus()) {
2652         return;
2653     }
2654     RectI lastFrameSurfacePos = curScreenNode_->GetLastFrameSurfacePos(surfaceNode.GetId());
2655     RectI currentFrameSurfacePos = curScreenNode_->GetCurrentFrameSurfacePos(surfaceNode.GetId());
2656     if (surfaceNode.GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
2657         RS_LOGD("CheckMergeDisplayDirtyByPosChanged global merge surface pos changed "
2658             "%{public}s: global dirty %{public}s, lastFrameRect %{public}s currentFrameRect %{public}s",
2659             surfaceNode.GetName().c_str(),
2660             curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2661             lastFrameSurfacePos.ToString().c_str(), currentFrameSurfacePos.ToString().c_str());
2662         if (!lastFrameSurfacePos.IsEmpty()) {
2663             curScreenNode_->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
2664         }
2665         if (!currentFrameSurfacePos.IsEmpty()) {
2666             curScreenNode_->GetDirtyManager()->MergeDirtyRect(currentFrameSurfacePos);
2667         }
2668     }
2669 }
2670 
CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode & surfaceNode) const2671 void RSUniRenderVisitor::CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode& surfaceNode) const
2672 {
2673     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2674     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2675     bool isShadowDisappear = !surfaceNode.GetRenderProperties().IsShadowValid() &&
2676         surfaceNode.IsShadowValidLastFrame();
2677     if (surfaceNode.GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2678         RectI shadowDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2679         // There are two situation here:
2680         // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2681         // dirtyRect == surfaceNode.GetOldDirtyInSurface()
2682         // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2683         // dirtyRect > surfaceNode.GetOldDirtyInSurface()
2684         // So we should always merge dirtyRect here.
2685         if (!shadowDirtyRect.IsEmpty()) {
2686             RS_LOGD("CheckMergeDisplayDirtyByShadowChanged global merge ShadowValid %{public}s: "
2687                 "global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2688                 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2689                 dirtyRect.ToString().c_str());
2690             curScreenNode_->GetDirtyManager()->MergeDirtyRect(dirtyRect);
2691         }
2692         if (isShadowDisappear) {
2693             surfaceNode.SetShadowValidLastFrame(false);
2694         }
2695     }
2696 }
2697 
CheckMergeDisplayDirtyBySurfaceChanged() const2698 void RSUniRenderVisitor::CheckMergeDisplayDirtyBySurfaceChanged() const
2699 {
2700     std::vector<RectI> surfaceChangedRects = curScreenNode_->GetSurfaceChangedRects();
2701     for (auto& surfaceChangedRect : surfaceChangedRects) {
2702         if (!surfaceChangedRect.IsEmpty()) {
2703             RS_LOGD("CheckMergeDisplayDirtyBySurfaceChanged global merge Surface closed, global dirty %{public}s,"
2704                 "add rect %{public}s",
2705                 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2706                 surfaceChangedRect.ToString().c_str());
2707             curScreenNode_->GetDirtyManager()->MergeDirtyRect(surfaceChangedRect);
2708         }
2709     }
2710 }
2711 
CheckMergeDisplayDirtyByAttractionChanged(RSSurfaceRenderNode & surfaceNode) const2712 void RSUniRenderVisitor::CheckMergeDisplayDirtyByAttractionChanged(RSSurfaceRenderNode& surfaceNode) const
2713 {
2714     if (surfaceNode.GetRenderProperties().IsAttractionValid()) {
2715         auto attractionDirtyRect = surfaceNode.GetRenderProperties().GetAttractionEffectCurrentDirtyRegion();
2716         RS_LOGD("CheckMergeDisplayDirtyByAttraction global merge attraction %{public}s: global dirty %{public}s,"
2717             "add rect %{public}s", surfaceNode.GetName().c_str(),
2718             curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2719             attractionDirtyRect.ToString().c_str());
2720         auto boundsGeometry = curScreenNode_->GetRenderProperties().GetBoundsGeometry();
2721         if (boundsGeometry) {
2722             Drawing::Rect rect(attractionDirtyRect.GetLeft(), attractionDirtyRect.GetTop(),
2723                 attractionDirtyRect.GetRight(), attractionDirtyRect.GetBottom());
2724             Drawing::Rect tempRect;
2725             boundsGeometry->GetMatrix().MapRect(tempRect, rect);
2726             attractionDirtyRect =
2727                 RectI(tempRect.GetLeft(), tempRect.GetTop(), tempRect.GetWidth(), tempRect.GetHeight());
2728         }
2729         curScreenNode_->GetDirtyManager()->MergeDirtyRect(attractionDirtyRect);
2730     }
2731 }
2732 
CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2733 void RSUniRenderVisitor::CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2734 {
2735     if (surfaceNode->GetDirtyManager() == nullptr || curScreenNode_->GetDirtyManager() == nullptr) {
2736         return;
2737     }
2738     // 1 handle last and curframe surfaces which appear or disappear case
2739     CheckMergeDisplayDirtyBySurfaceChanged();
2740     // 2 if the surface node is cross-display and prepared again, convert its dirty region into global.
2741     if (surfaceNode->IsFirstLevelCrossNode() && !curScreenNode_->IsFirstVisitCrossNodeDisplay()) {
2742         CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2743         CheckMergeDisplayDirtyByCrossDisplayWindow(*surfaceNode);
2744         return;
2745     }
2746     // 3 Handles the case of transparent surface, merge transparent dirty rect
2747     CheckMergeDisplayDirtyByTransparent(*surfaceNode);
2748     // 4 Zorder changed case, merge surface dest Rect
2749     CheckMergeDisplayDirtyByZorderChanged(*surfaceNode);
2750     // 5 surfacePos chanded case, merge surface lastframe pos or curframe pos
2751     CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2752     // 6 shadow disappear and appear case.
2753     CheckMergeDisplayDirtyByShadowChanged(*surfaceNode);
2754     // 7 handle surface has attraction effect
2755     CheckMergeDisplayDirtyByAttractionChanged(*surfaceNode);
2756     // More: any other screen dirty caused by surfaceNode should be added here like CheckMergeDisplayDirtByXXX
2757 }
2758 
CheckMergeDisplayDirtyByCrossDisplayWindow(RSSurfaceRenderNode & surfaceNode) const2759 void RSUniRenderVisitor::CheckMergeDisplayDirtyByCrossDisplayWindow(RSSurfaceRenderNode& surfaceNode) const
2760 {
2761     auto geoPtr = surfaceNode.GetRenderProperties().GetBoundsGeometry();
2762     if (!geoPtr) {
2763         return;
2764     }
2765     // transfer from the display coordinate system during quickprepare into current display coordinate system.
2766     auto dirtyRect = geoPtr->MapRect(surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion().ConvertTo<float>(),
2767         surfaceNode.GetCrossNodeSkipDisplayConversionMatrix(curScreenNode_->GetId()));
2768     RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeDisplayDirtyByCrossDisplayWindow %s, global dirty %s, add rect %s",
2769         surfaceNode.GetName().c_str(), curScreenDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
2770         dirtyRect.ToString().c_str());
2771     curScreenDirtyManager_->MergeDirtyRect(dirtyRect);
2772 }
2773 
CollectFilterInCrossDisplayWindow(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedDirtyRegion)2774 void RSUniRenderVisitor::CollectFilterInCrossDisplayWindow(
2775     std::shared_ptr<RSSurfaceRenderNode>& surfaceNode, Occlusion::Region& accumulatedDirtyRegion)
2776 {
2777     auto geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
2778     if (!surfaceNode->IsFirstLevelCrossNode() || curScreenNode_->IsFirstVisitCrossNodeDisplay() || !geoPtr) {
2779         return;
2780     }
2781     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2782     for (auto& child : surfaceNode->GetVisibleFilterChild()) {
2783         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2784         if (!filterNode) {
2785             continue;
2786         }
2787         auto filterRect = geoPtr->MapRect(filterNode->GetAbsDrawRect().ConvertTo<float>(),
2788             surfaceNode->GetCrossNodeSkipDisplayConversionMatrix(curScreenNode_->GetId())).IntersectRect(
2789             curScreenNode_->GetScreenRect());
2790         curScreenDirtyManager_->GetFilterCollector().CollectFilterDirtyRegionInfo(
2791             RSUniFilterDirtyComputeUtil::GenerateFilterDirtyRegionInfo(*filterNode, std::nullopt, true), true);
2792     }
2793 }
2794 
CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode & surfaceNode) const2795 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode& surfaceNode) const
2796 {
2797     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2798     if (surfaceNode.HasContainerWindow()) {
2799         // If a surface's dirty is intersect with container region (which can be considered transparent)
2800         // should be added to Screen dirty region.
2801         // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2802         auto containerRegion = surfaceNode.GetContainerRegion();
2803         auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2804         auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2805         if (!containerDirtyRegion.IsEmpty()) {
2806             RS_LOGD("CheckMergeDisplayDirtyByContainer global merge containerDirtyRegion "
2807                 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2808                 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2809                 containerDirtyRegion.GetRegionInfo().c_str());
2810             // plan: we can use surfacenode's absrect as containerRegion's bound
2811             const auto& rect = containerRegion.GetBoundRef();
2812             curScreenNode_->GetDirtyManager()->MergeDirtyRect(
2813                 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2814         }
2815     } else {
2816         // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2817         // transparent region and opaque region in adjacent frame, may cause Screendirty region incomplete after
2818         // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2819         // which include transparent region but not counted in Screen dirtyregion)
2820         if (!surfaceNode.IsNodeDirty()) {
2821             return;
2822         }
2823         auto transparentRegion = surfaceNode.GetTransparentRegion();
2824         auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2825         Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
2826         if (!transparentDirtyRegion.IsEmpty()) {
2827             RS_LOGD("CheckMergeDisplayDirtyByTransparentRegions global merge TransparentDirtyRegion "
2828                 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2829                 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2830                 transparentDirtyRegion.GetRegionInfo().c_str());
2831             const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
2832             for (const auto& rect : rects) {
2833                 curScreenNode_->GetDirtyManager()->MergeDirtyRect(
2834                     RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2835             }
2836         }
2837     }
2838 }
2839 
AccumulateSurfaceDirtyRegion(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedDirtyRegion) const2840 void RSUniRenderVisitor::AccumulateSurfaceDirtyRegion(
2841     std::shared_ptr<RSSurfaceRenderNode>& surfaceNode, Occlusion::Region& accumulatedDirtyRegion) const
2842 {
2843     auto geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
2844     if (!surfaceNode->GetDirtyManager() || !geoPtr) {
2845         return;
2846     }
2847     auto surfaceDirtyRect = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
2848     if (surfaceNode->IsFirstLevelCrossNode() && !curScreenNode_->IsFirstVisitCrossNodeDisplay()) {
2849         surfaceDirtyRect = geoPtr->MapRect(surfaceDirtyRect.ConvertTo<float>(),
2850             surfaceNode->GetCrossNodeSkipDisplayConversionMatrix(curScreenNode_->GetId()));
2851     }
2852     auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ surfaceDirtyRect } };
2853     auto surfaceVisibleDirtyRegion = surfaceNode->IsMainWindowType() ?
2854         surfaceDirtyRegion.And(surfaceNode->GetVisibleRegion()) : surfaceDirtyRegion;
2855     accumulatedDirtyRegion.OrSelf(surfaceVisibleDirtyRegion);
2856 }
2857 
UpdateDisplayDirtyAndExtendVisibleRegion()2858 void RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion()
2859 {
2860     if (curScreenNode_ == nullptr) {
2861         RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion curScreenNode_ is nullptr");
2862         return;
2863     }
2864     auto& curMainAndLeashSurfaces = curScreenNode_->GetAllMainAndLeashSurfaces();
2865     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2866     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2867         [this, &nodeMap](RSBaseRenderNode::SharedPtr& nodePtr) {
2868         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2869         if (surfaceNode == nullptr) {
2870             RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion surfaceNode is nullptr");
2871             return;
2872         }
2873         if (!surfaceNode->IsMainWindowType()) {
2874             return;
2875         }
2876         Occlusion::Region extendRegion;
2877         if (!surfaceNode->GetVisibleRegion().IsEmpty()) {
2878             ProcessFilterNodeObscured(surfaceNode, extendRegion, nodeMap);
2879         }
2880         surfaceNode->UpdateExtendVisibleRegion(extendRegion);
2881     });
2882 }
2883 
ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & extendRegion,const RSRenderNodeMap & nodeMap)2884 void RSUniRenderVisitor::ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2885     Occlusion::Region& extendRegion, const RSRenderNodeMap& nodeMap)
2886 {
2887     const auto& visibleFilterChild = surfaceNode->GetVisibleFilterChild();
2888     auto visibleRegion = surfaceNode->GetVisibleRegion();
2889     auto currentFrameDirtyRegion = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
2890     auto isTransparent = surfaceNode->IsTransparent();
2891     for (const auto& child : visibleFilterChild) {
2892         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2893         if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
2894             continue;
2895         }
2896         MarkBlurIntersectWithDRM(filterNode);
2897         auto filterRect = filterNode->GetOldDirtyInSurface();
2898         auto visibleRects = visibleRegion.GetRegionRectIs();
2899         auto iter = std::find_if(visibleRects.begin(), visibleRects.end(), [&filterRect](const auto& rect) {
2900             return filterRect.IsInsideOf(rect);
2901         });
2902         if (iter != visibleRects.end()) {
2903             continue;
2904         }
2905         if (!visibleRegion.IsIntersectWith(filterRect)) {
2906             continue;
2907         }
2908         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ filterRect } };
2909         extendRegion = extendRegion.Or(filterRegion);
2910         if (!isTransparent && filterRect.Intersect(currentFrameDirtyRegion)) {
2911             curScreenNode_->GetDirtyManager()->MergeDirtyRect(filterRect);
2912         }
2913     }
2914 }
2915 
UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2916 void RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2917 {
2918     if (surfaceNode == nullptr) {
2919         return;
2920     }
2921     if (surfaceNode->HasBlurFilter()) {
2922         surfaceNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
2923     }
2924     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2925     for (auto& child : surfaceNode->GetVisibleFilterChild()) {
2926         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2927         if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
2928             continue;
2929         }
2930         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode "
2931             "surfaceNode: %s, filterNode:[%lld], IsOccludedByFilterCache:%d", surfaceNode->GetName().c_str(),
2932             filterNode->GetId(), surfaceNode->IsOccludedByFilterCache());
2933         filterNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
2934     }
2935 }
2936 
CollectEffectInfo(RSRenderNode & node)2937 void RSUniRenderVisitor::CollectEffectInfo(RSRenderNode& node)
2938 {
2939     auto nodeParent = node.GetParent().lock();
2940     if (nodeParent == nullptr) {
2941         return;
2942     }
2943     if (RSUniHwcComputeUtil::IsBlendNeedFilter(node) || node.ChildHasVisibleFilter()) {
2944         nodeParent->SetChildHasVisibleFilter(true);
2945         nodeParent->UpdateVisibleFilterChild(node);
2946     }
2947     if ((node.GetRenderProperties().GetUseEffect() || node.ChildHasVisibleEffect()) && node.ShouldPaint()) {
2948         nodeParent->SetChildHasVisibleEffect(true);
2949         nodeParent->UpdateVisibleEffectChild(node);
2950     }
2951     if (node.GetSharedTransitionParam() || node.ChildHasSharedTransition()) {
2952         nodeParent->SetChildHasSharedTransition(true);
2953     }
2954 }
2955 
PostPrepare(RSRenderNode & node,bool subTreeSkipped)2956 CM_INLINE void RSUniRenderVisitor::PostPrepare(RSRenderNode& node, bool subTreeSkipped)
2957 {
2958     UpdateCurFrameInfoDetail(node, subTreeSkipped, true);
2959     if (const auto& sharedTransitionParam = node.GetSharedTransitionParam()) {
2960         sharedTransitionParam->GenerateDrawable(node);
2961     }
2962     auto curDirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curScreenDirtyManager_;
2963     if (!curDirtyManager) {
2964         return;
2965     }
2966     auto isOccluded = curSurfaceNode_ ?
2967         curSurfaceNode_->IsMainWindowType() && curSurfaceNode_->GetVisibleRegion().IsEmpty() : false;
2968     if (subTreeSkipped && (!isOccluded || node.IsFirstLevelCrossNode())) {
2969         hwcVisitor_->UpdateHwcNodeRectInSkippedSubTree(node);
2970         CheckFilterNodeInSkippedSubTreeNeedClearCache(node, *curDirtyManager);
2971         UpdateSubSurfaceNodeRectInSkippedSubTree(node);
2972     }
2973     if (node.NeedUpdateDrawableBehindWindow()) {
2974         node.GetMutableRenderProperties().SetNeedDrawBehindWindow(node.NeedDrawBehindWindow());
2975     }
2976     auto globalFilterRect = node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren() ?
2977         GetVisibleEffectDirty(node) : node.GetOldDirtyInSurface();
2978     auto globalHwcFilterRect = node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren() ?
2979         hwcVisitor_->GetHwcVisibleEffectDirty(node, globalFilterRect) : globalFilterRect;
2980     if (node.NeedDrawBehindWindow()) {
2981         if (isOccluded && !node.IsFirstLevelCrossNode()) {
2982             UpdateChildBlurBehindWindowAbsMatrix(node);
2983         }
2984         node.CalDrawBehindWindowRegion();
2985         globalFilterRect = node.GetFilterRect();
2986     }
2987     if (RSUniHwcComputeUtil::IsBlendNeedBackground(node)) {
2988         hwcVisitor_->UpdateHwcNodeEnableByFilterRect(
2989             curSurfaceNode_, node, node.GetHwcRecorder().GetZOrderForHwcEnableByFilter());
2990     }
2991     if (RSUniHwcComputeUtil::IsBlendNeedFilter(node)) {
2992         node.CalVisibleFilterRect(prepareClipRect_);
2993         node.MarkClearFilterCacheIfEffectChildrenChanged();
2994         CollectFilterInfoAndUpdateDirty(node, *curDirtyManager, globalFilterRect, globalHwcFilterRect);
2995         node.SetGlobalAlpha(curAlpha_);
2996     }
2997     CollectEffectInfo(node);
2998     node.NodePostPrepare(curSurfaceNode_, prepareClipRect_);
2999 
3000     if (isDrawingCacheEnabled_) {
3001         bool isInBlackList = false;
3002         if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
3003             auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
3004             if (surfaceNode.IsLeashWindow() &&
3005                 allBlackList_.find(surfaceNode.GetLeashPersistentId()) != allBlackList_.end()) {
3006                 isInBlackList = true;
3007             }
3008         }
3009         node.UpdateDrawingCacheInfoAfterChildren(isInBlackList);
3010     }
3011     if (auto nodeParent = node.GetParent().lock()) {
3012         nodeParent->UpdateChildUifirstSupportFlag(node.GetUifirstSupportFlag());
3013         nodeParent->GetOpincCache().UpdateSubTreeSupportFlag(
3014             RSOpincManager::Instance().OpincGetNodeSupportFlag(node),
3015             node.GetOpincCache().OpincGetRootFlag(),
3016             nodeParent->GetNodeGroupType() == RSRenderNode::NodeGroupType::NONE);
3017 #ifdef SUBTREE_PARALLEL_ENABLE
3018         nodeParent->UpdateRepaintBoundaryInfo(node);
3019 #endif
3020     }
3021     auto& stagingRenderParams = node.GetStagingRenderParams();
3022     if (stagingRenderParams != nullptr) {
3023         if (node.GetSharedTransitionParam() && node.GetRenderProperties().GetSandBox()) {
3024             stagingRenderParams->SetAlpha(curAlpha_);
3025         } else {
3026             stagingRenderParams->SetAlpha(node.GetRenderProperties().GetAlpha());
3027         }
3028     }
3029 
3030     // Collect prepared subtree into the control-level occlusion culling handler.
3031     // For the surface node, trigger occlusion detection.
3032     CollectSubTreeAndProcessOcclusion(node, subTreeSkipped);
3033 
3034     // planning: only do this if node is dirty
3035     node.UpdateRenderParams();
3036 
3037     // add if node is dirty
3038     node.AddToPendingSyncList();
3039 }
3040 
CollectSubTreeAndProcessOcclusion(OHOS::Rosen::RSRenderNode & node,bool subTreeSkipped)3041 void RSUniRenderVisitor::CollectSubTreeAndProcessOcclusion(OHOS::Rosen::RSRenderNode& node, bool subTreeSkipped)
3042 {
3043     if (!curOcclusionHandler_) {
3044         return;
3045     }
3046 
3047     curOcclusionHandler_->UpdateChildrenOutOfRectInfo(node);
3048     curOcclusionHandler_->CollectSubTree(node, !subTreeSkipped);
3049     if (node.GetId() != curOcclusionHandler_->GetRootNodeId()) {
3050         return;
3051     }
3052 
3053     auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.shared_from_this());
3054     if (surfaceNode == nullptr) {
3055         curOcclusionHandler_ = nullptr;
3056         return;
3057     }
3058     curOcclusionHandler_->UpdateSkippedSubTreeProp();
3059     curOcclusionHandler_->CalculateFrameOcclusion();
3060     auto occlusionParams = surfaceNode->GetOcclusionParams();
3061     occlusionParams->SetCulledNodes(curOcclusionHandler_->TakeCulledNodes());
3062     occlusionParams->SetCulledEntireSubtree(curOcclusionHandler_->TakeCulledEntireSubtree());
3063     occlusionParams->CheckKeyOcclusionNodeValidity(curOcclusionHandler_->GetOcclusionNodes());
3064     curOcclusionHandler_ = nullptr;
3065 }
3066 
MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const3067 void RSUniRenderVisitor::MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const
3068 {
3069     if (!RSSystemProperties::GetDrmMarkedFilterEnabled()) {
3070         return;
3071     }
3072     RSDrmUtil::MarkBlurIntersectWithDRM(node, drmNodes_, curScreenNode_);
3073 }
3074 
CheckFilterNodeInSkippedSubTreeNeedClearCache(const RSRenderNode & rootNode,RSDirtyRegionManager & dirtyManager)3075 void RSUniRenderVisitor::CheckFilterNodeInSkippedSubTreeNeedClearCache(
3076     const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager)
3077 {
3078     bool rotationChanged = curLogicalDisplayNode_ ?
3079         curLogicalDisplayNode_->IsRotationChanged() || curLogicalDisplayNode_->IsLastRotationChanged() : false;
3080     bool rotationStatusChanged = curLogicalDisplayNode_ ?
3081         curLogicalDisplayNode_->GetPreRotationStatus() != curLogicalDisplayNode_->GetCurRotationStatus() : false;
3082     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3083     for (auto& child : rootNode.GetVisibleFilterChild()) {
3084         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3085         if (filterNode == nullptr) {
3086             continue;
3087         }
3088         RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInSkippedSubTreeNeedClearCache node[%lld]", filterNode->GetId());
3089         if (auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode)) {
3090             UpdateRotationStatusForEffectNode(*effectNode);
3091         }
3092         filterNode->CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
3093         filterNode->MarkClearFilterCacheIfEffectChildrenChanged();
3094         if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3095             filterNode->UpdateFilterCacheWithBelowDirty(
3096                 Occlusion::Rect(dirtyManager.GetCurrentFrameDirtyRegion()), false);
3097         }
3098         RectI filterRect;
3099         filterNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, prepareClipRect_);
3100         hwcVisitor_->UpdateHwcNodeEnableByFilterRect(curSurfaceNode_, *filterNode);
3101         CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager, filterRect, filterRect);
3102     }
3103 }
3104 
ResetSubSurfaceNodesCalState(std::vector<std::pair<NodeId,std::weak_ptr<RSSurfaceRenderNode>>> & subSurfaceNodes)3105 inline static void ResetSubSurfaceNodesCalState(
3106     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>>& subSurfaceNodes)
3107 {
3108     for (auto& [id, node] : subSurfaceNodes) {
3109         auto subSurfaceNodePtr = node.lock();
3110         if (!subSurfaceNodePtr) {
3111             continue;
3112         }
3113         subSurfaceNodePtr->SetCalcRectInPrepare(false);
3114     }
3115 }
3116 
UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode & rootNode)3117 void RSUniRenderVisitor::UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3118 {
3119     if (!curSurfaceNode_ || !curSurfaceDirtyManager_) {
3120         return;
3121     }
3122     auto rootGeo = rootNode.GetRenderProperties().GetBoundsGeometry();
3123     if (!rootGeo) {
3124         return;
3125     }
3126 
3127     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
3128     curSurfaceNode_->GetAllSubSurfaceNodes(allSubSurfaceNodes);
3129     for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
3130         auto subSurfaceNodePtr = subSurfaceNode.lock();
3131         Drawing::Matrix absMatrix;
3132         if (!subSurfaceNodePtr || subSurfaceNodePtr->GetCalcRectInPrepare() ||
3133             !subSurfaceNodePtr->GetAbsMatrixReverse(rootNode, absMatrix)) {
3134             continue;
3135         }
3136 
3137         Drawing::RectF absDrawRect;
3138         absMatrix.MapRect(absDrawRect, RSPropertiesPainter::Rect2DrawingRect(subSurfaceNodePtr->GetSelfDrawRect()));
3139         RectI subSurfaceRect = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
3140             absDrawRect.GetWidth(), absDrawRect.GetHeight());
3141 
3142         subSurfaceNodePtr->SetOldDirtyInSurface(subSurfaceRect.IntersectRect(prepareClipRect_));
3143         UpdateNodeVisibleRegion(*subSurfaceNodePtr);
3144         hwcVisitor_->UpdateDstRect(*subSurfaceNodePtr, subSurfaceRect, prepareClipRect_);
3145         subSurfaceNodePtr->SetCalcRectInPrepare(true);
3146         if (subSurfaceNodePtr->IsLeashOrMainWindow()) {
3147             curMainAndLeashWindowNodesIds_.push(subSurfaceNodePtr->GetId());
3148             curScreenNode_->RecordMainAndLeashSurfaces(subSurfaceNodePtr);
3149             curScreenNode_->UpdateSurfaceNodePos(
3150                 subSurfaceNodePtr->GetId(), subSurfaceNodePtr->GetOldDirtyInSurface());
3151             if (auto subSurfaceDirtyManager = subSurfaceNodePtr->GetDirtyManager()) {
3152                 subSurfaceDirtyManager->MergeDirtyRect(subSurfaceNodePtr->GetOldDirtyInSurface().IntersectRect(
3153                     curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion()));
3154             }
3155             CollectOcclusionInfoForWMS(*subSurfaceNodePtr);
3156             subSurfaceNodePtr->UpdateRenderParams();
3157             auto& rateReduceManager = RSMainThread::Instance()->GetRSVsyncRateReduceManager();
3158             rateReduceManager.PushWindowNodeId(subSurfaceNodePtr->GetId());
3159             rateReduceManager.CollectSurfaceVsyncInfo(curScreenNode_->GetScreenInfo(), *subSurfaceNodePtr);
3160         }
3161     }
3162     ResetSubSurfaceNodesCalState(allSubSurfaceNodes);
3163 }
3164 
GetVisibleEffectDirty(RSRenderNode & node) const3165 RectI RSUniRenderVisitor::GetVisibleEffectDirty(RSRenderNode& node) const
3166 {
3167     RectI childEffectRect;
3168     auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3169     for (auto& nodeId : node.GetVisibleEffectChild()) {
3170         if (auto& subnode = nodeMap.GetRenderNode<RSRenderNode>(nodeId)) {
3171             childEffectRect = childEffectRect.JoinRect(subnode->GetOldDirtyInSurface());
3172         }
3173     }
3174     return childEffectRect;
3175 }
3176 
CollectFilterInfoAndUpdateDirty(RSRenderNode & node,RSDirtyRegionManager & dirtyManager,const RectI & globalFilterRect,const RectI & globalHwcFilterRect)3177 void RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty(RSRenderNode& node,
3178     RSDirtyRegionManager& dirtyManager, const RectI& globalFilterRect, const RectI& globalHwcFilterRect)
3179 {
3180     // case - 1. Deal with filter node self dirty.
3181     node.UpdateFilterCacheWithSelfDirty();
3182     // case - 2. Collect filter node with its current below dirty, process later.
3183     dirtyManager.GetFilterCollector().CollectFilterDirtyRegionInfo(
3184         RSUniFilterDirtyComputeUtil::GenerateFilterDirtyRegionInfo(
3185             node, Occlusion::Region(Occlusion::Rect(dirtyManager.GetCurrentFrameDirtyRegion())),
3186             curSurfaceNode_ != nullptr), false);
3187 
3188     if (curSurfaceNode_) {
3189         bool isIntersect = dirtyManager.GetCurrentFrameDirtyRegion().Intersect(globalFilterRect);
3190         if (curSurfaceNode_->IsTransparent()) {
3191             if (!isIntersect || (isIntersect && (node.GetRenderProperties().GetBackgroundFilter() ||
3192                 node.GetRenderProperties().GetNeedDrawBehindWindow()) && !node.IsBackgroundInAppOrNodeSelfDirty())) {
3193                 hwcVisitor_->transparentHwcCleanFilter_[curSurfaceNode_->GetId()].
3194                     push_back({node.GetId(), globalHwcFilterRect});
3195             }
3196             if (isIntersect) {
3197                 hwcVisitor_->transparentHwcDirtyFilter_[curSurfaceNode_->GetId()].
3198                     push_back({node.GetId(), globalHwcFilterRect});
3199             }
3200         }
3201     }
3202 }
3203 
UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode & node)3204 void RSUniRenderVisitor::UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode& node)
3205 {
3206     if (!node.IsLeashWindow()) {
3207         return;
3208     }
3209     auto& property = node.GetMutableRenderProperties();
3210     auto& geoPtr = (property.GetBoundsGeometry());
3211     if (geoPtr == nullptr) {
3212         return;
3213     }
3214     auto absMatrix = geoPtr->GetAbsMatrix();
3215     bool isScale = false;
3216     if (RSUifirstManager::Instance().GetUiFirstType() == UiFirstCcmType::MULTI) {
3217         isScale = (!ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_X), 1.f, EPSILON_SCALE) ||
3218                   !ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_Y), 1.f, EPSILON_SCALE));
3219     } else {
3220         bool getMinMaxScales = false;
3221         // scaleFactors[0]-minimum scaling factor, scaleFactors[1]-maximum scaling factor
3222         Drawing::scalar scaleFactors[2];
3223         getMinMaxScales = absMatrix.GetMinMaxScales(scaleFactors);
3224         if (getMinMaxScales) {
3225             isScale = !ROSEN_EQ(scaleFactors[0], 1.f, EPSILON_SCALE) || !ROSEN_EQ(scaleFactors[1], 1.f, EPSILON_SCALE);
3226         }
3227         if (!getMinMaxScales) {
3228             RS_LOGD("getMinMaxScales fail, node:%{public}s %{public}" PRIu64 "", node.GetName().c_str(), node.GetId());
3229             const auto& dstRect = node.GetDstRect();
3230             float dstRectWidth = dstRect.GetWidth();
3231             float dstRectHeight = dstRect.GetHeight();
3232             float boundsWidth = property.GetBoundsWidth();
3233             float boundsHeight = property.GetBoundsHeight();
3234             isScale =
3235                 !ROSEN_EQ(std::min(dstRectWidth, dstRectHeight), std::min(boundsWidth, boundsHeight), EPSILON_SCALE) ||
3236                 !ROSEN_EQ(std::max(dstRectWidth, dstRectHeight), std::max(boundsWidth, boundsHeight), EPSILON_SCALE);
3237         }
3238     }
3239     node.SetIsScaleInPreFrame(node.IsScale());
3240     node.SetIsScale(isScale);
3241 }
3242 
PrepareRootRenderNode(RSRootRenderNode & node)3243 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
3244 {
3245     RS_TRACE_NAME_FMT("RSUniRender::PrepareRootRenderNode:node[%" PRIu64 "] pid[%d] subTreeDirty[%d]",
3246         node.GetId(), ExtractPid(node.GetId()), node.IsSubTreeDirty());
3247     bool dirtyFlag = dirtyFlag_;
3248     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3249     auto prepareClipRect = prepareClipRect_;
3250 
3251     auto nodeParent = (node.GetParent().lock());
3252     const auto& property = node.GetRenderProperties();
3253     bool geoDirty = property.IsGeoDirty();
3254     auto& geoPtr = (property.GetBoundsGeometry());
3255     auto prevAlpha = curAlpha_;
3256     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
3257 
3258     if (curSurfaceDirtyManager_ == nullptr) {
3259         RS_LOGE_LIMIT(
3260             __func__, __line__, "RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
3261         return;
3262     }
3263     dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
3264         *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
3265     if (nodeParent == curSurfaceNode_) {
3266         const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
3267         const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
3268         Drawing::Matrix gravityMatrix;
3269         (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
3270             RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
3271             rootWidth, rootHeight, gravityMatrix);
3272         // Only Apply gravityMatrix when rootNode is dirty
3273         if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
3274             geoPtr->ConcatMatrix(gravityMatrix);
3275         }
3276     }
3277 
3278     if (geoPtr != nullptr) {
3279         parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3280     }
3281 
3282     node.EnableWindowKeyFrame(false);
3283 
3284     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
3285     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
3286         node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
3287     PostPrepare(node, !isSubTreeNeedPrepare);
3288 
3289     curAlpha_ = prevAlpha;
3290     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3291     dirtyFlag_ = dirtyFlag;
3292     prepareClipRect_ = prepareClipRect;
3293 }
3294 
InitializeOcclusionHandler(RSSurfaceRenderNode & node)3295 void RSUniRenderVisitor::InitializeOcclusionHandler(RSSurfaceRenderNode& node)
3296 {
3297     if (!OcclusionCullingParam::IsIntraAppControlsLevelOcclusionCullingEnable()) {
3298         return;
3299     }
3300     if (curOcclusionHandler_) {
3301         return;
3302     }
3303     auto occlusionParams = node.GetOcclusionParams();
3304     if (!occlusionParams->IsOcclusionCullingOn()) {
3305         return;
3306     }
3307 
3308     curOcclusionHandler_ = occlusionParams->GetOcclusionHandler();
3309     if (curOcclusionHandler_ == nullptr) {
3310         curOcclusionHandler_ = std::make_shared<RSOcclusionHandler>(node.GetId());
3311         occlusionParams->SetOcclusionHandler(curOcclusionHandler_);
3312     }
3313 }
3314 
SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams> & renderThreadParams)3315 void RSUniRenderVisitor::SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams>& renderThreadParams)
3316 {
3317     if (!renderThreadParams) {
3318         RS_LOGE("RSUniRenderVisitor::SetUniRenderThreadParam renderThreadParams is nullptr");
3319         return;
3320     }
3321     renderThreadParams->isPartialRenderEnabled_ = isPartialRenderEnabled_;
3322     renderThreadParams->isRegionDebugEnabled_ = isRegionDebugEnabled_;
3323     renderThreadParams->isDirtyRegionDfxEnabled_ = isDirtyRegionDfxEnabled_;
3324     renderThreadParams->isDisplayDirtyDfxEnabled_ = isDisplayDirtyDfxEnabled_;
3325     renderThreadParams->isMergedDirtyRegionDfxEnabled_ = isMergedDirtyRegionDfxEnabled_;
3326     renderThreadParams->isOpaqueRegionDfxEnabled_ = isOpaqueRegionDfxEnabled_;
3327     renderThreadParams->isVisibleRegionDfxEnabled_ = isVisibleRegionDfxEnabled_;
3328     renderThreadParams->isAllSurfaceVisibleDebugEnabled_ = isAllSurfaceVisibleDebugEnabled_;
3329     renderThreadParams->isTargetDirtyRegionDfxEnabled_ = isTargetDirtyRegionDfxEnabled_;
3330     renderThreadParams->dirtyRegionDebugType_ = dirtyRegionDebugType_;
3331     renderThreadParams->isOpDropped_ = isOpDropped_;
3332     renderThreadParams->isDirtyAlignEnabled_ = isDirtyAlignEnabled_;
3333     renderThreadParams->isStencilPixelOcclusionCullingEnabled_ = isStencilPixelOcclusionCullingEnabled_;
3334     renderThreadParams->isCrossNodeOffscreenOn_ = isCrossNodeOffscreenOn_;
3335     renderThreadParams->isUIFirstDebugEnable_ = isUIFirstDebugEnable_;
3336     renderThreadParams->dfxTargetSurfaceNames_ = std::move(dfxTargetSurfaceNames_);
3337     renderThreadParams->isVirtualDirtyEnabled_ = isVirtualDirtyEnabled_;
3338     renderThreadParams->isVirtualDirtyDfxEnabled_ = isVirtualDirtyDfxEnabled_;
3339     renderThreadParams->isExpandScreenDirtyEnabled_ = isExpandScreenDirtyEnabled_;
3340     renderThreadParams->advancedDirtyType_ = advancedDirtyType_;
3341     renderThreadParams->hasDisplayHdrOn_ = hasDisplayHdrOn_;
3342     renderThreadParams->hasMirrorDisplay_ = hasMirrorDisplay_;
3343     if (RSPointerWindowManager::Instance().IsNeedForceCommitByPointer()) {
3344         renderThreadParams->forceCommitReason_ |= ForceCommitReason::FORCED_BY_POINTER_WINDOW;
3345     }
3346 }
3347 
SendRcdMessage(RSScreenRenderNode & node)3348 void RSUniRenderVisitor::SendRcdMessage(RSScreenRenderNode& node)
3349 {
3350     if (RoundCornerDisplayManager::CheckRcdRenderEnable(curScreenNode_->GetScreenInfo()) &&
3351         RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
3352         using rcd_msg = RSSingleton<RsMessageBus>;
3353         auto& screenInfo = curScreenNode_->GetScreenInfo();
3354         uint32_t left = 0; // render region
3355         uint32_t top = 0;
3356         uint32_t width = screenInfo.width;
3357         uint32_t height = screenInfo.height;
3358         if (!screenInfo.activeRect.IsEmpty()) {
3359             left = static_cast<uint32_t>(std::max(0, screenInfo.activeRect.GetLeft()));
3360             top = static_cast<uint32_t>(std::max(0, screenInfo.activeRect.GetTop()));
3361             width = static_cast<uint32_t>(std::max(0, screenInfo.activeRect.GetWidth()));
3362             height = static_cast<uint32_t>(std::max(0, screenInfo.activeRect.GetHeight()));
3363         }
3364         rcd_msg::GetInstance().SendMsg<NodeId, uint32_t, uint32_t, uint32_t, uint32_t>(TOPIC_RCD_DISPLAY_SIZE,
3365             node.GetId(), left, top, width, height);
3366         // rcd_msg::GetInstance().SendMsg<NodeId, ScreenRotation>(TOPIC_RCD_DISPLAY_ROTATION,
3367         //    node.GetId(), node.GetScreenRotation());
3368         rcd_msg::GetInstance().SendMsg<NodeId, int>(TOPIC_RCD_DISPLAY_NOTCH,
3369             node.GetId(), RSSystemParameters::GetHideNotchStatus());
3370     }
3371 }
3372 
ProcessUnpairedSharedTransitionNode()3373 void RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode()
3374 {
3375     static auto unpairNode = [](const std::weak_ptr<RSRenderNode>& wptr) {
3376         auto sptr = wptr.lock();
3377         if (sptr == nullptr) {
3378             return;
3379         }
3380         // make sure parent regenerates ChildrenDrawable
3381         auto parent = sptr->GetParent().lock();
3382         if (parent == nullptr) {
3383             return;
3384         }
3385         parent->AddDirtyType(ModifierNG::RSModifierType::CHILDREN);
3386         parent->ApplyModifiers();
3387         // avoid changing the paired status or unpairedShareTransitions_
3388         auto param = sptr->GetSharedTransitionParam();
3389         if (param == nullptr) {
3390             ROSEN_LOGE("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: param is null");
3391             return;
3392         }
3393         param->paired_ = false;
3394         SharedTransitionParam::unpairedShareTransitions_.clear();
3395     };
3396     auto unpairedShareTransitions = std::move(SharedTransitionParam::unpairedShareTransitions_);
3397     for (auto& [id, wptr] : unpairedShareTransitions) {
3398         auto sharedTransitionParam = wptr.lock();
3399         // If the unpaired share transition is already deal with, do nothing
3400         if (!sharedTransitionParam) {
3401             continue;
3402         }
3403         sharedTransitionParam->ResetRelation();
3404         if (!sharedTransitionParam->paired_) {
3405             continue;
3406         }
3407         ROSEN_LOGD("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: mark %s as unpaired",
3408             sharedTransitionParam->Dump().c_str());
3409         sharedTransitionParam->paired_ = false;
3410         unpairNode(sharedTransitionParam->inNode_);
3411         unpairNode(sharedTransitionParam->outNode_);
3412     }
3413 }
3414 
CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr> & surfaces)3415 void RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr>& surfaces)
3416 {
3417     // Debug dirtyregion of show current refreshRation
3418     if (!RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
3419         return;
3420     }
3421     if (curScreenNode_ == nullptr) {
3422         RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate  curScreenNode is nullptr");
3423         return;
3424     }
3425     static const RectI refreshDirtyRect = {100, 100, 500, 200};   // setDirtyRegion for RealtimeRefreshRate
3426     bool surfaceNodeSet = false;
3427     for (auto surface : surfaces) {
3428         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
3429         if (surfaceNode == nullptr) {
3430             RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate surfaceNode is nullptr");
3431             continue;
3432         }
3433         if (surfaceNode->GetSurfaceWindowType() == SurfaceWindowType::SCB_GESTURE_BACK) {
3434             // refresh rate rect for mainwindow
3435             auto& surfaceGeoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
3436             if (!surfaceGeoPtr) {
3437                 continue;
3438             }
3439             auto displayNodeId = surfaceNode->GetLogicalDisplayNodeId();
3440             const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3441             auto displayNode = nodeMap.GetRenderNode<RSLogicalDisplayRenderNode>(displayNodeId);
3442             if (!displayNode) {
3443                 continue;
3444             }
3445             auto& displayGeoPtr = displayNode->GetRenderProperties().GetBoundsGeometry();
3446             if (!displayGeoPtr) {
3447                 continue;
3448             }
3449             auto tmpRect = refreshDirtyRect;
3450             auto windowContainer = displayNode->GetWindowContainer();
3451             if (windowContainer &&
3452                 (!ROSEN_EQ(windowContainer->GetRenderProperties().GetScaleX(), 1.0f, EPSILON_SCALE) ||
3453                  !ROSEN_EQ(windowContainer->GetRenderProperties().GetScaleY(), 1.0f, EPSILON_SCALE))) {
3454                 tmpRect = displayGeoPtr->MapAbsRect(tmpRect.ConvertTo<float>());
3455             } else {
3456                 tmpRect = surfaceGeoPtr->MapAbsRect(tmpRect.ConvertTo<float>());
3457             }
3458             curScreenNode_->GetDirtyManager()->MergeDirtyRect(tmpRect, true);
3459             surfaceNodeSet = true;
3460         }
3461     }
3462     if (!surfaceNodeSet) {
3463         for (auto& displayNode : *curScreenNode_->GetChildren()) {
3464             auto& geoPtr = curScreenNode_->GetRenderProperties().GetBoundsGeometry();
3465             if (!geoPtr) {
3466                 continue;
3467             }
3468             auto tmpRect = refreshDirtyRect;
3469             tmpRect = geoPtr->MapAbsRect(tmpRect.ConvertTo<float>());
3470             curScreenNode_->GetDirtyManager()->MergeDirtyRect(tmpRect, true);
3471         }
3472     }
3473 }
3474 
CheckMergeScreenDirtyByRoundCornerDisplay() const3475 void RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay() const
3476 {
3477     if (!screenManager_ || !curScreenNode_) {
3478         RS_LOGE(
3479             "RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay screenmanager or displaynode is nullptr");
3480         return;
3481     }
3482     if (!RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
3483         RS_LOGD("RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay rcd disabled!");
3484         return;
3485     }
3486     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
3487     if (screenManager_->GetScreenType(curScreenNode_->GetScreenId(), screenType) != SUCCESS) {
3488         RS_LOGD("RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay get screen type failed.");
3489         return;
3490     }
3491     if (screenType != EXTERNAL_TYPE_SCREEN) {
3492         RectI dirtyRectTop;
3493         RectI dirtyRectBottom;
3494         if (RSSingleton<RoundCornerDisplayManager>::GetInstance().HandleRoundCornerDirtyRect(
3495             curScreenNode_->GetId(), dirtyRectTop, RoundCornerDisplayManager::RCDLayerType::TOP)) {
3496             RS_LOGD("RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay global merge topRcdNode dirty "
3497                     "%{public}s, global dirty %{public}s, add rect %{public}s",
3498                 std::to_string(curScreenNode_->GetScreenId()).c_str(),
3499                 curScreenDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
3500                 dirtyRectTop.ToString().c_str());
3501             curScreenNode_->GetDirtyManager()->MergeDirtyRect(dirtyRectTop);
3502         }
3503         if (RSSingleton<RoundCornerDisplayManager>::GetInstance().HandleRoundCornerDirtyRect(
3504             curScreenNode_->GetId(), dirtyRectBottom, RoundCornerDisplayManager::RCDLayerType::BOTTOM)) {
3505             RS_LOGD("RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay global merge bottomRcdNode dirty "
3506                     "%{public}s, global dirty %{public}s, add rect %{public}s",
3507                 std::to_string(curScreenNode_->GetScreenId()).c_str(),
3508                 curScreenDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
3509                 dirtyRectBottom.ToString().c_str());
3510             curScreenNode_->GetDirtyManager()->MergeDirtyRect(dirtyRectBottom);
3511         }
3512     }
3513 }
3514 
CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode & node)3515 void RSUniRenderVisitor::CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode& node)
3516 {
3517     bool hasAnim = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
3518     if (!node.IsScale() || hasAnim || curCornerRadius_.IsZero() || curAlpha_ < 1) {
3519         node.SetGpuOverDrawBufferOptimizeNode(false);
3520         return;
3521     }
3522 
3523     for (auto& child : *(node.GetChildren())) {
3524         if (!child || !(child->IsInstanceOf<RSSurfaceRenderNode>() &&
3525             RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashOrMainWindow())) {
3526             continue;
3527         }
3528         auto rootNode = child->GetFirstChild();
3529         if (!rootNode) {
3530             break;
3531         }
3532         auto canvasNode = rootNode->GetFirstChild();
3533         if (!canvasNode) {
3534             break;
3535         }
3536         const auto& surfaceProperties = node.GetRenderProperties();
3537         const auto& canvasProperties = canvasNode->GetRenderProperties();
3538         if (canvasProperties.GetAlpha() >= 1 &&
3539             canvasProperties.GetBackgroundColor().GetAlpha() >= MAX_ALPHA &&
3540             canvasProperties.GetFrameWidth() == surfaceProperties.GetFrameWidth() &&
3541             canvasProperties.GetFrameHeight() == surfaceProperties.GetFrameHeight()) {
3542             node.SetGpuOverDrawBufferOptimizeNode(true);
3543             node.SetOverDrawBufferNodeCornerRadius(curCornerRadius_);
3544             return;
3545         }
3546     }
3547 
3548     node.SetGpuOverDrawBufferOptimizeNode(false);
3549 }
3550 
SetHdrWhenMultiDisplayChange()3551 void RSUniRenderVisitor::SetHdrWhenMultiDisplayChange()
3552 {
3553     auto mainThread = RSMainThread::Instance();
3554     if (!mainThread->GetMultiDisplayChange()) {
3555         return;
3556     }
3557     auto isMultiDisplay = mainThread->GetMultiDisplayStatus();
3558     RS_LOGI("RSUniRenderVisitor::SetHdrWhenMultiDisplayChange closeHdrStatus: %{public}d.", isMultiDisplay);
3559     RS_TRACE_NAME_FMT("RSUniRenderVisitor::SetHdrWhenMultiDisplayChange closeHdrStatus: %d", isMultiDisplay);
3560     RSLuminanceControl::Get().ForceCloseHdr(CLOSEHDR_SCENEID::MULTI_DISPLAY, isMultiDisplay);
3561 }
3562 
TryNotifyUIBufferAvailable()3563 void RSUniRenderVisitor::TryNotifyUIBufferAvailable()
3564 {
3565     for (auto& id : uiBufferAvailableId_) {
3566         const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3567         auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
3568         if (surfaceNode) {
3569             surfaceNode->NotifyUIBufferAvailable();
3570         }
3571     }
3572     uiBufferAvailableId_.clear();
3573 }
3574 
CollectSelfDrawingNodeRectInfo(RSSurfaceRenderNode & node)3575 void RSUniRenderVisitor::CollectSelfDrawingNodeRectInfo(RSSurfaceRenderNode& node)
3576 {
3577     auto& monitor = SelfDrawingNodeMonitor::GetInstance();
3578     if (!monitor.IsListeningEnabled()) {
3579         return;
3580     }
3581 
3582     if (!node.IsSelfDrawingType()) {
3583         return;
3584     }
3585     auto rect = node.GetRenderProperties().GetBoundsGeometry()->GetAbsRect();
3586     monitor.InsertCurRectMap(node.GetId(), rect);
3587 }
3588 
HandleTunnelLayerId(RSSurfaceRenderNode & node)3589 void RSUniRenderVisitor::HandleTunnelLayerId(RSSurfaceRenderNode& node)
3590 {
3591     auto tunnelLayerId = node.GetTunnelLayerId();
3592     if (!tunnelLayerId) {
3593         return;
3594     }
3595     const auto nodeParams = static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
3596     if (nodeParams == nullptr) {
3597         return;
3598     }
3599     nodeParams->SetTunnelLayerId(tunnelLayerId);
3600     RS_LOGI("%{public}s lpp surfaceid:%{public}" PRIu64 ", nodeid:%{public}" PRIu64,
3601         __func__, tunnelLayerId, node.GetId());
3602     RS_TRACE_NAME_FMT("%s lpp surfaceid:%" PRIu64 ", nodeid:%" PRIu64, __func__, tunnelLayerId, node.GetId());
3603 }
3604 
UpdateChildBlurBehindWindowAbsMatrix(RSRenderNode & node)3605 void RSUniRenderVisitor::UpdateChildBlurBehindWindowAbsMatrix(RSRenderNode& node)
3606 {
3607     auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.shared_from_this());
3608     if (!surfaceNode) {
3609         RS_LOGE("RSUniRenderVisitor::UpdateChildBlurBehindWindowAbsMatrix not surfaceNode");
3610         return;
3611     }
3612     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3613     for (auto& childId : surfaceNode->GetChildBlurBehindWindow()) {
3614         auto child = nodeMap.GetRenderNode<RSRenderNode>(childId);
3615         if (!child) {
3616             RS_LOGE("RSUniRenderVisitor::UpdateChildBlurBehindWindowAbsMatrix child[%{public}" PRIu64 "] nullptr",
3617                 childId);
3618             continue;
3619         }
3620         Drawing::Matrix absMatrix;
3621         if (!child->GetAbsMatrixReverse(node, absMatrix)) {
3622             RS_LOGE("RSUniRenderVisitor::UpdateChildBlurBehindWindowAbsMatrix child[%{public}" PRIu64
3623                 "] GetAbsMatrixReverse fail", childId);
3624             continue;
3625         }
3626         child->GetRenderProperties().GetBoundsGeometry()->SetAbsMatrix(absMatrix);
3627     }
3628 }
3629 } // namespace Rosen
3630 } // namespace OHOS