1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "pipeline/rs_uni_render_visitor.h"
17 #include <memory>
18 #include "rs_trace.h"
19 #include "screen_manager/rs_screen_manager.h"
20 
21 #ifdef RS_ENABLE_OLD_VK
22 #include <vulkan_window.h>
23 #endif
24 
25 #include "common/rs_common_def.h"
26 #include "common/rs_common_hook.h"
27 #include "common/rs_obj_abs_geometry.h"
28 #include "common/rs_optional_trace.h"
29 #include "common/rs_singleton.h"
30 #include "luminance/rs_luminance_control.h"
31 #include "memory/rs_tag_tracker.h"
32 #include "params/rs_display_render_params.h"
33 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
34 #include "pipeline/rs_base_render_node.h"
35 #include "pipeline/rs_base_render_util.h"
36 #include "pipeline/rs_display_render_node.h"
37 #include "pipeline/rs_effect_render_node.h"
38 #include "pipeline/rs_paint_filter_canvas.h"
39 #include "pipeline/rs_pointer_window_manager.h"
40 #include "pipeline/rs_realtime_refresh_rate_manager.h"
41 #include "pipeline/rs_root_render_node.h"
42 #include "pipeline/rs_surface_render_node.h"
43 #include "pipeline/rs_uni_render_virtual_processor.h"
44 #include "pipeline/rs_uni_render_util.h"
45 #include "pipeline/rs_uifirst_manager.h"
46 #include "platform/common/rs_log.h"
47 #include "platform/common/rs_system_properties.h"
48 #include "property/rs_properties_painter.h"
49 #include "system/rs_system_parameters.h"
50 #include "hgm_core.h"
51 #include "metadata_helper.h"
52 #include <v1_0/buffer_handle_meta_key_type.h>
53 #include <v1_0/cm_color_space.h>
54 
55 #include "pipeline/round_corner_display/rs_round_corner_display_manager.h"
56 #include "pipeline/round_corner_display/rs_message_bus.h"
57 
58 #include "rs_profiler.h"
59 #ifdef RS_PROFILER_ENABLED
60 #include "rs_profiler_capture_recorder.h"
61 #endif
62 
63 namespace OHOS {
64 namespace Rosen {
65 namespace {
66 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
67 constexpr int MAX_ALPHA = 255;
68 constexpr int TRACE_LEVEL_THREE = 3;
69 constexpr float EPSILON_SCALE = 0.00001f;
70 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
71 constexpr const char* RELIABLE_GESTURE_BACK_SURFACE_NAME = "SCBGestureBack";
72 constexpr int MIN_OVERLAP = 2;
73 static std::map<NodeId, uint32_t> cacheRenderNodeMap = {};
74 static uint32_t g_cacheReuseTimes = 0;
75 static std::mutex cacheRenderNodeMapMutex;
76 
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)77 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
78 {
79     if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
80         auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
81         const auto& property = rootNode->GetRenderProperties();
82         if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
83             return true;
84         }
85     }
86     return false;
87 }
88 
CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)89 bool CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
90 {
91     if (child != nullptr && child->IsInstanceOf<RSCanvasRenderNode>()) {
92         auto canvasRenderNode = child->ReinterpretCastTo<RSCanvasRenderNode>();
93         const auto& property = canvasRenderNode->GetRenderProperties();
94         if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0) {
95             return true;
96         }
97     }
98     return false;
99 }
100 
IsFirstFrameReadyToDraw(const RSSurfaceRenderNode & node)101 bool IsFirstFrameReadyToDraw(const RSSurfaceRenderNode& node)
102 {
103     bool result = false;
104     auto sortedChildren = node.GetSortedChildren();
105     if (node.IsScbScreen() || node.IsSCBNode()) {
106         for (const auto& child : *sortedChildren) {
107             result = CheckScbReadyToDraw(child);
108         }
109         return result;
110     }
111     for (auto& child : *sortedChildren) {
112         result = CheckRootNodeReadyToDraw(child);
113         // when appWindow has abilityComponent node
114         if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
115             for (const auto& surfaceNodeChild : *child->GetSortedChildren()) {
116                 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
117             }
118         }
119     }
120     return result;
121 }
122 
VisibleDataToString(const VisibleData & val)123 std::string VisibleDataToString(const VisibleData& val)
124 {
125     std::stringstream ss;
126     ss << "VisibleData[name, nodeId, visibleLevel]:";
127     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
128     for (const auto& v : val) {
129         auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(v.first);
130         auto name = surfaceNode ? surfaceNode->GetName() : "";
131         ss << "[" << name << ", " << v.first << ", " << v.second << "], ";
132     }
133     return ss.str();
134 }
135 } // namespace
136 
RSUniRenderVisitor()137 RSUniRenderVisitor::RSUniRenderVisitor()
138     : curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
139 {
140     PartialRenderOptionInit();
141     auto mainThread = RSMainThread::Instance();
142     renderEngine_ = mainThread->GetRenderEngine();
143     hasMirrorDisplay_ = mainThread->HasMirrorDisplay();
144     // when occlusion enabled is false, subTree do not skip, but not influence visible region
145     isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
146     isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
147 #ifdef DDGR_ENABLE_FEATURE_OPINC
148     autoCacheEnable_ = RSSystemProperties::IsDdgrOpincEnable();
149 #endif
150     RSTagTracker::UpdateReleaseResourceEnabled(RSSystemProperties::GetReleaseResourceEnabled());
151     isScreenRotationAnimating_ = RSSystemProperties::GetCacheEnabledForRotation();
152     isSkipCanvasNodeOutOfScreen_ = RSSystemParameters::GetSkipCanvasNodeOutofScreenEnabled();
153 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
154     if (renderEngine_ && renderEngine_->GetRenderContext()) {
155         auto subThreadManager = RSSubThreadManager::Instance();
156         subThreadManager->Start(renderEngine_->GetRenderContext().get());
157     }
158 #endif
159     isUIFirstDebugEnable_ = RSSystemProperties::GetUIFirstDebugEnabled();
160     isPrevalidateHwcNodeEnable_ = RSSystemParameters::GetPrevalidateHwcNodeEnabled() &&
161         RSUniHwcPrevalidateUtil::GetInstance().IsLoadSuccess();
162 }
163 
PartialRenderOptionInit()164 void RSUniRenderVisitor::PartialRenderOptionInit()
165 {
166     partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
167     isPartialRenderEnabled_ = (partialRenderType_ != PartialRenderType::DISABLED);
168     isCompleteRenderEnabled_ = (partialRenderType_ == PartialRenderType::SET_DAMAGE_BUT_COMPLETE_RENDER);
169     dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
170     surfaceRegionDebugType_ = RSSystemProperties::GetSurfaceRegionDfxType();
171     isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_) &&
172         (surfaceRegionDebugType_ == SurfaceRegionDebugType::DISABLED);
173     isRegionDebugEnabled_ = (dirtyRegionDebugType_ != DirtyRegionDebugType::DISABLED) ||
174         (surfaceRegionDebugType_ != SurfaceRegionDebugType::DISABLED) || (dfxTargetSurfaceNames_.size() > 0);
175     isVisibleRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::VISIBLE_REGION);
176     isOpaqueRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::OPAQUE_REGION);
177     isAllSurfaceVisibleDebugEnabled_ = RSSystemProperties::GetAllSurfaceVisibleDebugEnabled();
178     isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
179         (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
180     isDisplayDirtyDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
181         (dirtyRegionDebugType_ == DirtyRegionDebugType::DISPLAY_DIRTY);
182     isCanvasNodeSkipDfxEnabled_ = (dirtyRegionDebugType_ == DirtyRegionDebugType::CANVAS_NODE_SKIP_RECT);
183     isOpDropped_ = isPartialRenderEnabled_ &&
184         (partialRenderType_ != PartialRenderType::SET_DAMAGE) && !isRegionDebugEnabled_;
185     isVirtualDirtyDfxEnabled_ = RSSystemProperties::GetVirtualDirtyDebugEnabled();
186     isVirtualDirtyEnabled_ = RSSystemProperties::GetVirtualDirtyEnabled() &&
187         (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL);
188     isExpandScreenDirtyEnabled_ = RSSystemProperties::GetExpandScreenDirtyEnabled();
189 }
190 
RSUniRenderVisitor(const RSUniRenderVisitor & visitor)191 RSUniRenderVisitor::RSUniRenderVisitor(const RSUniRenderVisitor& visitor) : RSUniRenderVisitor()
192 {
193     currentVisitDisplay_ = visitor.currentVisitDisplay_;
194     screenInfo_ = visitor.screenInfo_;
195     displayHasSecSurface_ = visitor.displayHasSecSurface_;
196     displayHasSkipSurface_ = visitor.displayHasSkipSurface_;
197     displayHasProtectedSurface_ = visitor.displayHasProtectedSurface_;
198     displaySpecailSurfaceChanged_ = visitor.displaySpecailSurfaceChanged_;
199     hasCaptureWindow_ = visitor.hasCaptureWindow_;
200     parentSurfaceNodeMatrix_ = visitor.parentSurfaceNodeMatrix_;
201     curAlpha_ = visitor.curAlpha_;
202     dirtyFlag_ = visitor.dirtyFlag_;
203     curDisplayNode_ = visitor.curDisplayNode_;
204     currentFocusedNodeId_ = visitor.currentFocusedNodeId_;
205     prepareClipRect_ = visitor.prepareClipRect_;
206     isOpDropped_ = visitor.isOpDropped_;
207     isPartialRenderEnabled_ = visitor.isPartialRenderEnabled_;
208     isAllSurfaceVisibleDebugEnabled_ = visitor.isAllSurfaceVisibleDebugEnabled_;
209     isHardwareForcedDisabled_ = visitor.isHardwareForcedDisabled_;
210     doAnimate_ = visitor.doAnimate_;
211     isDirty_ = visitor.isDirty_;
212 }
213 
~RSUniRenderVisitor()214 RSUniRenderVisitor::~RSUniRenderVisitor() {}
215 
MergeRemovedChildDirtyRegion(RSRenderNode & node,bool needMap)216 void RSUniRenderVisitor::MergeRemovedChildDirtyRegion(RSRenderNode& node, bool needMap)
217 {
218     if (!node.HasRemovedChild()) {
219         return;
220     }
221     RectI dirtyRect = node.GetChildrenRect();
222     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
223     if (dirtyManager == nullptr || dirtyRect.IsEmpty()) {
224         node.ResetHasRemovedChild();
225         return;
226     }
227 
228     // [planning] merge removed child's rect instead
229     if (needMap) {
230         if (auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry()) {
231             dirtyRect = geoPtr->MapAbsRect(dirtyRect.ConvertTo<float>());
232         }
233         if (!node.HasChildrenOutOfRect()) {
234             dirtyRect = dirtyRect.IntersectRect(node.GetOldClipRect());
235         }
236     } else {
237         dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
238     }
239     dirtyManager->MergeDirtyRect(dirtyRect);
240     RS_OPTIONAL_TRACE_NAME_FMT("MergeRemovedChildDirtyRegion NodeId:%" PRIu64 ", dirty rect:%s",
241         node.GetId(), dirtyRect.ToString().c_str());
242     if (dirtyManager->IsTargetForDfx()) {
243         // since childRect includes multiple rects, defaultly marked as canvas_node
244         dirtyManager->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
245             DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
246     }
247     node.ResetHasRemovedChild();
248 }
249 
CheckColorSpace(RSSurfaceRenderNode & node)250 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
251 {
252     // currently, P3 is the only supported wide color gamut, this may be modified later.
253     if (node.IsAppWindow() && node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
254         newColorSpace_ = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
255         RS_LOGD("RSUniRenderVisitor::CheckColorSpace: node(%{public}s) set new colorgamut %{public}d",
256             node.GetName().c_str(), newColorSpace_);
257     }
258 }
259 
CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode & node)260 void RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode& node)
261 {
262     if (!node.IsOnTheTree()) {
263         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is not on the tree",
264             node.GetName().c_str());
265         return;
266     }
267     if (!node.IsHardwareForcedDisabled()) {
268         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is hardware-enabled",
269             node.GetName().c_str());
270         return;
271     }
272     // currently, P3 is the only supported wide color gamut, this may be modified later.
273     node.UpdateColorSpaceWithMetadata();
274     if (node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
275         newColorSpace_ = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
276         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) set new colorgamut %{public}d",
277             node.GetName().c_str(), newColorSpace_);
278     }
279 }
280 
UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode & node)281 void RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode& node)
282 {
283     const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
284     for (const auto& selfDrawingNode : selfDrawingNodes) {
285         if (newColorSpace_ == GRAPHIC_COLOR_GAMUT_DISPLAY_P3) {
286             RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc: newColorSpace is already DISPLAY_P3.");
287             return;
288         }
289         if (!selfDrawingNode || !selfDrawingNode->GetAncestorDisplayNode().lock()) {
290             RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc selfDrawingNode or ancestorNode is nullptr");
291             continue;
292         }
293         auto ancestor = selfDrawingNode->GetAncestorDisplayNode().lock()->ReinterpretCastTo<RSDisplayRenderNode>();
294         if (ancestor != nullptr && node.GetId() == ancestor->GetId()) {
295             CheckColorSpaceWithSelfDrawingNode(*selfDrawingNode);
296         }
297     }
298 }
299 
HandleColorGamuts(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)300 void RSUniRenderVisitor::HandleColorGamuts(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
301 {
302     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
303     if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
304         RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen type failed.");
305         return;
306     }
307 
308     if (screenType == VIRTUAL_TYPE_SCREEN) {
309         ScreenColorGamut screenColorGamut;
310         if (screenManager->GetScreenColorGamut(node.GetScreenId(), screenColorGamut) != SUCCESS) {
311             RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen color gamut failed.");
312             return;
313         }
314         newColorSpace_ = static_cast<GraphicColorGamut>(screenColorGamut);
315     }
316 
317     node.SetColorSpace(newColorSpace_);
318     newColorSpace_ = GRAPHIC_COLOR_GAMUT_SRGB;
319 }
320 
CheckPixelFormat(RSSurfaceRenderNode & node)321 void RSUniRenderVisitor::CheckPixelFormat(RSSurfaceRenderNode& node)
322 {
323     if (node.GetHDRPresent()) {
324         RS_LOGD("SetHDRPresent true, surfaceNode: %{public}" PRIu64 "", node.GetId());
325         hasUniRenderHdrSurface_ = true;
326     }
327     if (hasFingerprint_) {
328         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat hasFingerprint is true.");
329         return;
330     }
331     if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
332         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat node(%{public}s) did not have buffer.", node.GetName().c_str());
333         return;
334     }
335 
336     const sptr<SurfaceBuffer>& buffer = node.GetRSSurfaceHandler()->GetBuffer();
337 
338     if (node.GetFingerprint()) {
339         hasFingerprint_ = true;
340         newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_1010102;
341         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat newPixelFormat_ is set 1010102 for fingerprint.");
342         return;
343     }
344 
345     auto bufferPixelFormat = buffer->GetFormat();
346     if ((bufferPixelFormat == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
347         bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCBCR_P010 ||
348         bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCRCB_P010) && !IsHardwareComposerEnabled()) {
349         newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_1010102;
350         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat pixelformat is set to 1010102 for 10bit buffer");
351     }
352 }
353 
HandlePixelFormat(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)354 void RSUniRenderVisitor::HandlePixelFormat(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
355 {
356     if (!RSSystemProperties::GetHDRImageEnable()) {
357         hasUniRenderHdrSurface_ = false;
358     }
359     auto stagingDisplayParams = static_cast<RSDisplayRenderParams*>(node.GetStagingRenderParams().get());
360     if (!stagingDisplayParams) {
361         RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get StagingRenderParams failed.");
362         return;
363     }
364     SetHdrWhenMultiDisplayChangeInPC();
365     ScreenId screenId = stagingDisplayParams->GetScreenId();
366     RSLuminanceControl::Get().SetHdrStatus(screenId, hasUniRenderHdrSurface_);
367     bool isHdrOn = RSLuminanceControl::Get().IsHdrOn(screenId);
368     float brightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
369     RS_TRACE_NAME_FMT("HDR:%d, in Unirender:%d brightnessRatio:%f", isHdrOn, hasUniRenderHdrSurface_, brightnessRatio);
370     RS_LOGD("RSUniRenderVisitor::HandlePixelFormat HDR isHdrOn:%{public}d hasUniRenderHdrSurface:%{public}d "
371         "brightnessRatio:%{public}f", isHdrOn, hasUniRenderHdrSurface_, brightnessRatio);
372     if (!hasUniRenderHdrSurface_) {
373         isHdrOn = false;
374     }
375     node.SetHDRPresent(isHdrOn);
376     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
377     if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
378         RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen type failed.");
379         return;
380     }
381 
382     if (screenType == VIRTUAL_TYPE_SCREEN) {
383         if (screenManager->GetPixelFormat(node.GetScreenId(), newPixelFormat_) != SUCCESS) {
384             RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen color gamut failed.");
385         }
386     }
387     stagingDisplayParams->SetNewPixelFormat(newPixelFormat_);
388 }
389 
ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode & node)390 void RSUniRenderVisitor::ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode& node)
391 {
392     // record current frame mainwindow or leashwindow node
393     if (node.IsMainWindowType() || node.IsLeashWindow()) {
394         curMainAndLeashWindowNodesIds_.push(node.GetId());
395         curDisplayNode_->RecordMainAndLeashSurfaces(node.shared_from_this());
396     }
397     // only reset for instance node
398     if (curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetId()) {
399         return;
400     }
401     if (auto directParent = node.GetParent().lock()) {
402         if (auto parentInstance = directParent->GetInstanceRootNode()) {
403             // in case leashwindow is not directParent
404             auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
405             if (surfaceParent && (surfaceParent->IsLeashWindow() || surfaceParent->IsMainWindowType())) {
406                 curSurfaceNode_ = surfaceParent;
407                 curSurfaceDirtyManager_ = surfaceParent->GetDirtyManager();
408                 filterInGlobal_ = surfaceParent->IsTransparent();
409                 return;
410             }
411             curSurfaceNode_ = nullptr;
412             curSurfaceDirtyManager_ = nullptr;
413             filterInGlobal_ = true;
414         }
415     }
416 }
417 
IsHardwareComposerEnabled()418 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
419 {
420     return !isHardwareForcedDisabled_;
421 }
422 
UpdateSecuritySkipAndProtectedLayersRecord(RSSurfaceRenderNode & node)423 void RSUniRenderVisitor::UpdateSecuritySkipAndProtectedLayersRecord(RSSurfaceRenderNode& node)
424 {
425     if (node.GetHasSecurityLayer()) {
426         displayHasSecSurface_[currentVisitDisplay_] = true;
427         curDisplayNode_->AddSecurityLayer(node.IsLeashWindow() ? node.GetLeashPersistentId() : node.GetId());
428     }
429     if (node.GetHasSkipLayer() && node.GetName().find(CAPTURE_WINDOW_NAME) == std::string::npos) {
430         displayHasSkipSurface_[currentVisitDisplay_] = true;
431     }
432     if (node.GetHasProtectedLayer()) {
433         displayHasProtectedSurface_[currentVisitDisplay_] = true;
434     }
435     if (node.IsSpecialLayerChanged()) {
436         displaySpecailSurfaceChanged_[currentVisitDisplay_] = true;
437     }
438 }
439 
UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode & node)440 void RSUniRenderVisitor::UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode& node)
441 {
442     if (!node.IsMainWindowType()) {
443         return;
444     }
445     auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
446     if (!geoPtr) {
447         return;
448     }
449     if (RSUniRenderUtil::GetRotationDegreeFromMatrix(geoPtr->GetAbsMatrix()) % RS_ROTATION_90 != 0) {
450         node.SetIsRotating(true);
451     }
452 }
453 
IsSubTreeOccluded(RSRenderNode & node) const454 bool RSUniRenderVisitor::IsSubTreeOccluded(RSRenderNode& node) const
455 {
456     if (!isOcclusionEnabled_) {
457         return false;
458     }
459     // step1. apply occlusion info for surfacenode and skip fully covered subtree
460     if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
461         auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
462         if (surfaceNode.IsMainWindowType()) {
463             RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::IsSubTreeOccluded node[%s]"
464                 "name:[%s] visibleRegionIsEmpty[%d]",
465                 std::to_string(node.GetId()).c_str(), surfaceNode.GetName().c_str(),
466                 surfaceNode.GetVisibleRegion().IsEmpty());
467             auto isOccluded = hasMirrorDisplay_ ?
468                 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
469             isOccluded = isOccluded && (!RSUifirstManager::Instance().IsSubTreeNeedPrepareForSnapshot(surfaceNode));
470             if (isOccluded && curSurfaceDirtyManager_) {
471                 curSurfaceDirtyManager_->Clear();
472             }
473             surfaceNode.AccmulateDirtyInOcclusion(isOccluded);
474             return isOccluded;
475         }
476     }
477     // step2.1 For partial visible surface, intersected region->rects in surface
478     // step2.2 check if clean subtree in occlusion rects
479     return false;
480 }
481 
ResetDisplayDirtyRegion()482 void RSUniRenderVisitor::ResetDisplayDirtyRegion()
483 {
484     if (!curDisplayDirtyManager_) {
485         return;
486     }
487     if (curDisplayNode_ == nullptr) {
488         return;
489     }
490     bool isNeedNotchUpdate = RSSingleton<RoundCornerDisplayManager>::GetInstance().IsNotchNeedUpdate(
491         curDisplayNode_->GetId(), RSSystemParameters::GetHideNotchStatus());
492     bool ret = CheckScreenPowerChange() ||
493         CheckColorFilterChange() ||
494         CheckCurtainScreenUsingStatusChange() ||
495         IsFirstFrameOfPartialRender() ||
496         IsWatermarkFlagChanged() ||
497         zoomStateChange_ ||
498         isCompleteRenderEnabled_ ||
499         CheckLuminanceStatusChange() ||
500         IsFirstFrameOfOverdrawSwitch() ||
501         IsFirstFrameOfDrawingCacheDfxSwitch() ||
502         isNeedNotchUpdate;
503     if (ret) {
504         curDisplayDirtyManager_->ResetDirtyAsSurfaceSize();
505         RS_LOGD("RSUniRenderVisitor::ResetDisplayDirtyRegion on");
506     }
507 }
508 
CheckScreenPowerChange() const509 bool RSUniRenderVisitor::CheckScreenPowerChange() const
510 {
511     if (!RSMainThread::Instance()->GetScreenPowerOnChanged()) {
512         return false;
513     }
514     RS_LOGD("RSUniRenderVisitor::CheckScreenPowerChange changed");
515     return true;
516 }
517 
CheckCurtainScreenUsingStatusChange() const518 bool RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange() const
519 {
520     if (!RSMainThread::Instance()->IsCurtainScreenUsingStatusChanged()) {
521         return false;
522     }
523     RS_LOGD("RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange changed");
524     return true;
525 }
526 
CheckLuminanceStatusChange()527 bool RSUniRenderVisitor::CheckLuminanceStatusChange()
528 {
529     if (!RSMainThread::Instance()->ExchangeLuminanceChangingStatus()) {
530         return false;
531     }
532     RS_LOGD("RSUniRenderVisitor::CheckLuminanceStatusChange changed");
533     return true;
534 }
535 
IsFirstFrameOfPartialRender() const536 bool RSUniRenderVisitor::IsFirstFrameOfPartialRender() const
537 {
538     if (!RSMainThread::Instance()->IsFirstFrameOfPartialRender()) {
539         return false;
540     }
541     RS_LOGD("FirstFrameOfPartialRender");
542     return true;
543 }
544 
IsFirstFrameOfDrawingCacheDfxSwitch() const545 bool RSUniRenderVisitor::IsFirstFrameOfDrawingCacheDfxSwitch() const
546 {
547     return RSMainThread::Instance()->IsFirstFrameOfDrawingCacheDFXSwitch();
548 }
549 
IsFirstFrameOfOverdrawSwitch() const550 bool RSUniRenderVisitor::IsFirstFrameOfOverdrawSwitch() const
551 {
552     if (!RSMainThread::Instance()->IsFirstFrameOfOverdrawSwitch()) {
553         return false;
554     }
555     RS_LOGD("IsFirstFrameOfOverdrawSwitch");
556     return true;
557 }
558 
IsWatermarkFlagChanged() const559 bool RSUniRenderVisitor::IsWatermarkFlagChanged() const
560 {
561     if (RSMainThread::Instance()->IsWatermarkFlagChanged()) {
562         RS_LOGD("FirstOrLastFrameOfWatermark");
563         return true;
564     } else {
565         return false;
566     }
567 }
568 
UpdateDisplayZoomState()569 void RSUniRenderVisitor::UpdateDisplayZoomState()
570 {
571     if (!curDisplayNode_) {
572         return;
573     }
574     auto scale = curDisplayNode_->GetRenderProperties().GetScale();
575     bool curZoomState = scale.x_ > 1.f || scale.y_ > 1.f;
576     curDisplayNode_->UpdateZoomState(curZoomState);
577     zoomStateChange_ = curZoomState || curDisplayNode_->IsZoomStateChange();
578 }
579 
UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode & node)580 void RSUniRenderVisitor::UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode& node)
581 {
582     // only for virtual screen
583     if (!(node.IsMirrorDisplay())) {
584         return;
585     }
586     auto mirrorNode = node.GetMirrorSource().lock();
587     if (mirrorNode == nullptr || screenManager_ == nullptr) {
588         return;
589     }
590     auto securityExemptionList = screenManager_->GetVirtualScreenSecurityExemptionList(node.GetScreenId());
591     if (securityExemptionList.size() == 0) {
592         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:false",
593             node.GetId());
594         node.SetSecurityExemption(false);
595         mirrorNode->ClearSecurityLayerList();
596         return;
597     }
598     auto securityLayerList = mirrorNode->GetSecurityLayerList();
599     for (const auto& exemptionLayer : securityExemptionList) {
600         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
601             "securityExemption nodeId %{public}" PRIu64 ".", node.GetId(), exemptionLayer);
602     }
603     for (const auto& secLayer : securityLayerList) {
604         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
605             "securityLayer nodeId %{public}" PRIu64 ".", mirrorNode->GetId(), secLayer);
606     }
607     bool isSecurityExemption = false;
608     if (securityExemptionList.size() >= securityLayerList.size()) {
609         isSecurityExemption = true;
610         for (const auto& secLayer : securityLayerList) {
611             if (std::find(securityExemptionList.begin(), securityExemptionList.end(), secLayer) ==
612                 securityExemptionList.end()) {
613                 isSecurityExemption = false;
614                 break;
615             }
616         }
617     }
618     RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:%{public}d",
619         node.GetId(), isSecurityExemption);
620     node.SetSecurityExemption(isSecurityExemption);
621     mirrorNode->ClearSecurityLayerList();
622 }
623 
QuickPrepareDisplayRenderNode(RSDisplayRenderNode & node)624 void RSUniRenderVisitor::QuickPrepareDisplayRenderNode(RSDisplayRenderNode& node)
625 {
626     // 0. init display info
627     RS_TRACE_NAME("RSUniRender:QuickPrepareDisplayRenderNode " + std::to_string(node.GetScreenId()));
628     if (!InitDisplayInfo(node)) {
629         return;
630     }
631     UpdateDisplayZoomState();
632     SendRcdMessage(node);
633     UpdateVirtualScreenSecurityExemption(node);
634     ancestorNodeHasAnimation_ = false;
635     displayNodeRotationChanged_ = node.IsRotationChanged();
636     dirtyFlag_ = isDirty_ || displayNodeRotationChanged_ || zoomStateChange_;
637     prepareClipRect_ = screenRect_;
638     hasAccumulatedClip_ = false;
639 
640     curAlpha_ = 1.0f;
641     globalZOrder_ = 0.0f;
642     hasSkipLayer_ = false;
643     node.UpdateRotation();
644     if (!(RSMainThread::Instance()->IsRequestedNextVSync() || RSMainThread::Instance()->GetNextDVsyncAnimateFlag())) {
645         RS_OPTIONAL_TRACE_NAME_FMT("do not request next vsync");
646         needRequestNextVsync_ = false;
647     }
648     RSUifirstManager::Instance().SetRotationChanged(displayNodeRotationChanged_ || isScreenRotationAnimating_);
649     if (node.IsSubTreeDirty() || node.IsRotationChanged()) {
650         QuickPrepareChildren(node);
651     }
652     PostPrepare(node);
653     UpdateHwcNodeEnable();
654     UpdateSurfaceDirtyAndGlobalDirty();
655     UpdateSurfaceOcclusionInfo();
656     if (needRecalculateOcclusion_) {
657         // Callback for registered self drawing surfacenode
658         RSMainThread::Instance()->SurfaceOcclusionCallback();
659     }
660     //UIFirst layer must be above displayNode, so use zorder + 1
661     RSUifirstManager::Instance().UpdateUIFirstLayerInfo(screenInfo_, globalZOrder_ + 1);
662     curDisplayNode_->UpdatePartialRenderParams();
663     RSDisplayRenderNode::ScreenRenderParams screenRenderParams;
664     screenRenderParams.screenInfo = std::move(screenInfo_);
665     screenRenderParams.displayHasSecSurface = std::move(displayHasSecSurface_);
666     screenRenderParams.displayHasSkipSurface = std::move(displayHasSkipSurface_);
667     screenRenderParams.displayHasProtectedSurface = std::move(displayHasProtectedSurface_);
668     screenRenderParams.displaySpecailSurfaceChanged = std::move(displaySpecailSurfaceChanged_);
669     screenRenderParams.hasCaptureWindow = std::move(hasCaptureWindow_);
670     curDisplayNode_->UpdateScreenRenderParams(screenRenderParams);
671     curDisplayNode_->UpdateOffscreenRenderParams(curDisplayNode_->IsRotationChanged());
672     UpdateColorSpaceAfterHwcCalc(node);
673     HandleColorGamuts(node, screenManager_);
674     HandlePixelFormat(node, screenManager_);
675     if (UNLIKELY(!SharedTransitionParam::unpairedShareTransitions_.empty())) {
676         ProcessUnpairedSharedTransitionNode();
677     }
678     node.RenderTraceDebug();
679 }
680 
CheckFilterCacheNeedForceClearOrSave(RSRenderNode & node)681 void RSUniRenderVisitor::CheckFilterCacheNeedForceClearOrSave(RSRenderNode& node)
682 {
683     if (!node.HasBlurFilter()) {
684         return;
685     }
686     bool rotationChanged = curDisplayNode_ ?
687         curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
688     bool rotationStatusChanged = curDisplayNode_ ?
689         curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
690     node.CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
691 }
692 
693 // private method, curDisplayNode_ or curSurfaceNode_ will not be nullptr
CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet & filterSet,bool isGlobalDirty)694 void RSUniRenderVisitor::CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet& filterSet, bool isGlobalDirty)
695 {
696     // Recursively traverses until the globalDirty do not change
697     auto dirtyManager = isGlobalDirty ? curDisplayNode_->GetDirtyManager() : curSurfaceNode_->GetDirtyManager();
698     if (dirtyManager == nullptr) {
699         return;
700     }
701     for (auto it = filterSet.begin(); it != filterSet.end();) {
702         auto dirtyRect = dirtyManager->GetCurrentFrameDirtyRegion();
703         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
704         auto dirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
705         auto filterDirtyRegion = filterRegion.And(dirtyRegion);
706         if (!filterDirtyRegion.IsEmpty()) {
707             if (isGlobalDirty) {
708                 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
709                     "global dirty %{public}s, add filterRegion %{public}s",
710                     dirtyRect.ToString().c_str(), (it->second).ToString().c_str());
711             }
712             dirtyManager->MergeDirtyRect(it->second);
713             it = filterSet.erase(it);
714             if (dirtyRect != dirtyManager->GetCurrentFrameDirtyRegion()) {
715                 // When dirtyRegion is changed, collect dirty filter region from begin.
716                 // After all filter region is added, the cycle will definitely stop.
717                 it = filterSet.begin();
718             }
719         } else {
720             ++it;
721         }
722     }
723     filterSet.clear();
724 }
725 
QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode & node)726 void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
727 {
728     RS_OPTIONAL_TRACE_NAME_FMT("RSUniRender::QuickPrepare:[%s] nodeId[%" PRIu64 "]"
729         "pid[%d] nodeType[%u] subTreeDirty[%d]", node.GetName().c_str(), node.GetId(), ExtractPid(node.GetId()),
730         static_cast<uint>(node.GetSurfaceNodeType()), node.IsSubTreeDirty());
731     RS_LOGD("RSUniRender::QuickPrepareSurfaceRenderNode:[%{public}s] nodeid:[%{public}" PRIu64 "]"
732         "pid:[%{public}d] nodeType:[%{public}d] subTreeDirty[%{public}d]", node.GetName().c_str(), node.GetId(),
733         ExtractPid(node.GetId()), static_cast<int>(node.GetSurfaceNodeType()), node.IsSubTreeDirty());
734 
735     // 0. init curSurface info and check node info
736     auto curCornerRadius = curCornerRadius_;
737     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
738     if (!BeforeUpdateSurfaceDirtyCalc(node)) {
739         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode BeforeUpdateSurfaceDirtyCalc fail");
740         RSUifirstManager::Instance().DisableUifirstNode(node);
741         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
742         return;
743     }
744 
745     if (curSurfaceDirtyManager_ == nullptr) {
746         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
747             node.GetName().c_str());
748         return;
749     }
750 
751     // 1. Update matrix and collect dirty region
752     auto dirtyFlag = dirtyFlag_;
753     auto prepareClipRect = prepareClipRect_;
754     bool hasAccumulatedClip = hasAccumulatedClip_;
755     auto prevAlpha = curAlpha_;
756     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
757     node.SetGlobalAlpha(curAlpha_);
758     CheckFilterCacheNeedForceClearOrSave(node);
759     node.CheckContainerDirtyStatusAndUpdateDirty(curContainerDirty_);
760     dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
761         *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix);
762     auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
763     if (!geoPtr) {
764         return;
765     }
766     parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
767     if (!AfterUpdateSurfaceDirtyCalc(node)) {
768         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode AfterUpdateSurfaceDirtyCalc fail");
769         RSUifirstManager::Instance().DisableUifirstNode(node);
770         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
771         return;
772     }
773     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
774     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_, IsSubTreeOccluded(node)) ||
775         ForcePrepareSubTree();
776     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
777         node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
778 
779     // Update whether leash window's visible region is empty after prepare children
780     UpdateLeashWindowVisibleRegionEmpty(node);
781 
782     if (node.IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()) {
783         CheckIsGpuOverDrawBufferOptimizeNode(node);
784     }
785     PostPrepare(node, !isSubTreeNeedPrepare);
786     if (node.IsHardwareEnabledTopSurface() && node.shared_from_this()) {
787         UpdateHwcNodeProperty(node.shared_from_this()->ReinterpretCastTo<RSSurfaceRenderNode>());
788     }
789     CheckMergeFilterDirtyByIntersectWithDirty(curSurfaceNoBelowDirtyFilter_, false);
790     curAlpha_ = prevAlpha;
791     prepareClipRect_ = prepareClipRect;
792     hasAccumulatedClip_ = hasAccumulatedClip;
793     dirtyFlag_ = dirtyFlag;
794 
795     PrepareForUIFirstNode(node);
796     node.OpincSetInAppStateEnd(unchangeMarkInApp_);
797     ResetCurSurfaceInfoAsUpperSurfaceParent(node);
798     curCornerRadius_ = curCornerRadius;
799     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
800     node.RenderTraceDebug();
801     node.SetNeedOffscreen(isScreenRotationAnimating_);
802     if (node.NeedUpdateDrawableBehindWindow()) {
803         RSMainThread::Instance()->RequestNextVSync("drawBehindWindow");
804     }
805 }
806 
PrepareForUIFirstNode(RSSurfaceRenderNode & node)807 void RSUniRenderVisitor::PrepareForUIFirstNode(RSSurfaceRenderNode& node)
808 {
809     MultiThreadCacheType lastFlag = node.GetLastFrameUifirstFlag();
810     RSUifirstManager::Instance().UpdateUifirstNodes(node, ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation());
811     RSUifirstManager::Instance().UpdateUIFirstNodeUseDma(node, globalSurfaceBounds_);
812     if (node.GetLastFrameUifirstFlag() == MultiThreadCacheType::LEASH_WINDOW &&
813         !node.IsHardwareForcedDisabled()) {
814         if (auto& geo = node.GetRenderProperties().GetBoundsGeometry()) {
815             UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
816         }
817         UpdateHwcNodeByTransform(node);
818     }
819     if (RSUifirstManager::Instance().GetUseDmaBuffer(node.GetName()) && curSurfaceDirtyManager_ &&
820         (node.GetLastFrameUifirstFlag() != lastFlag ||
821         !node.IsHardwareForcedDisabled() != node.GetIsLastFrameHwcEnabled())) {
822         curSurfaceDirtyManager_->MergeDirtyRect(node.GetOldDirty());
823     }
824 }
825 
UpdateNodeVisibleRegion(RSSurfaceRenderNode & node)826 void RSUniRenderVisitor::UpdateNodeVisibleRegion(RSSurfaceRenderNode& node)
827 {
828     Occlusion::Rect selfDrawRect = node.GetSurfaceOcclusionRect(true);
829     Occlusion::Region selfDrawRegion { selfDrawRect };
830     if (needRecalculateOcclusion_) {
831         Occlusion::Region subResult = selfDrawRegion.Sub(accumulatedOcclusionRegion_);
832         node.SetVisibleRegion(subResult);
833         Occlusion::Region subResultWithoutSkipLayer = selfDrawRegion.Sub(occlusionRegionWithoutSkipLayer_);
834         node.SetVisibleRegionInVirtual(subResultWithoutSkipLayer);
835     }
836     RS_OPTIONAL_TRACE_NAME_FMT_LEVEL(TRACE_LEVEL_THREE,
837         "RSUniRenderVisitor::UpdateNodeVisibleRegion name[%s] visibleRegion[%s]",
838         node.GetName().c_str(), node.GetVisibleRegion().GetRegionInfo().c_str());
839 }
840 
CalculateOcclusion(RSSurfaceRenderNode & node)841 void RSUniRenderVisitor::CalculateOcclusion(RSSurfaceRenderNode& node)
842 {
843     if (!curDisplayNode_) {
844         RS_LOGE("RSUniRenderVisitor::CalculateOcclusion curDisplayNode is nullptr");
845         return;
846     }
847     // CheckAndUpdateOpaqueRegion only in mainWindow
848     auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
849     auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
850         (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
851     node.CheckAndUpdateOpaqueRegion(screenRect_, curDisplayNode_->GetRotation(), isFocused);
852     if (!needRecalculateOcclusion_) {
853         needRecalculateOcclusion_ = node.CheckIfOcclusionChanged();
854     }
855     // Update node visibleRegion
856     hasSkipLayer_ = hasSkipLayer_ || node.GetSkipLayer();
857     UpdateNodeVisibleRegion(node);
858     auto mainThread = RSMainThread::Instance();
859     node.SetOcclusionInSpecificScenes(mainThread->GetDeviceType() == DeviceType::PC &&
860         mainThread->IsPCThreeFingerScenesListScene());
861     // check current surface Participate In Occlusion
862     if (node.CheckParticipateInOcclusion() && !isAllSurfaceVisibleDebugEnabled_) {
863         accumulatedOcclusionRegion_.OrSelf(node.GetOpaqueRegion());
864         std::unordered_set<NodeId> currentBlackList = GetCurrentBlackList();
865         if (IsValidInVirtualScreen(node) && currentBlackList.find(node.GetId()) == currentBlackList.end()) {
866             occlusionRegionWithoutSkipLayer_.OrSelf(node.GetOpaqueRegion());
867         }
868     }
869     node.SetOcclusionInSpecificScenes(false);
870     CollectOcclusionInfoForWMS(node);
871 }
872 
CollectOcclusionInfoForWMS(RSSurfaceRenderNode & node)873 void RSUniRenderVisitor::CollectOcclusionInfoForWMS(RSSurfaceRenderNode& node)
874 {
875     if (!node.IsMainWindowType()) {
876         return;
877     }
878     // collect mainWindow occlusion visibleLevel
879     Occlusion::Region selfDrawRegion { node.GetSurfaceOcclusionRect(true) };
880     auto visibleLevel = GetRegionVisibleLevel(node.GetVisibleRegion(), selfDrawRegion);
881     // wms default all visible about sefdrawing node and AbilityComponent node
882     auto instanceNode = node.GetInstanceRootNode() ?
883         node.GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
884     if (instanceNode == nullptr) {
885         return;
886     }
887     if ((node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
888         !instanceNode->GetVisibleRegion().IsEmpty()) || node.IsAbilityComponent()) {
889         dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
890             WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
891         return;
892     }
893     dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
894         node.GetVisibleLevelForWMS(visibleLevel)));
895 }
896 
SurfaceOcclusionCallbackToWMS()897 void RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS()
898 {
899     if (RSSystemParameters::GetOcclusionCallBackToWMSDebugType()) {
900         allDstCurVisVec_.clear();
901         const auto& curAllSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
902         for (const auto& surfacePtr : curAllSurfaces) {
903             if (surfacePtr == nullptr) {
904                 continue;
905             }
906             const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*surfacePtr);
907             if (surfaceNode.IsMainWindowType()) {
908                 allDstCurVisVec_.emplace_back(std::make_pair(surfacePtr->GetId(),
909                     WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
910             }
911         }
912     }
913     if (allDstCurVisVec_ != allLastVisVec_) {
914         RSMainThread::Instance()->SurfaceOcclusionChangeCallback(allDstCurVisVec_);
915         RS_LOGI("RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS %{public}s",
916             VisibleDataToString(allDstCurVisVec_).c_str());
917         allLastVisVec_ = std::move(allDstCurVisVec_);
918     }
919 }
920 
GetCurrentBlackList() const921 const std::unordered_set<NodeId> RSUniRenderVisitor::GetCurrentBlackList() const
922 {
923     if (!screenManager_ || !curDisplayNode_) {
924         return std::unordered_set<NodeId>();
925     }
926 
927     std::unordered_set<NodeId> currentBlackList;
928     if (screenManager_->GetCastScreenEnableSkipWindow(curDisplayNode_->GetScreenId())) {
929         screenManager_->GetCastScreenBlackList(currentBlackList);
930     } else {
931         currentBlackList = screenManager_->GetVirtualScreenBlackList(curDisplayNode_->GetScreenId());
932     }
933     return currentBlackList;
934 }
935 
GetRegionVisibleLevel(const Occlusion::Region & visibleRegion,const Occlusion::Region & selfDrawRegion)936 RSVisibleLevel RSUniRenderVisitor::GetRegionVisibleLevel(const Occlusion::Region& visibleRegion,
937     const Occlusion::Region& selfDrawRegion)
938 {
939     if (visibleRegion.IsEmpty()) {
940         return RSVisibleLevel::RS_INVISIBLE;
941     } else if (visibleRegion.Area() == selfDrawRegion.Area()) {
942         return RSVisibleLevel::RS_ALL_VISIBLE;
943     } else if (static_cast<uint>(visibleRegion.Area()) <
944         (static_cast<uint>(selfDrawRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
945         return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
946     }
947     return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
948 }
949 
QuickPrepareEffectRenderNode(RSEffectRenderNode & node)950 void RSUniRenderVisitor::QuickPrepareEffectRenderNode(RSEffectRenderNode& node)
951 {
952     // 0. check current node need to tranverse
953     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
954     if (!dirtyManager) {
955         RS_LOGE("RSUniRenderVisitor::QuickPrepareEffectRenderNode dirtyManager is nullptr");
956         return;
957     }
958     auto dirtyFlag = dirtyFlag_;
959     auto prevAlpha = curAlpha_;
960     auto curCornerRadius = curCornerRadius_;
961     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
962     UpdateRotationStatusForEffectNode(node);
963     CheckFilterCacheNeedForceClearOrSave(node);
964     RectI prepareClipRect = prepareClipRect_;
965     bool hasAccumulatedClip = hasAccumulatedClip_;
966     dirtyFlag_ =
967         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
968     node.UpdateCurCornerRadius(curCornerRadius_);
969     // 1. Recursively traverse child nodes
970     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
971     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
972     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
973         node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
974 
975     PostPrepare(node, !isSubTreeNeedPrepare);
976     prepareClipRect_ = prepareClipRect;
977     hasAccumulatedClip_ = hasAccumulatedClip;
978     dirtyFlag_ = dirtyFlag;
979     curAlpha_ = prevAlpha;
980     curCornerRadius_ = curCornerRadius;
981     node.RenderTraceDebug();
982 }
983 
QuickPrepareCanvasRenderNode(RSCanvasRenderNode & node)984 void RSUniRenderVisitor::QuickPrepareCanvasRenderNode(RSCanvasRenderNode& node)
985 {
986     // 0. check current node need to traverse
987     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
988     auto dirtyFlag = dirtyFlag_;
989     auto prevAlpha = curAlpha_;
990     auto curCornerRadius = curCornerRadius_;
991     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
992     CheckFilterCacheNeedForceClearOrSave(node);
993     if (isDrawingCacheEnabled_) {
994         node.UpdateDrawingCacheInfoBeforeChildren(isScreenRotationAnimating_);
995     }
996     node.OpincQuickMarkStableNode(unchangeMarkInApp_, unchangeMarkEnable_,
997         RSMainThread::Instance()->IsAccessibilityConfigChanged());
998 
999     RectI prepareClipRect = prepareClipRect_;
1000     bool hasAccumulatedClip = hasAccumulatedClip_;
1001 
1002     if (!dirtyManager) {
1003         return;
1004     }
1005     dirtyFlag_ =
1006         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1007     // update prepare clip before children
1008     UpdatePrepareClip(node);
1009     node.UpdateCurCornerRadius(curCornerRadius_);
1010 
1011     // 1. Recursively traverse child nodes if above curSurfaceNode and subnode need draw
1012     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1013     bool isSubTreeNeedPrepare = !curSurfaceNode_ || node.IsSubTreeNeedPrepare(filterInGlobal_) ||
1014         ForcePrepareSubTree() || node.OpincForcePrepareSubTree();
1015     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1016         node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1017 
1018     PostPrepare(node, !isSubTreeNeedPrepare);
1019     prepareClipRect_ = prepareClipRect;
1020     hasAccumulatedClip_ = hasAccumulatedClip;
1021     dirtyFlag_ = dirtyFlag;
1022     curAlpha_ = prevAlpha;
1023     curCornerRadius_ = curCornerRadius;
1024     node.OpincUpdateRootFlag(unchangeMarkEnable_);
1025     node.RenderTraceDebug();
1026 }
1027 
UpdateRotationStatusForEffectNode(RSEffectRenderNode & node)1028 void RSUniRenderVisitor::UpdateRotationStatusForEffectNode(RSEffectRenderNode& node)
1029 {
1030      // folding/expanding screen force invalidate cache.
1031     node.SetFoldStatusChanged(doAnimate_ &&
1032         curDisplayNode_->GetScreenId() != node.GetCurrentAttachedScreenId());
1033     node.SetCurrentAttachedScreenId(curDisplayNode_->GetScreenId());
1034     node.SetRotationChanged(curDisplayNode_->IsRotationChanged());
1035 }
1036 
UpdatePrepareClip(RSRenderNode & node)1037 void RSUniRenderVisitor::UpdatePrepareClip(RSRenderNode& node)
1038 {
1039     const auto& property = node.GetRenderProperties();
1040     auto& geoPtr = property.GetBoundsGeometry();
1041     if (geoPtr == nullptr) {
1042         return;
1043     }
1044     // Dirty Region use abstract coordinate, property of node use relative coordinate
1045     // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
1046     if (property.GetClipToBounds()) {
1047         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
1048     }
1049     // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
1050     if (property.GetClipToFrame()) {
1051         // MapAbsRect do not handle the translation of OffsetX and OffsetY
1052         RectF frameRect{
1053             property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
1054             property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
1055             property.GetFrameWidth(), property.GetFrameHeight()};
1056         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
1057     }
1058     if (property.GetClipToRRect()) {
1059         RectF rect = property.GetClipRRect().rect_;
1060         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(rect));
1061     }
1062 }
1063 
IsLeashAndHasMainSubNode(RSRenderNode & node) const1064 bool RSUniRenderVisitor::IsLeashAndHasMainSubNode(RSRenderNode& node) const
1065 {
1066     if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1067         return false;
1068     }
1069     const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1070     if (!surfaceNode.IsLeashWindow()) {
1071         return false;
1072     }
1073     // check leashWindow surface has first level mainwindow node
1074     auto children = node.GetSortedChildren();
1075     auto iter = std::find_if((*children).begin(), (*children).end(),
1076         [](const std::shared_ptr<RSRenderNode>& node) {
1077         if (node && node->GetType() == RSRenderNodeType::SURFACE_NODE) {
1078             const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*node);
1079             return surfaceNode.IsMainWindowType();
1080         }
1081         return false;
1082     });
1083     return iter != (*children).end();
1084 }
1085 
NeedPrepareChindrenInReverseOrder(RSRenderNode & node) const1086 bool RSUniRenderVisitor::NeedPrepareChindrenInReverseOrder(RSRenderNode& node) const
1087 {
1088     if (!curSurfaceNode_ && node.GetType() != RSRenderNodeType::RS_NODE) {
1089         return true;
1090     }
1091     return IsLeashAndHasMainSubNode(node);
1092 }
1093 
QuickPrepareChildren(RSRenderNode & node)1094 void RSUniRenderVisitor::QuickPrepareChildren(RSRenderNode& node)
1095 {
1096     MergeRemovedChildDirtyRegion(node, true);
1097     if (node.LastFrameSubTreeSkipped() && curSurfaceDirtyManager_) {
1098         node.ForceMergeSubTreeDirtyRegion(*curSurfaceDirtyManager_, prepareClipRect_);
1099     }
1100     bool animationBackup = ancestorNodeHasAnimation_;
1101     ancestorNodeHasAnimation_ = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
1102     node.ResetChildRelevantFlags();
1103     node.ResetChildUifirstSupportFlag();
1104     auto children = node.GetSortedChildren();
1105     if (NeedPrepareChindrenInReverseOrder(node)) {
1106         std::for_each((*children).rbegin(), (*children).rend(), [this](const std::shared_ptr<RSRenderNode>& node) {
1107             if (!node) {
1108                 return;
1109             }
1110             auto containerDirty = curContainerDirty_;
1111             curDirty_ = node->IsDirty();
1112             curContainerDirty_ = curContainerDirty_ || node->IsDirty();
1113             node->QuickPrepare(shared_from_this());
1114             curContainerDirty_ = containerDirty;
1115         });
1116     } else {
1117         std::for_each((*children).begin(), (*children).end(), [this](const std::shared_ptr<RSRenderNode>& node) {
1118             if (!node) {
1119                 return;
1120             }
1121             curDirty_ = node->IsDirty();
1122             node->QuickPrepare(shared_from_this());
1123         });
1124     }
1125     ancestorNodeHasAnimation_ = animationBackup;
1126     node.ResetGeoUpdateDelay();
1127 }
1128 
InitDisplayInfo(RSDisplayRenderNode & node)1129 bool RSUniRenderVisitor::InitDisplayInfo(RSDisplayRenderNode& node)
1130 {
1131     // 1 init curDisplay and curDisplayDirtyManager
1132     currentVisitDisplay_ = node.GetScreenId();
1133     displayHasSecSurface_.emplace(currentVisitDisplay_, false);
1134     displayHasSkipSurface_.emplace(currentVisitDisplay_, false);
1135     displayHasProtectedSurface_.emplace(currentVisitDisplay_, false);
1136     displaySpecailSurfaceChanged_.emplace(currentVisitDisplay_, false);
1137     hasCaptureWindow_.emplace(currentVisitDisplay_, false);
1138     curDisplayDirtyManager_ = node.GetDirtyManager();
1139     curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
1140     if (!curDisplayDirtyManager_ || !curDisplayNode_) {
1141         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo dirtyMgr or node ptr is nullptr");
1142         return false;
1143     }
1144     curDisplayDirtyManager_->Clear();
1145     transparentCleanFilter_.clear();
1146     transparentDirtyFilter_.clear();
1147 
1148     // 2 init screenManager info
1149     screenManager_ = CreateOrGetScreenManager();
1150     if (!screenManager_) {
1151         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo screenManager_ is nullptr");
1152         return false;
1153     }
1154     screenInfo_ = screenManager_->QueryScreenInfo(node.GetScreenId());
1155     curDisplayDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1156     screenRect_ = RectI{0, 0, screenInfo_.width, screenInfo_.height};
1157 
1158     // 3 init Occlusion info
1159     needRecalculateOcclusion_ = false;
1160     accumulatedOcclusionRegion_.Reset();
1161     occlusionRegionWithoutSkipLayer_.Reset();
1162     if (!curMainAndLeashWindowNodesIds_.empty()) {
1163         std::queue<NodeId>().swap(curMainAndLeashWindowNodesIds_);
1164     }
1165 
1166     // 4. check isHardwareForcedDisabled
1167     auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1168     if (geoPtr == nullptr) {
1169         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo geoPtr is nullptr");
1170         return false;
1171     }
1172     if (geoPtr->IsNeedClientCompose()) {
1173         isHardwareForcedDisabled_ = true;
1174     }
1175 
1176     // 5. check compositeType
1177     auto mirrorNode = node.GetMirrorSource().lock();
1178     node.SetIsMirrorScreen(mirrorNode != nullptr);
1179     switch (screenInfo_.state) {
1180         case ScreenState::PRODUCER_SURFACE_ENABLE:
1181             node.SetCompositeType(mirrorNode ?
1182                 RSDisplayRenderNode::CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1183                 RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1184             break;
1185         case ScreenState::HDI_OUTPUT_ENABLE:
1186             node.SetCompositeType(node.IsForceSoftComposite() ?
1187                 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
1188                 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
1189             break;
1190         default:
1191             return false;
1192     }
1193 
1194     return true;
1195 }
1196 
BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1197 bool RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1198 {
1199     // 1. init and record surface info
1200     if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1201         hasCaptureWindow_[currentVisitDisplay_] = true;
1202     }
1203     UpdateSecuritySkipAndProtectedLayersRecord(node);
1204     node.UpdateUIFirstFrameGravity();
1205     if (node.IsMainWindowType() || node.IsLeashWindow()) {
1206         // UpdateCurCornerRadius must process before curSurfaceNode_ update
1207         node.UpdateCurCornerRadius(curCornerRadius_);
1208         curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1209         curSurfaceDirtyManager_ = node.GetDirtyManager();
1210         if (!curSurfaceDirtyManager_ || !curSurfaceNode_) {
1211             RS_LOGE("RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc %{public}s has invalid"
1212                 " SurfaceDirtyManager or node ptr", node.GetName().c_str());
1213             return false;
1214         }
1215         curSurfaceDirtyManager_->Clear();
1216         curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1217         filterInGlobal_ = curSurfaceNode_->IsTransparent();
1218         // update surfaceNode contentDirty and subTreeDirty flag for UIFirst purging policy
1219         RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1220         curSurfaceNode_->UpdateSurfaceCacheContentStaticFlag();
1221         curSurfaceNode_->UpdateSurfaceSubTreeDirtyFlag();
1222         curSurfaceNode_->SetLeashWindowVisibleRegionEmpty(false);
1223     } else if (node.IsAbilityComponent()) {
1224         if (auto nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>()) {
1225             RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(nodePtr);
1226             nodePtr->UpdateSurfaceCacheContentStaticFlag();
1227         }
1228     }
1229     // 2. update surface info and CheckIfOcclusionReusable
1230     node.SetAncestorDisplayNode(curDisplayNode_); // set for boot animation
1231     node.UpdateAncestorDisplayNodeInRenderParams();
1232     node.CleanDstRectChanged();
1233     // [planning] check node isDirty can be optimized.
1234     needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.IsDirty() ||
1235         node.CheckIfOcclusionReusable(preMainAndLeashWindowNodesIds_);
1236     if (autoCacheEnable_ && node.IsAppWindow()) {
1237         node.OpincSetInAppStateStart(unchangeMarkInApp_);
1238     }
1239     // 3. check color space pixelFormat and update RelMatrix
1240     CheckColorSpace(node);
1241     CheckPixelFormat(node);
1242     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
1243         node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
1244     }
1245     if (node.IsHardwareEnabledTopSurface() && node.ShouldPaint()) {
1246         RSPointerWindowManager::Instance().CollectInfoForHardCursor(curDisplayNode_->GetId(),
1247             node.GetRenderDrawable());
1248     }
1249     return true;
1250 }
1251 
AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1252 bool RSUniRenderVisitor::AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1253 {
1254     // 1. Update surfaceNode info and AppWindow gravity
1255     const auto& property = node.GetRenderProperties();
1256     if (node.IsAppWindow()) {
1257         boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
1258         frameGravity_ = property.GetFrameGravity();
1259     }
1260     auto& geoPtr = property.GetBoundsGeometry();
1261     if (geoPtr == nullptr) {
1262         return false;
1263     }
1264     UpdateDstRect(node, geoPtr->GetAbsRect(), prepareClipRect_);
1265     node.UpdatePositionZ();
1266     if (node.IsHardwareEnabledType() && node.GetZorderChanged() && curSurfaceNode_) {
1267         curSurfaceNode_->SetNeedCollectHwcNode(true);
1268     }
1269     UpdateSurfaceRenderNodeScale(node);
1270     UpdateSurfaceRenderNodeRotate(node);
1271     if (node.IsMainWindowType() || node.IsLeashWindow()) {
1272         curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
1273         curDisplayNode_->AddSurfaceNodePosByDescZOrder(node.GetId(), node.GetOldDirtyInSurface());
1274     }
1275     // 2. Update Occlusion info before children preparation
1276     if (node.IsMainWindowType()) {
1277         CalculateOcclusion(node);
1278         if (node.GetFirstLevelNodeId() == node.GetId()) {
1279             globalSurfaceBounds_.emplace_back(node.GetAbsDrawRect());
1280         }
1281     }
1282     // 3. Update HwcNode Info for appNode
1283     UpdateHwcNodeInfoForAppNode(node);
1284     if (node.IsHardwareEnabledTopSurface()) {
1285         UpdateSrcRect(node, geoPtr->GetAbsMatrix(), geoPtr->GetAbsRect());
1286     }
1287     return true;
1288 }
1289 
UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode & node)1290 void RSUniRenderVisitor::UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode& node)
1291 {
1292     if (!node.IsLeashWindow()) {
1293         return;
1294     }
1295     bool isVisibleRegionEmpty = true;
1296     for (const auto& child : *node.GetSortedChildren()) {
1297         const auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1298         if (childSurfaceNode && childSurfaceNode->IsAppWindow()) {
1299             // leash window is visible when child app has visible region
1300             if (!childSurfaceNode->GetVisibleRegion().IsEmpty()) {
1301                 isVisibleRegionEmpty = false;
1302             } else {
1303                 RS_OPTIONAL_TRACE_NAME_FMT("%s's visible region is empty", childSurfaceNode->GetName().c_str());
1304             }
1305         } else {
1306             // leash window is visible when child is not app window node
1307             isVisibleRegionEmpty = false;
1308         }
1309         if (!isVisibleRegionEmpty) {
1310             break;
1311         }
1312     }
1313     node.SetLeashWindowVisibleRegionEmpty(isVisibleRegionEmpty);
1314 }
1315 
UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode & node)1316 void RSUniRenderVisitor::UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode& node)
1317 {
1318     // app node
1319     if (node.GetNeedCollectHwcNode()) {
1320         node.ResetChildHardwareEnabledNodes();
1321     }
1322     // hwc node
1323     if (node.IsHardwareEnabledType() && curSurfaceNode_) {
1324         if (curSurfaceNode_->GetNeedCollectHwcNode()) {
1325             curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
1326         }
1327         if (!node.GetHardWareDisabledByReverse()) {
1328             node.SetHardwareForcedDisabledState(node.GetIsHwcPendingDisabled());
1329             node.SetIsHwcPendingDisabled(false);
1330         }
1331         node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1332         if (!IsHardwareComposerEnabled() || !node.IsDynamicHardwareEnable() ||
1333             curSurfaceNode_->GetVisibleRegion().IsEmpty() ||
1334             !node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1335             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by param/invisible/no buffer",
1336                 node.GetName().c_str(), node.GetId());
1337             node.SetHardwareForcedDisabledState(true);
1338             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
1339                 HwcDisabledReasons::DISABLED_BY_INVALID_PARAM, node.GetName());
1340             if (!node.GetFixRotationByUser()) {
1341                 return;
1342             }
1343         }
1344         auto& geo = node.GetRenderProperties().GetBoundsGeometry();
1345         if (geo == nullptr) {
1346             return;
1347         }
1348         UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
1349         UpdateHwcNodeByTransform(node);
1350         UpdateHwcNodeEnableByBackgroundAlpha(node);
1351         UpdateHwcNodeEnableByBufferSize(node);
1352         UpdateHwcNodeEnableBySrcRect(node);
1353     }
1354 }
1355 
UpdateSrcRect(RSSurfaceRenderNode & node,const Drawing::Matrix & absMatrix,const RectI & absRect)1356 void RSUniRenderVisitor::UpdateSrcRect(RSSurfaceRenderNode& node,
1357     const Drawing::Matrix& absMatrix, const RectI& absRect)
1358 {
1359     auto canvas = std::make_unique<Rosen::Drawing::Canvas>(screenInfo_.phyWidth, screenInfo_.phyHeight);
1360     canvas->ConcatMatrix(absMatrix);
1361 
1362     const auto& dstRect = node.GetDstRect();
1363     Drawing::RectI dst = { std::round(dstRect.GetLeft()), std::round(dstRect.GetTop()), std::round(dstRect.GetRight()),
1364                            std::round(dstRect.GetBottom()) };
1365     node.UpdateSrcRect(*canvas.get(), dst);
1366     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
1367         RSUniRenderUtil::UpdateRealSrcRect(node, absRect);
1368     }
1369 }
1370 
UpdateDstRect(RSSurfaceRenderNode & node,const RectI & absRect,const RectI & clipRect)1371 void RSUniRenderVisitor::UpdateDstRect(RSSurfaceRenderNode& node, const RectI& absRect, const RectI& clipRect)
1372 {
1373     auto dstRect = absRect;
1374     if (!node.IsHardwareEnabledTopSurface()) {
1375         // If the screen is expanded, intersect the destination rectangle with the screen rectangle
1376         dstRect = dstRect.IntersectRect(RectI(curDisplayNode_->GetDisplayOffsetX(),
1377             curDisplayNode_->GetDisplayOffsetY(), screenInfo_.width, screenInfo_.height));
1378         // Remove the offset of the screen
1379         dstRect.left_ = dstRect.left_ - curDisplayNode_->GetDisplayOffsetX();
1380         dstRect.top_ = dstRect.top_ - curDisplayNode_->GetDisplayOffsetY();
1381     }
1382     // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
1383     if (node.IsHardwareEnabledType() || node.IsHardwareEnabledTopSurface()) {
1384         dstRect = dstRect.IntersectRect(clipRect);
1385         if (curSurfaceNode_ && (node.GetId() != curSurfaceNode_->GetId())) {
1386             dstRect = dstRect.IntersectRect(curSurfaceNode_->GetDstRect());
1387         }
1388     }
1389     dstRect.left_ = static_cast<int>(std::round(dstRect.left_ * screenInfo_.GetRogWidthRatio()));
1390     dstRect.top_ = static_cast<int>(std::round(dstRect.top_ * screenInfo_.GetRogHeightRatio()));
1391     dstRect.width_ = static_cast<int>(std::round(dstRect.width_ * screenInfo_.GetRogWidthRatio()));
1392     dstRect.height_ = static_cast<int>(std::round(dstRect.height_ * screenInfo_.GetRogHeightRatio()));
1393     // Set the destination rectangle of the node
1394     node.SetDstRect(dstRect);
1395 }
1396 
UpdateHwcNodeByTransform(RSSurfaceRenderNode & node)1397 void RSUniRenderVisitor::UpdateHwcNodeByTransform(RSSurfaceRenderNode& node)
1398 {
1399     if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1400         return;
1401     }
1402     node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1403     RSUniRenderUtil::DealWithNodeGravity(node, screenInfo_);
1404     RSUniRenderUtil::LayerRotate(node, screenInfo_);
1405     RSUniRenderUtil::LayerCrop(node, screenInfo_);
1406     RSUniRenderUtil::DealWithScalingMode(node, screenInfo_);
1407     node.SetCalcRectInPrepare(true);
1408 }
1409 
UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode & node)1410 void RSUniRenderVisitor::UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode& node)
1411 {
1412     bool bgTransport = !node.GetAncoForceDoDirect() &&
1413         (static_cast<uint8_t>(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX);
1414     auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
1415     bool isSolidColorEnbaled = stagingSurfaceParams->GetSelfDrawingNodeType() == SelfDrawingNodeType::XCOM &&
1416         node.GetRenderProperties().GetBackgroundColor() != RgbPalette::Black();
1417     if (bgTransport) {
1418         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by background color alpha < 1",
1419             node.GetName().c_str(), node.GetId());
1420         // use in skip updating hardware state for hwcnode with background alpha in specific situation
1421         if (!RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag()) {
1422             node.SetHardwareForcedDisabledState(true);
1423         }
1424         node.SetNodeHasBackgroundColorAlpha(true);
1425         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
1426             HwcDisabledReasons::DISABLED_BY_BACKGROUND_ALPHA, node.GetName());
1427     } else if (RsCommonHook::Instance().GetIsWhiteListForSolidColorLayerFlag() && isSolidColorEnbaled) {
1428         if (!RSSystemParameters::GetSolidLayerHwcEnabled()) {
1429             node.SetHardwareForcedDisabledState(true);
1430             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by solidLayer switch",
1431                 node.GetName().c_str(), node.GetId());
1432             return;
1433         }
1434         stagingSurfaceParams->SetIsHwcEnabledBySolidLayer(true);
1435     } else if (!RsCommonHook::Instance().GetIsWhiteListForSolidColorLayerFlag() && isSolidColorEnbaled) {
1436         node.SetHardwareForcedDisabledState(true);
1437         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by solid background color",
1438             node.GetName().c_str(), node.GetId());
1439     }
1440 }
1441 
UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode & node)1442 void RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode& node)
1443 {
1444     if (!node.IsRosenWeb() || node.IsHardwareForcedDisabled()) {
1445         return;
1446     }
1447     if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1448         return;
1449     }
1450     const auto& property = node.GetRenderProperties();
1451     auto gravity = property.GetFrameGravity();
1452     if (gravity != Gravity::TOP_LEFT) {
1453         return;
1454     }
1455     auto surfaceHandler = node.GetRSSurfaceHandler();
1456     auto consumer = surfaceHandler->GetConsumer();
1457     if (consumer == nullptr) {
1458         return;
1459     }
1460 
1461     auto buffer = surfaceHandler->GetBuffer();
1462     const auto bufferWidth = buffer->GetSurfaceBufferWidth();
1463     const auto bufferHeight = buffer->GetSurfaceBufferHeight();
1464     auto boundsWidth = property.GetBoundsWidth();
1465     auto boundsHeight = property.GetBoundsHeight();
1466 
1467     auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
1468     if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
1469         RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize GetSurfaceBufferTransformType failed");
1470     }
1471     if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
1472         transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
1473         std::swap(boundsWidth, boundsHeight);
1474     }
1475     if ((bufferWidth < boundsWidth) || (bufferHeight < boundsHeight)) {
1476         RS_OPTIONAL_TRACE_NAME_FMT(
1477             "hwc debug: name:%s id:%" PRIu64 " buffer:[%d, %d] bounds:[%f, %f] disabled by buffer nonmatching",
1478             node.GetName().c_str(), node.GetId(), bufferWidth, bufferHeight, boundsWidth, boundsHeight);
1479         node.SetHardwareForcedDisabledState(true);
1480         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(
1481             node.GetId(), HwcDisabledReasons::DISABLED_BY_BUFFER_NONMATCH, node.GetName());
1482     }
1483 }
1484 
UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode & node)1485 void RSUniRenderVisitor::UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode& node)
1486 {
1487     if (node.IsHardwareForcedDisabled()) {
1488         return;
1489     }
1490     bool hasRotation = false;
1491     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetConsumer()) {
1492         const auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
1493         auto rotation = RSBaseRenderUtil::GetRotateTransform(
1494             RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, node.GetRSSurfaceHandler()->GetBuffer()));
1495         hasRotation = rotation == GRAPHIC_ROTATE_90 || rotation == GRAPHIC_ROTATE_270;
1496     }
1497     node.UpdateHwcDisabledBySrcRect(hasRotation);
1498     if (node.IsHardwareDisabledBySrcRect()) {
1499         node.SetHardwareForcedDisabledState(true);
1500         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
1501             HwcDisabledReasons::DISABLED_BY_SRC_PIXEL, node.GetName());
1502     }
1503 }
1504 
UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)1505 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector<RectI>& hwcRects,
1506     std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
1507 {
1508     if (hwcNode->IsHardwareForcedDisabled()) {
1509         return;
1510     }
1511     auto dst = hwcNode->GetDstRect();
1512     if (hwcNode->GetAncoForceDoDirect()) {
1513         hwcRects.emplace_back(dst);
1514         return;
1515     }
1516     for (auto rect : hwcRects) {
1517         if (dst.Intersect(rect) && !RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
1518             if (RsCommonHook::Instance().GetVideoSurfaceFlag() &&
1519                 ((dst.GetBottom() - rect.GetTop() <= MIN_OVERLAP && dst.GetBottom() - rect.GetTop() >= 0) ||
1520                 (rect.GetBottom() - dst.GetTop() <= MIN_OVERLAP && rect.GetBottom() - dst.GetTop() >= 0))) {
1521                 return;
1522             }
1523             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by hwc node above",
1524                 hwcNode->GetName().c_str(), hwcNode->GetId());
1525             hwcNode->SetHardwareForcedDisabledState(true);
1526             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
1527                 HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
1528             return;
1529         }
1530     }
1531     hwcRects.emplace_back(dst);
1532 }
1533 
UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)1534 void RSUniRenderVisitor::UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)
1535 {
1536     auto hwcNodeGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
1537     if (!hwcNodeGeo) {
1538         RS_LOGE("hwcNode Geometry is not prepared.");
1539         return;
1540     }
1541     bool hasCornerRadius = !hwcNode->GetRenderProperties().GetCornerRadius().IsZero();
1542     std::vector<RectI> currIntersectedRoundCornerAABBs = {};
1543     float alpha = hwcNode->GetRenderProperties().GetAlpha();
1544     Drawing::Matrix totalMatrix = hwcNodeGeo->GetMatrix();
1545     auto hwcNodeRect = hwcNodeGeo->GetAbsRect();
1546     bool isNodeRenderByDrawingCache = false;
1547     hwcNode->SetAbsRotation(hwcNode->GetRenderProperties().GetRotation());
1548     RSUniRenderUtil::TraverseParentNodeAndReduce(
1549         hwcNode,
1550         [&isNodeRenderByDrawingCache](std::shared_ptr<RSRenderNode> parent) {
1551             if (isNodeRenderByDrawingCache) {
1552                 return;
1553             }
1554             // if the parent node of hwcNode is marked freeze or nodegroup, RS closes hardware composer of hwcNode.
1555             isNodeRenderByDrawingCache = isNodeRenderByDrawingCache || parent->IsStaticCached() ||
1556                 (parent->GetNodeGroupType() != RSRenderNode::NodeGroupType::NONE);
1557         },
1558         [&alpha](std::shared_ptr<RSRenderNode> parent) {
1559             auto& parentProperty = parent->GetRenderProperties();
1560             alpha *= parentProperty.GetAlpha();
1561         },
1562         [&totalMatrix](std::shared_ptr<RSRenderNode> parent) {
1563             if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
1564                 totalMatrix.PostConcat(opt.value());
1565             } else {
1566                 return;
1567             }
1568         },
1569         [&currIntersectedRoundCornerAABBs, hwcNodeRect](std::shared_ptr<RSRenderNode> parent) {
1570             auto& parentProperty = parent->GetRenderProperties();
1571             auto cornerRadius = parentProperty.GetCornerRadius();
1572             auto maxCornerRadius = *std::max_element(std::begin(cornerRadius.data_), std::end(cornerRadius.data_));
1573             auto parentGeo = parentProperty.GetBoundsGeometry();
1574             static const std::array offsetVecs {
1575                 UIPoint { 0, 0 },
1576                 UIPoint { 1, 0 },
1577                 UIPoint { 0, 1 },
1578                 UIPoint { 1, 1 }
1579             };
1580 
1581             // The logic here is to calculate whether the HWC Node affects
1582             // the round corner property of the parent node.
1583             // The method is calculating the rounded AABB of each HWC node
1584             // with respect to all parent nodes above it and storing the results.
1585             // When a HWC node is found below, the AABBs and the HWC node
1586             // are checked for intersection. If there is an intersection,
1587             // the node above it is disabled from taking the HWC pipeline.
1588             auto checkIntersectWithRoundCorner = [&currIntersectedRoundCornerAABBs, hwcNodeRect](
1589                 const RectI& rect, float radiusX, float radiusY) {
1590                 if (radiusX <= 0 || radiusY <= 0) {
1591                     return;
1592                 }
1593                 UIPoint offset { rect.GetWidth() - radiusX, rect.GetHeight() - radiusY };
1594                 UIPoint anchorPoint { rect.GetLeft(), rect.GetTop() };
1595                 std::for_each(std::begin(offsetVecs), std::end(offsetVecs),
1596                     [&currIntersectedRoundCornerAABBs, hwcNodeRect, offset,
1597                         radiusX, radiusY, anchorPoint](auto offsetVec) {
1598                         auto res = anchorPoint + offset * offsetVec;
1599                         auto roundCornerAABB = RectI(res.x_, res.y_, radiusX, radiusY);
1600                         if (!roundCornerAABB.IntersectRect(hwcNodeRect).IsEmpty()) {
1601                             currIntersectedRoundCornerAABBs.push_back(roundCornerAABB);
1602                         }
1603                     }
1604                 );
1605             };
1606             if (parentGeo) {
1607                 auto parentRect = parentGeo->GetAbsRect();
1608                 checkIntersectWithRoundCorner(parentRect, maxCornerRadius, maxCornerRadius);
1609 
1610                 if (parentProperty.GetClipToRRect()) {
1611                     RRect parentClipRRect = parentProperty.GetClipRRect();
1612                     RectI parentClipRect = parentGeo->MapAbsRect(parentClipRRect.rect_);
1613                     float maxClipRRectCornerRadiusX = 0, maxClipRRectCornerRadiusY = 0;
1614                     constexpr size_t radiusVecSize = 4;
1615                     for (size_t i = 0; i < radiusVecSize; ++i) {
1616                         maxClipRRectCornerRadiusX = std::max(maxClipRRectCornerRadiusX, parentClipRRect.radius_[i].x_);
1617                         maxClipRRectCornerRadiusY = std::max(maxClipRRectCornerRadiusY, parentClipRRect.radius_[i].y_);
1618                     }
1619                     checkIntersectWithRoundCorner(parentClipRect, maxClipRRectCornerRadiusX, maxClipRRectCornerRadiusY);
1620                 }
1621             }
1622         },
1623         [hwcNode](std::shared_ptr<RSRenderNode> parent) {
1624             hwcNode->SetAbsRotation(hwcNode->GetAbsRotation() + parent->GetRenderProperties().GetRotation());
1625         });
1626     if (isNodeRenderByDrawingCache) {
1627         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by drawing cache",
1628             hwcNode->GetName().c_str(), hwcNode->GetId());
1629         hwcNode->SetHardwareForcedDisabledState(isNodeRenderByDrawingCache);
1630     }
1631     hwcNode->SetTotalMatrix(totalMatrix);
1632     hwcNode->SetGlobalAlpha(alpha);
1633     hwcNode->SetIntersectedRoundCornerAABBs(std::move(currIntersectedRoundCornerAABBs));
1634 }
1635 
UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode> & hwcNode)1636 void RSUniRenderVisitor::UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
1637 {
1638     auto alpha = hwcNode->GetGlobalAlpha();
1639     auto totalMatrix = hwcNode->GetTotalMatrix();
1640     if (alpha < 1.0f) {
1641         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by accumulated alpha:%.2f",
1642             hwcNode->GetName().c_str(), hwcNode->GetId(), alpha);
1643         hwcNode->SetHardwareForcedDisabledState(true);
1644         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
1645             HwcDisabledReasons::DISABLED_BY_ACCUMULATED_ALPHA, hwcNode->GetName());
1646         return;
1647     }
1648     // [planning] degree only multiples of 90 now
1649     int degree = RSUniRenderUtil::GetRotationDegreeFromMatrix(totalMatrix);
1650     bool hasRotate = degree % RS_ROTATION_90 != 0 || RSUniRenderUtil::Is3DRotation(totalMatrix);
1651     if (hasRotate) {
1652         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by rotation:%d",
1653             hwcNode->GetName().c_str(), hwcNode->GetId(), degree);
1654         hwcNode->SetHardwareForcedDisabledState(true);
1655         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
1656             HwcDisabledReasons::DISABLED_BY_ROTATION, hwcNode->GetName());
1657         return;
1658     }
1659 }
1660 
ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode> & hwcNodePtr)1661 void RSUniRenderVisitor::ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr)
1662 {
1663     if ((hwcNodePtr->GetAncoFlags() & static_cast<uint32_t>(AncoFlags::IS_ANCO_NODE)) == 0) {
1664         return;
1665     }
1666     ancoNodes_.insert(hwcNodePtr);
1667     auto alpha = hwcNodePtr->GetGlobalAlpha();
1668     RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 "src %{public}s dst %{public}s "
1669         "alpha:%{public}.2f", hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(),
1670         hwcNodePtr->GetSrcRect().ToString().c_str(), hwcNodePtr->GetDstRect().ToString().c_str(), alpha);
1671     if (ROSEN_EQ(alpha, 0.0f)) {
1672         return;
1673     }
1674 
1675     if (!hwcNodePtr->GetRSSurfaceHandler() || !hwcNodePtr->GetRSSurfaceHandler()->GetBuffer()) {
1676         RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 " handler or buffer is null, skip",
1677             hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
1678         return;
1679     }
1680 
1681     ancoHasGpu_ = (ancoHasGpu_ || hwcNodePtr->IsHardwareForcedDisabled());
1682 }
1683 
InitAncoStatus()1684 void RSUniRenderVisitor::InitAncoStatus()
1685 {
1686     ancoHasGpu_ = false;
1687     ancoNodes_.clear();
1688 }
1689 
UpdateHwcNodeEnable()1690 void RSUniRenderVisitor::UpdateHwcNodeEnable()
1691 {
1692     InitAncoStatus();
1693 
1694     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1695     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
1696         [this](RSBaseRenderNode::SharedPtr& nodePtr) {
1697         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
1698         if (!surfaceNode) {
1699             return;
1700         }
1701         UpdateHwcNodeEnableByGlobalFilter(surfaceNode);
1702         surfaceNode->ResetNeedCollectHwcNode();
1703         const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
1704         if (hwcNodes.empty()) {
1705             return;
1706         }
1707         std::vector<RectI> hwcRects;
1708         for (const auto& hwcNode : hwcNodes) {
1709             auto hwcNodePtr = hwcNode.lock();
1710             if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
1711                 continue;
1712             }
1713             if (hwcNodePtr->GetProtectedLayer()) {
1714                 drmNodes_.emplace_back(hwcNode);
1715             }
1716             UpdateHwcNodeProperty(hwcNodePtr);
1717             UpdateHwcNodeEnableByRotateAndAlpha(hwcNodePtr);
1718             UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(hwcRects, hwcNodePtr);
1719 
1720             ProcessAncoNode(hwcNodePtr);
1721         }
1722     });
1723     UpdateAncoNodeHWCDisabledState();
1724     PrevalidateHwcNode();
1725     UpdateHwcNodeEnableByNodeBelow();
1726 }
1727 
UpdateAncoNodeHWCDisabledState()1728 void RSUniRenderVisitor::UpdateAncoNodeHWCDisabledState()
1729 {
1730     if (ancoHasGpu_) {
1731         for (const auto& hwcNodePtr : ancoNodes_) {
1732             hwcNodePtr->SetHardwareForcedDisabledState(true);
1733         }
1734     }
1735 
1736     InitAncoStatus();
1737 }
1738 
PrevalidateHwcNode()1739 void RSUniRenderVisitor::PrevalidateHwcNode()
1740 {
1741     if (!isPrevalidateHwcNodeEnable_) {
1742         RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate close");
1743         return;
1744     }
1745     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1746     std::vector<RequestLayerInfo> prevalidLayers;
1747     uint32_t curFps = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(curDisplayNode_->GetScreenId());
1748     uint32_t zOrder = static_cast<uint32_t>(globalZOrder_);
1749     // add surfaceNode layer
1750     RSUniHwcPrevalidateUtil::GetInstance().CollectSurfaceNodeLayerInfo(
1751         prevalidLayers, curMainAndLeashSurfaces, curFps, zOrder, screenInfo_);
1752     std::vector<RequestLayerInfo> uiFirstLayers;
1753     // collect uifirst layer
1754     // zOrder + 1.f is displayNode, UIFirst layer must be above displayNode(zorder + 2.f)
1755     RSUniHwcPrevalidateUtil::GetInstance().CollectUIFirstLayerInfo(
1756         uiFirstLayers, curFps, static_cast<float>(zOrder) + 2.f, screenInfo_);
1757     RS_TRACE_NAME_FMT("PrevalidateHwcNode hwcLayer: %u, uifirstLayer: %u", prevalidLayers.size(), uiFirstLayers.size());
1758     if (prevalidLayers.size() == 0 && uiFirstLayers.size() == 0) {
1759         RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode no hardware layer");
1760         return;
1761     }
1762     // add display layer
1763     RequestLayerInfo displayLayer;
1764     if (RSUniHwcPrevalidateUtil::GetInstance().CreateDisplayNodeLayerInfo(
1765         zOrder++, curDisplayNode_, screenInfo_, curFps, displayLayer)) {
1766         prevalidLayers.emplace_back(displayLayer);
1767     }
1768     // add uiFirst layer
1769     prevalidLayers.insert(prevalidLayers.end(), uiFirstLayers.begin(), uiFirstLayers.end());
1770     // add rcd layer
1771     RequestLayerInfo rcdLayer;
1772     if (RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
1773         auto rcdSurface = RSRcdRenderManager::GetInstance().GetBottomSurfaceNode(curDisplayNode_->GetId());
1774         if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(rcdSurface, screenInfo_, curFps, rcdLayer)) {
1775             prevalidLayers.emplace_back(rcdLayer);
1776         }
1777         rcdSurface = RSRcdRenderManager::GetInstance().GetTopSurfaceNode(curDisplayNode_->GetId());
1778         if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(rcdSurface, screenInfo_, curFps, rcdLayer)) {
1779             prevalidLayers.emplace_back(rcdLayer);
1780         }
1781     }
1782     std::map<uint64_t, RequestCompositionType> strategy;
1783     if (!RSUniHwcPrevalidateUtil::GetInstance().PreValidate(screenInfo_.id, prevalidLayers, strategy)) {
1784         RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate failed");
1785         return;
1786     }
1787     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1788     for (auto it : strategy) {
1789         RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode id: %{public}" PRIu64 ","
1790             " result: %{public}d", it.first, it.second);
1791         if (it.second == RequestCompositionType::DEVICE) {
1792             continue;
1793         }
1794         auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(it.first);
1795         if (node == nullptr) {
1796             continue;
1797         }
1798         if (it.second == RequestCompositionType::DEVICE_VSCF) {
1799             node->SetArsrTag(false);
1800             continue;
1801         }
1802         if (node->IsInFixedRotation() || node->GetProtectedLayer()) {
1803             continue;
1804         }
1805         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by prevalidate",
1806             node->GetName().c_str(), node->GetId());
1807         node->SetHardwareForcedDisabledState(true);
1808         if (node->GetRSSurfaceHandler()) {
1809             node->GetRSSurfaceHandler()->SetGlobalZOrder(-1.f);
1810         }
1811         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
1812             HwcDisabledReasons::DISABLED_BY_PREVALIDATE, node->GetName());
1813     }
1814 }
1815 
UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode> & node)1816 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode>& node)
1817 {
1818     const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
1819     if (hwcNodes.empty()) {
1820         return;
1821     }
1822     std::vector<std::shared_ptr<RSSurfaceRenderNode>> topLayers;
1823     for (auto hwcNode : hwcNodes) {
1824         auto hwcNodePtr = hwcNode.lock();
1825         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
1826             continue;
1827         }
1828         auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
1829         if (hwcNodePtr->IsLayerTop()) {
1830             topLayers.emplace_back(hwcNodePtr);
1831             continue;
1832         }
1833         if ((hasUniRenderHdrSurface_ || !drmNodes_.empty()) && !hwcNodePtr->GetProtectedLayer()) {
1834             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64
1835                 " disabled by having UniRenderHdrSurface/DRM nodes",
1836                 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
1837             hwcNodePtr->SetHardwareForcedDisabledState(true);
1838             // DRM will force HDR to use unirender
1839             hasUniRenderHdrSurface_ = hasUniRenderHdrSurface_ || RSMainThread::CheckIsHdrSurface(*hwcNodePtr);
1840         }
1841         UpdateHwcNodeDirtyRegionForApp(node, hwcNodePtr);
1842         hwcNodePtr->SetCalcRectInPrepare(false);
1843         hwcNodePtr->SetHardWareDisabledByReverse(false);
1844         surfaceHandler->SetGlobalZOrder(hwcNodePtr->IsHardwareForcedDisabled() && !hwcNodePtr->GetProtectedLayer()
1845             ? -1.f : globalZOrder_++);
1846         auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(hwcNodePtr->GetStagingRenderParams().get());
1847         if (stagingSurfaceParams->GetIsHwcEnabledBySolidLayer()) {
1848             surfaceHandler->SetGlobalZOrder(globalZOrder_++);
1849         }
1850         auto transform = RSUniRenderUtil::GetLayerTransform(*hwcNodePtr, screenInfo_);
1851         hwcNodePtr->UpdateHwcNodeLayerInfo(transform);
1852     }
1853     curDisplayNode_->SetDisplayGlobalZOrder(globalZOrder_);
1854     if (!topLayers.empty()) {
1855         UpdateTopLayersDirtyStatus(topLayers);
1856     }
1857 }
1858 
UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode> & pointWindow)1859 void RSUniRenderVisitor::UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode>& pointWindow)
1860 {
1861     if (!pointWindow->IsHardwareEnabledTopSurface() || !pointWindow->ShouldPaint()) {
1862         pointWindow->SetHardCursorStatus(false);
1863         return;
1864     }
1865     std::shared_ptr<RSSurfaceHandler> pointSurfaceHandler = pointWindow->GetMutableRSSurfaceHandler();
1866     if (pointSurfaceHandler) {
1867         // globalZOrder_ + 2 is displayNode layer, point window must be at the top.
1868         pointSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 2);
1869         bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curDisplayNode_);
1870         pointWindow->SetHardwareForcedDisabledState(true);
1871         auto transform = RSUniRenderUtil::GetLayerTransform(*pointWindow, screenInfo_);
1872         pointWindow->SetHardCursorStatus(isHardCursor);
1873         pointWindow->UpdateHwcNodeLayerInfo(transform, isHardCursor);
1874         if (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) {
1875             RSPointerWindowManager::Instance().UpdatePointerDirtyToGlobalDirty(pointWindow, curDisplayNode_);
1876         }
1877     }
1878 }
1879 
UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & topLayers)1880 void RSUniRenderVisitor::UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& topLayers)
1881 {
1882     for (const auto& topLayer : topLayers) {
1883         std::shared_ptr<RSSurfaceHandler> topLayerSurfaceHandler = topLayer->GetMutableRSSurfaceHandler();
1884         if (topLayerSurfaceHandler) {
1885             topLayerSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 1);
1886             topLayer->SetCalcRectInPrepare(false);
1887             topLayer->SetHardwareForcedDisabledState(!IsHardwareComposerEnabled() || !topLayer->ShouldPaint() ||
1888                 hasUniRenderHdrSurface_ || !drmNodes_.empty());
1889             auto transform = RSUniRenderUtil::GetLayerTransform(*topLayer, screenInfo_);
1890             topLayer->UpdateHwcNodeLayerInfo(transform);
1891         }
1892     }
1893 }
1894 
UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode> & appNode,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)1895 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode>& appNode,
1896     std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
1897 {
1898     // if current frame hwc enable status not equal with last frame
1899     // or current frame do gpu composition and has buffer consumed,
1900     // we need merge hwc node dst rect to dirty region.
1901     if (!hwcNode->IsHardwareForcedDisabled() != hwcNode->GetIsLastFrameHwcEnabled()) {
1902         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
1903         return;
1904     }
1905     if (!hwcNode->GetRSSurfaceHandler()) {
1906         return;
1907     }
1908     if (hwcNode->IsHardwareForcedDisabled() && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
1909         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetOldDirtyInSurface());
1910     }
1911     if (hasMirrorDisplay_ && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
1912         !appNode->GetVisibleRegion().IsEmpty()) {
1913         // merge hwc node dst rect for virtual screen dirty, in case the main display node skip
1914         curDisplayDirtyManager_->MergeHwcDirtyRect(hwcNode->GetDstRect());
1915     }
1916 }
1917 
UpdateSurfaceDirtyAndGlobalDirty()1918 void RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty()
1919 {
1920     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1921     // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
1922     Occlusion::Region accumulatedDirtyRegion;
1923     bool hasMainAndLeashSurfaceDirty = false;
1924     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
1925         [this, &accumulatedDirtyRegion, &hasMainAndLeashSurfaceDirty](RSBaseRenderNode::SharedPtr& nodePtr) {
1926         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
1927         if (!surfaceNode) {
1928             RS_LOGE("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surfaceNode is nullptr");
1929             return;
1930         }
1931         auto dirtyManager = surfaceNode->GetDirtyManager();
1932         RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
1933         // 0. update hwc node dirty region and create layer
1934         UpdateHwcNodeDirtyRegionAndCreateLayer(surfaceNode);
1935         UpdatePointWindowDirtyStatus(surfaceNode);
1936         // 1. calculate abs dirtyrect and update partialRenderParams
1937         // currently only sync visible region info
1938         surfaceNode->UpdatePartialRenderParams();
1939         if (dirtyManager && dirtyManager->IsCurrentFrameDirty()) {
1940             hasMainAndLeashSurfaceDirty = true;
1941         }
1942         // 2. check surface node dirtyrect need merge into displayDirtyManager
1943         CheckMergeSurfaceDirtysForDisplay(surfaceNode);
1944         // 3. check merge transparent filter when it intersects with pre-dirty
1945         CheckMergeDisplayDirtyByTransparentFilter(surfaceNode, accumulatedDirtyRegion);
1946     });
1947     curDisplayNode_->SetMainAndLeashSurfaceDirty(hasMainAndLeashSurfaceDirty);
1948     CheckMergeDebugRectforRefreshRate(curMainAndLeashSurfaces);
1949     CheckMergeGlobalFilterForDisplay(accumulatedDirtyRegion);
1950     ResetDisplayDirtyRegion();
1951     curDisplayNode_->ClearCurrentSurfacePos();
1952     std::swap(preMainAndLeashWindowNodesIds_, curMainAndLeashWindowNodesIds_);
1953 
1954 #ifdef RS_PROFILER_ENABLED
1955     RS_PROFILER_SET_DIRTY_REGION(accumulatedDirtyRegion);
1956 #endif
1957 }
UpdateHwcNodeEnableByNodeBelow()1958 void RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow()
1959 {
1960     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1961     // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order travelsal
1962     std::vector<RectI> hwcRects;
1963     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
1964         [this, &hwcRects](RSBaseRenderNode::SharedPtr& nodePtr) {
1965         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
1966         if (!surfaceNode) {
1967             RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow surfaceNode is nullptr");
1968             return;
1969         }
1970         // use in temporary scheme to realize DSS
1971         auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
1972         if (!hwcNodes.empty() && RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag() &&
1973             RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
1974             UpdateHardwareStateByHwcNodeBackgroundAlpha(hwcNodes);
1975         }
1976         // use end
1977         // disable hwc node with corner radius if intersects with hwc node below
1978         UpdateChildHwcNodeEnableByHwcNodeBelow(hwcRects, surfaceNode);
1979     });
1980 }
1981 
UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & appNode)1982 void RSUniRenderVisitor::UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI>& hwcRects,
1983     std::shared_ptr<RSSurfaceRenderNode>& appNode)
1984 {
1985     const auto& hwcNodes = appNode->GetChildHardwareEnabledNodes();
1986     for (auto hwcNode : hwcNodes) {
1987         auto hwcNodePtr = hwcNode.lock();
1988         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
1989             continue;
1990         }
1991         UpdateHwcNodeEnableByHwcNodeBelowSelf(hwcRects, hwcNodePtr,
1992             hwcNodePtr->GetIntersectedRoundCornerAABBsSize() != 0);
1993     }
1994 }
1995 
UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,std::vector<RectI> & hwcRects)1996 void RSUniRenderVisitor::UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,
1997     std::vector<RectI>& hwcRects)
1998 {
1999     if (!hwcNode || !hwcNode->GetProtectedLayer()) {
2000         return;
2001     }
2002     auto instanceNode = hwcNode->GetInstanceRootNode() ?
2003         hwcNode->GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
2004     if (!instanceNode) {
2005         hwcNode->SetCornerRadiusInfoForDRM({});
2006         return;
2007     }
2008     auto instanceAbsRect = instanceNode->GetAbsDrawRect();
2009     auto instanceCornerRadius = instanceNode->GetGlobalCornerRadius();
2010     if (instanceAbsRect.IsEmpty() || instanceCornerRadius.IsZero() ||
2011         ROSEN_EQ(instanceNode->GetRenderProperties().GetBoundsWidth(), 0.0f)) {
2012         hwcNode->SetCornerRadiusInfoForDRM({});
2013         return;
2014     }
2015     auto hwcGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2016     if (!hwcGeo) {
2017         hwcNode->SetCornerRadiusInfoForDRM({});
2018         return;
2019     }
2020     auto hwcAbsRect = hwcGeo->MapRect(hwcNode->GetSelfDrawRect(), hwcNode->GetTotalMatrix());
2021     hwcAbsRect = hwcAbsRect.IntersectRect(instanceAbsRect);
2022     if (hwcAbsRect.IsEmpty()) {
2023         hwcNode->SetCornerRadiusInfoForDRM({});
2024         return;
2025     }
2026     auto ratio = static_cast<float>(instanceAbsRect.GetWidth()) /
2027         instanceNode->GetRenderProperties().GetBoundsWidth();
2028     std::vector<float> ratioVector = { 0.0f, 0.0f, 0.0f, 0.0f };
2029     bool isIntersectWithRoundCorner =
2030         CheckIfRoundCornerIntersectDRM(ratio, ratioVector, instanceCornerRadius, instanceAbsRect, hwcAbsRect);
2031     // store radius information when drm overlaps with other hwc nodes
2032     if (isIntersectWithRoundCorner) {
2033         for (const auto& rect : hwcRects) {
2034             if (hwcAbsRect.Intersect(rect)) {
2035                 std::vector<float> drmCornerRadiusInfo = {
2036                     static_cast<float>(hwcAbsRect.GetLeft()), static_cast<float>(hwcAbsRect.GetTop()),
2037                     static_cast<float>(hwcAbsRect.GetWidth()), static_cast<float>(hwcAbsRect.GetHeight()),
2038                     // get corner radius num by index 0, 1, 2, 3
2039                     instanceCornerRadius[0] * ratioVector[0], instanceCornerRadius[1] * ratioVector[1],
2040                     instanceCornerRadius[2] * ratioVector[2], instanceCornerRadius[3] * ratioVector[3]};
2041                 hwcNode->SetCornerRadiusInfoForDRM(drmCornerRadiusInfo);
2042                 return;
2043             }
2044         }
2045     }
2046     hwcNode->SetCornerRadiusInfoForDRM({});
2047 }
2048 
CheckIfRoundCornerIntersectDRM(const float & ratio,std::vector<float> & ratioVector,const Vector4f & instanceCornerRadius,const RectI & instanceAbsRect,const RectI & hwcAbsRect)2049 bool RSUniRenderVisitor::CheckIfRoundCornerIntersectDRM(const float& ratio, std::vector<float>& ratioVector,
2050     const Vector4f& instanceCornerRadius, const RectI& instanceAbsRect, const RectI& hwcAbsRect)
2051 {
2052     auto maxRadius = *std::max_element(std::begin(instanceCornerRadius.data_),
2053         std::end(instanceCornerRadius.data_)) * ratio;
2054     bool isIntersectWithRoundCorner = false;
2055     static const std::vector<UIPoint> offsetVecs = { UIPoint { 0, 0 }, UIPoint { 1, 0 },
2056         UIPoint { 0, 1 }, UIPoint { 1, 1 } };
2057     UIPoint offset { instanceAbsRect.GetWidth() - maxRadius, instanceAbsRect.GetHeight() - maxRadius };
2058     UIPoint anchorPoint { instanceAbsRect.GetLeft(), instanceAbsRect.GetTop() };
2059     // if round corners intersect drm, update ratioVectors
2060     for (size_t i = 0; i < offsetVecs.size(); i++) {
2061         auto res = anchorPoint + offset * offsetVecs[i];
2062         if (RectI(res.x_, res.y_, maxRadius, maxRadius).Intersect(hwcAbsRect)) {
2063             isIntersectWithRoundCorner = true;
2064             ratioVector[i] = ratio;
2065         }
2066     }
2067     return isIntersectWithRoundCorner;
2068 }
2069 
UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & hwcNode,bool isIntersectWithRoundCorner)2070 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI>& hwcRects,
2071     std::shared_ptr<RSSurfaceRenderNode>& hwcNode, bool isIntersectWithRoundCorner)
2072 {
2073     if (hwcNode->IsHardwareForcedDisabled()) {
2074         if (RSMainThread::CheckIsHdrSurface(*hwcNode)) {
2075             hasUniRenderHdrSurface_ = true;
2076         }
2077         return;
2078     }
2079     auto absBound = RectI();
2080     if (auto geo = hwcNode->GetRenderProperties().GetBoundsGeometry()) {
2081         absBound = geo->GetAbsRect();
2082     } else {
2083         return;
2084     }
2085     if (hwcNode->GetAncoForceDoDirect() || !isIntersectWithRoundCorner) {
2086         hwcRects.emplace_back(absBound);
2087         return;
2088     }
2089     for (const auto& rect : hwcRects) {
2090         for (auto& roundCornerAABB : hwcNode->GetIntersectedRoundCornerAABBs()) {
2091             if (!roundCornerAABB.IntersectRect(rect).IsEmpty()) {
2092                 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64
2093                     " disabled by corner radius + hwc node below",
2094                     hwcNode->GetName().c_str(), hwcNode->GetId());
2095                 if (hwcNode->GetProtectedLayer()) {
2096                     continue;
2097                 }
2098                 hwcNode->SetHardwareForcedDisabledState(true);
2099                 if (RSMainThread::CheckIsHdrSurface(*hwcNode)) {
2100                     hasUniRenderHdrSurface_ = true;
2101                 }
2102                 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2103                     HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
2104                 return;
2105             }
2106         }
2107     }
2108     hwcRects.emplace_back(absBound);
2109 }
2110 
UpdateSurfaceOcclusionInfo()2111 void RSUniRenderVisitor::UpdateSurfaceOcclusionInfo()
2112 {
2113     allDstCurVisVec_.insert(allDstCurVisVec_.end(), dstCurVisVec_.begin(), dstCurVisVec_.end());
2114     dstCurVisVec_.clear();
2115 }
2116 
CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode & surfaceNode) const2117 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode& surfaceNode) const
2118 {
2119     // surfaceNode is transparent
2120     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2121     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2122     Occlusion::Region visibleRegion = hasMirrorDisplay_ ?
2123         surfaceNode.GetVisibleRegionInVirtual() : surfaceNode.GetVisibleRegion();
2124     if (surfaceNode.IsMainWindowType() && !visibleRegion.IsIntersectWith(dirtyRect)) {
2125         return;
2126     }
2127     if (surfaceNode.IsTransparent()) {
2128         RectI transparentDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2129         if (!transparentDirtyRect.IsEmpty()) {
2130             RS_LOGD("CheckMergeDisplayDirtyByTransparent global merge transparent dirty "
2131                 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2132                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2133                 transparentDirtyRect.ToString().c_str());
2134             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(transparentDirtyRect);
2135         }
2136     }
2137     // surfaceNode has transparent regions
2138     CheckMergeDisplayDirtyByTransparentRegions(surfaceNode);
2139 }
2140 
CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode & surfaceNode) const2141 void RSUniRenderVisitor::CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode& surfaceNode) const
2142 {
2143     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2144     if (surfaceNode.GetZorderChanged()) {
2145         RS_LOGD("CheckMergeDisplayDirtyByZorderChanged global merge GetZorderChanged "
2146             "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2147             curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2148             oldDirtyInSurface.ToString().c_str());
2149         curDisplayNode_->GetDirtyManager()->MergeDirtyRect(oldDirtyInSurface);
2150     }
2151 }
2152 
CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode & surfaceNode) const2153 void RSUniRenderVisitor::CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode& surfaceNode) const
2154 {
2155     if (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC &&
2156         surfaceNode.IsHardwareEnabledTopSurface() && surfaceNode.GetHardCursorStatus()) {
2157         return;
2158     }
2159     RectI lastFrameSurfacePos = curDisplayNode_->GetLastFrameSurfacePos(surfaceNode.GetId());
2160     RectI currentFrameSurfacePos = curDisplayNode_->GetCurrentFrameSurfacePos(surfaceNode.GetId());
2161     if (surfaceNode.GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
2162         RS_LOGD("CheckMergeDisplayDirtyByPosChanged global merge surface pos changed "
2163             "%{public}s: global dirty %{public}s, lastFrameRect %{public}s currentFrameRect %{public}s",
2164             surfaceNode.GetName().c_str(),
2165             curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2166             lastFrameSurfacePos.ToString().c_str(), currentFrameSurfacePos.ToString().c_str());
2167         if (!lastFrameSurfacePos.IsEmpty()) {
2168             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
2169         }
2170         if (!currentFrameSurfacePos.IsEmpty()) {
2171             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(currentFrameSurfacePos);
2172         }
2173     }
2174 }
2175 
CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode & surfaceNode) const2176 void RSUniRenderVisitor::CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode& surfaceNode) const
2177 {
2178     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2179     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2180     bool isShadowDisappear = !surfaceNode.GetRenderProperties().IsShadowValid() &&
2181         surfaceNode.IsShadowValidLastFrame();
2182     if (surfaceNode.GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2183         RectI shadowDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2184         // There are two situation here:
2185         // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2186         // dirtyRect == surfaceNode.GetOldDirtyInSurface()
2187         // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2188         // dirtyRect > surfaceNode.GetOldDirtyInSurface()
2189         // So we should always merge dirtyRect here.
2190         if (!shadowDirtyRect.IsEmpty()) {
2191             RS_LOGD("CheckMergeDisplayDirtyByShadowChanged global merge ShadowValid %{public}s: "
2192                 "global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2193                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2194                 dirtyRect.ToString().c_str());
2195             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRect);
2196         }
2197         if (isShadowDisappear) {
2198             surfaceNode.SetShadowValidLastFrame(false);
2199         }
2200     }
2201 }
2202 
CheckMergeDisplayDirtyBySurfaceChanged() const2203 void RSUniRenderVisitor::CheckMergeDisplayDirtyBySurfaceChanged() const
2204 {
2205     std::vector<RectI> surfaceChangedRects = curDisplayNode_->GetSurfaceChangedRects();
2206     for (auto& surfaceChangedRect : surfaceChangedRects) {
2207         if (!surfaceChangedRect.IsEmpty()) {
2208             RS_LOGD("CheckMergeDisplayDirtyBySurfaceChanged global merge Surface closed, global dirty %{public}s,"
2209                 "add rect %{public}s",
2210                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2211                 surfaceChangedRect.ToString().c_str());
2212             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(surfaceChangedRect);
2213         }
2214     }
2215 }
2216 
CheckMergeDisplayDirtyByAttractionChanged(RSSurfaceRenderNode & surfaceNode) const2217 void RSUniRenderVisitor::CheckMergeDisplayDirtyByAttractionChanged(RSSurfaceRenderNode& surfaceNode) const
2218 {
2219     if (surfaceNode.GetRenderProperties().IsAttractionValid()) {
2220         auto attractionDirtyRect = surfaceNode.GetRenderProperties().GetAttractionEffectCurrentDirtyRegion();
2221         RS_LOGD("CheckMergeDisplayDirtyByAttraction global merge attraction %{public}s: global dirty %{public}s,"
2222             "add rect %{public}s", surfaceNode.GetName().c_str(),
2223             curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2224             attractionDirtyRect.ToString().c_str());
2225         auto boundsGeometry = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
2226         if (boundsGeometry) {
2227             Drawing::Rect rect(attractionDirtyRect.GetLeft(), attractionDirtyRect.GetTop(),
2228                 attractionDirtyRect.GetRight(), attractionDirtyRect.GetBottom());
2229             Drawing::Rect tempRect;
2230             boundsGeometry->GetMatrix().MapRect(tempRect, rect);
2231             attractionDirtyRect =
2232                 RectI(tempRect.GetLeft(), tempRect.GetTop(), tempRect.GetWidth(), tempRect.GetHeight());
2233         }
2234         curDisplayNode_->GetDirtyManager()->MergeDirtyRect(attractionDirtyRect);
2235     }
2236 }
2237 
CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2238 void RSUniRenderVisitor::CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2239 {
2240     if (surfaceNode->GetDirtyManager() == nullptr || curDisplayNode_->GetDirtyManager() == nullptr) {
2241         return;
2242     }
2243     // 1 Handles the case of transparent surface, merge transparent dirty rect
2244     CheckMergeDisplayDirtyByTransparent(*surfaceNode);
2245     // 2 Zorder changed case, merge surface dest Rect
2246     CheckMergeDisplayDirtyByZorderChanged(*surfaceNode);
2247     // 3 surfacePos chanded case, merge surface lastframe pos or curframe pos
2248     CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2249     // 4 shadow disappear and appear case.
2250     CheckMergeDisplayDirtyByShadowChanged(*surfaceNode);
2251     // 5 handle last and curframe surfaces which appear or disappear case
2252     CheckMergeDisplayDirtyBySurfaceChanged();
2253     // 6 handle attraction effect which appear or disappear case
2254     CheckMergeDisplayDirtyByAttractionChanged(*surfaceNode);
2255     // More: any other display dirty caused by surfaceNode should be added here like CheckMergeDisplayDirtByXXX
2256 }
2257 
CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode & surfaceNode) const2258 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode& surfaceNode) const
2259 {
2260     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2261     if (surfaceNode.HasContainerWindow()) {
2262         // If a surface's dirty is intersect with container region (which can be considered transparent)
2263         // should be added to display dirty region.
2264         // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2265         auto containerRegion = surfaceNode.GetContainerRegion();
2266         auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2267         auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2268         if (!containerDirtyRegion.IsEmpty()) {
2269             RS_LOGD("CheckMergeDisplayDirtyByContainer global merge containerDirtyRegion "
2270                 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2271                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2272                 containerDirtyRegion.GetRegionInfo().c_str());
2273             // plan: we can use surfacenode's absrect as containerRegion's bound
2274             const auto& rect = containerRegion.GetBoundRef();
2275             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(
2276                 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2277         }
2278     } else {
2279         // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2280         // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
2281         // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2282         // which include transparent region but not counted in display dirtyregion)
2283         if (!surfaceNode.IsNodeDirty()) {
2284             return;
2285         }
2286         auto transparentRegion = surfaceNode.GetTransparentRegion();
2287         auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2288         Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
2289         if (!transparentDirtyRegion.IsEmpty()) {
2290             RS_LOGD("CheckMergeDisplayDirtyByTransparentRegions global merge TransparentDirtyRegion "
2291                 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2292                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2293                 transparentDirtyRegion.GetRegionInfo().c_str());
2294             const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
2295             for (const auto& rect : rects) {
2296                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(RectI{ rect.left_, rect.top_,
2297                     rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2298             }
2299         }
2300     }
2301 }
2302 
CheckMergeDisplayDirtyByTransparentFilter(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedDirtyRegion)2303 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter(
2304     std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2305     Occlusion::Region& accumulatedDirtyRegion)
2306 {
2307     auto disappearedSurfaceRegionBelowCurrent =
2308         curDisplayNode_->GetDisappearedSurfaceRegionBelowCurrent(surfaceNode->GetId());
2309     accumulatedDirtyRegion.OrSelf(disappearedSurfaceRegionBelowCurrent);
2310     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2311     auto filterVecIter = transparentCleanFilter_.find(surfaceNode->GetId());
2312     if (filterVecIter != transparentCleanFilter_.end()) {
2313         RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter surface:%{public}s "
2314             "has transparentCleanFilter", surfaceNode->GetName().c_str());
2315         // check accumulatedDirtyRegion influence filter nodes which in the current surface
2316         for (auto it = filterVecIter->second.begin(); it != filterVecIter->second.end(); ++it) {
2317             auto filterNode = nodeMap.GetRenderNode(it->first);
2318             if (filterNode == nullptr) {
2319                 continue;
2320             }
2321             auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
2322             auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
2323             if (!filterDirtyRegion.IsEmpty()) {
2324                 if (filterNode->GetRenderProperties().GetBackgroundFilter() ||
2325                     filterNode->GetRenderProperties().GetNeedDrawBehindWindow()) {
2326                     // backgroundfilter affected by below dirty
2327                     filterNode->MarkFilterStatusChanged(false, false);
2328                 }
2329                 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter global merge filterRegion "
2330                     "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode->GetName().c_str(),
2331                     curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2332                     it->second.ToString().c_str());
2333                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
2334                 if (filterNode->GetRenderProperties().GetFilter()) {
2335                     // foregroundfilter affected by below dirty
2336                     filterNode->MarkFilterStatusChanged(true, false);
2337                 }
2338             } else {
2339                 globalFilter_.insert(*it);
2340             }
2341             filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
2342         }
2343     }
2344     auto surfaceDirtyRegion = Occlusion::Region{
2345         Occlusion::Rect{ surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion() } };
2346     accumulatedDirtyRegion.OrSelf(surfaceDirtyRegion);
2347 }
2348 
UpdateDisplayDirtyAndExtendVisibleRegion()2349 void RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion()
2350 {
2351     if (curDisplayNode_ == nullptr) {
2352         RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion curDisplayNode_ is nullptr");
2353         return;
2354     }
2355     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2356     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2357     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2358         [this, &nodeMap](RSBaseRenderNode::SharedPtr& nodePtr) {
2359         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2360         if (surfaceNode == nullptr) {
2361             RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion surfaceNode is nullptr");
2362             return;
2363         }
2364         if (!surfaceNode->IsMainWindowType()) {
2365             return;
2366         }
2367         Occlusion::Region extendRegion;
2368         if (!surfaceNode->GetVisibleRegion().IsEmpty()) {
2369             ProcessFilterNodeObscured(surfaceNode, extendRegion, nodeMap);
2370         }
2371         surfaceNode->UpdateExtendVisibleRegion(extendRegion);
2372     });
2373 }
2374 
ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & extendRegion,const RSRenderNodeMap & nodeMap)2375 void RSUniRenderVisitor::ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2376     Occlusion::Region& extendRegion, const RSRenderNodeMap& nodeMap)
2377 {
2378     const auto& visibleFilterChild = surfaceNode->GetVisibleFilterChild();
2379     auto visibleRegion = surfaceNode->GetVisibleRegion();
2380     auto currentFrameDirtyRegion = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
2381     auto isTransparent = surfaceNode->IsTransparent();
2382     for (const auto& child : visibleFilterChild) {
2383         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2384         if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
2385             continue;
2386         }
2387         MarkBlurIntersectWithDRM(filterNode);
2388         auto filterRect = filterNode->GetOldDirtyInSurface();
2389         auto visibleRects = visibleRegion.GetRegionRectIs();
2390         auto iter = std::find_if(visibleRects.begin(), visibleRects.end(), [&filterRect](const auto& rect) {
2391             return filterRect.IsInsideOf(rect);
2392         });
2393         if (iter != visibleRects.end()) {
2394             continue;
2395         }
2396         if (!visibleRegion.IsIntersectWith(filterRect)) {
2397             continue;
2398         }
2399         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ filterRect } };
2400         extendRegion = extendRegion.Or(filterRegion);
2401         if (!isTransparent && filterRect.Intersect(currentFrameDirtyRegion)) {
2402             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(filterRect);
2403         }
2404     }
2405 }
2406 
UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2407 void RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2408 {
2409     if (surfaceNode == nullptr) {
2410         return;
2411     }
2412     if (surfaceNode->HasBlurFilter()) {
2413         surfaceNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
2414     }
2415     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2416     for (auto& child : surfaceNode->GetVisibleFilterChild()) {
2417         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2418         if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
2419             continue;
2420         }
2421         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode "
2422             "surfaceNode: %s, filterNode:[%lld], IsOccludedByFilterCache:%d", surfaceNode->GetName().c_str(),
2423             filterNode->GetId(), surfaceNode->IsOccludedByFilterCache());
2424         filterNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
2425     }
2426 }
2427 
CheckMergeGlobalFilterForDisplay(Occlusion::Region & accumulatedDirtyRegion)2428 void RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay(Occlusion::Region& accumulatedDirtyRegion)
2429 {
2430     // [planning] if not allowed containerNode filter, The following processing logic can be removed
2431     // Recursively traverses container nodes need filter
2432     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2433     for (auto it = containerFilter_.begin(); it != containerFilter_.end(); ++it) {
2434         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(it->first);
2435         if (filterNode == nullptr) {
2436             continue;
2437         }
2438         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
2439         auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
2440         RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeGlobalFilterForDisplay::filternode:%" PRIu64
2441                                    ", filterRect:%s, dirtyRegion:%s",
2442             filterNode->GetId(), it->second.ToString().c_str(), accumulatedDirtyRegion.GetRegionInfo().c_str());
2443         if (!filterDirtyRegion.IsEmpty()) {
2444             RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
2445                 "global dirty %{public}s, add container filterRegion %{public}s",
2446                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2447                 (it->second).ToString().c_str());
2448             if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
2449                 filterNode->MarkFilterStatusChanged(false, false); // background filter affected by below dirty
2450             }
2451             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
2452             if (filterNode->GetRenderProperties().GetFilter()) {
2453                 filterNode->MarkFilterStatusChanged(true, false); // foreground filter affected by below dirty
2454             }
2455         } else {
2456             globalFilter_.insert(*it);
2457         }
2458         filterNode->UpdateFilterCacheWithSelfDirty();
2459         filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
2460     }
2461     UpdateDisplayDirtyAndExtendVisibleRegion();
2462     CheckMergeFilterDirtyByIntersectWithDirty(globalFilter_, true);
2463 }
2464 
CollectEffectInfo(RSRenderNode & node)2465 void RSUniRenderVisitor::CollectEffectInfo(RSRenderNode& node)
2466 {
2467     auto nodeParent = node.GetParent().lock();
2468     if (nodeParent == nullptr) {
2469         return;
2470     }
2471     if (node.GetRenderProperties().NeedFilter() || node.ChildHasVisibleFilter()) {
2472         nodeParent->SetChildHasVisibleFilter(true);
2473         nodeParent->UpdateVisibleFilterChild(node);
2474     }
2475     if (node.GetRenderProperties().GetUseEffect() || node.ChildHasVisibleEffect()) {
2476         nodeParent->SetChildHasVisibleEffect(true);
2477         nodeParent->UpdateVisibleEffectChild(node);
2478     }
2479     if (node.GetSharedTransitionParam() || node.ChildHasSharedTransition()) {
2480         nodeParent->SetChildHasSharedTransition(true);
2481     }
2482 }
2483 
PostPrepare(RSRenderNode & node,bool subTreeSkipped)2484 void RSUniRenderVisitor::PostPrepare(RSRenderNode& node, bool subTreeSkipped)
2485 {
2486     auto curDirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
2487     if (!curDirtyManager) {
2488         return;
2489     }
2490     auto isOccluded = curSurfaceNode_ ?
2491         curSurfaceNode_->IsMainWindowType() && curSurfaceNode_->GetVisibleRegion().IsEmpty() : false;
2492     if (subTreeSkipped && !isOccluded) {
2493         UpdateHwcNodeRectInSkippedSubTree(node);
2494         CheckFilterNodeInSkippedSubTreeNeedClearCache(node, *curDirtyManager);
2495         UpdateSubSurfaceNodeRectInSkippedSubTree(node);
2496     }
2497     if (node.GetRenderProperties().NeedFilter()) {
2498         UpdateHwcNodeEnableByFilterRect(
2499             curSurfaceNode_, node.GetOldDirtyInSurface(), NeedPrepareChindrenInReverseOrder(node));
2500         auto globalFilterRect = (node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren()) ?
2501             GetVisibleEffectDirty(node) : node.GetOldDirtyInSurface();
2502         node.CalVisibleFilterRect(prepareClipRect_);
2503         node.MarkClearFilterCacheIfEffectChildrenChanged();
2504         CollectFilterInfoAndUpdateDirty(node, *curDirtyManager, globalFilterRect);
2505         node.SetGlobalAlpha(curAlpha_);
2506     }
2507     CollectEffectInfo(node);
2508     node.MapAndUpdateChildrenRect();
2509     node.UpdateSubTreeInfo(prepareClipRect_);
2510     node.UpdateLocalDrawRect();
2511     node.UpdateAbsDrawRect();
2512     node.ResetChangeState();
2513     if (isDrawingCacheEnabled_) {
2514         node.UpdateDrawingCacheInfoAfterChildren();
2515     }
2516     if (auto nodeParent = node.GetParent().lock()) {
2517         nodeParent->UpdateChildUifirstSupportFlag(node.GetUifirstSupportFlag());
2518         nodeParent->OpincUpdateNodeSupportFlag(node.OpincGetNodeSupportFlag());
2519     }
2520     auto& stagingRenderParams = node.GetStagingRenderParams();
2521     if (stagingRenderParams != nullptr) {
2522         if (node.GetSharedTransitionParam() && node.GetRenderProperties().GetSandBox()) {
2523             stagingRenderParams->SetAlpha(curAlpha_);
2524         } else {
2525             stagingRenderParams->SetAlpha(node.GetRenderProperties().GetAlpha());
2526         }
2527     }
2528 
2529     // planning: only do this if node is dirty
2530     node.UpdateRenderParams();
2531 
2532     // add if node is dirty
2533     node.AddToPendingSyncList();
2534 }
2535 
MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const2536 void RSUniRenderVisitor::MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const
2537 {
2538     if (!RSSystemProperties::GetDrmMarkedFilterEnabled()) {
2539         return;
2540     }
2541     static std::vector<std::string> drmKeyWins = { "SCBVolumePanel", "SCBBannerNotification" };
2542     auto appWindowNodeId = node->GetInstanceRootNodeId();
2543     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2544     auto appWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
2545     if (appWindowNode == nullptr) {
2546         return;
2547     }
2548     for (const auto& win : drmKeyWins) {
2549         if (appWindowNode->GetName().find(win) == std::string::npos) {
2550             continue;
2551         }
2552         for (auto& drmNode : drmNodes_) {
2553             auto drmNodePtr = drmNode.lock();
2554             if (drmNodePtr == nullptr) {
2555                 continue;
2556             }
2557             bool isIntersect =
2558                 drmNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(node->GetFilterRegion());
2559             if (isIntersect) {
2560                 node->MarkBlurIntersectWithDRM(true, RSMainThread::Instance()->GetGlobalDarkColorMode());
2561             }
2562         }
2563     }
2564 }
2565 
CheckFilterNodeInSkippedSubTreeNeedClearCache(const RSRenderNode & rootNode,RSDirtyRegionManager & dirtyManager)2566 void RSUniRenderVisitor::CheckFilterNodeInSkippedSubTreeNeedClearCache(
2567     const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager)
2568 {
2569     bool rotationChanged = curDisplayNode_ ?
2570         curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
2571     bool rotationStatusChanged = curDisplayNode_ ?
2572         curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
2573     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2574     for (auto& child : rootNode.GetVisibleFilterChild()) {
2575         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2576         if (filterNode == nullptr) {
2577             continue;
2578         }
2579         RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInSkippedSubTreeNeedClearCache node[%lld]", filterNode->GetId());
2580         if (auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode)) {
2581             UpdateRotationStatusForEffectNode(*effectNode);
2582         }
2583         filterNode->CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
2584         filterNode->MarkClearFilterCacheIfEffectChildrenChanged();
2585         if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
2586             filterNode->UpdateFilterCacheWithBelowDirty(dirtyManager, false);
2587         }
2588         RectI filterRect;
2589         filterNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, prepareClipRect_);
2590         UpdateHwcNodeEnableByFilterRect(curSurfaceNode_, filterNode->GetOldDirtyInSurface());
2591         CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager, filterRect);
2592     }
2593 }
2594 
UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode & rootNode)2595 void RSUniRenderVisitor::UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
2596 {
2597     if (!curSurfaceNode_ || RS_PROFILER_SHOULD_BLOCK_HWCNODE()) {
2598         return;
2599     }
2600     const auto& hwcNodes = curSurfaceNode_->GetChildHardwareEnabledNodes();
2601     if (hwcNodes.empty()) {
2602         return;
2603     }
2604     for (auto hwcNode : hwcNodes) {
2605         auto hwcNodePtr = hwcNode.lock();
2606         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree() || hwcNodePtr->GetCalcRectInPrepare()) {
2607             continue;
2608         }
2609         const auto& property = hwcNodePtr->GetRenderProperties();
2610         auto geoPtr = property.GetBoundsGeometry();
2611         if (geoPtr == nullptr) {
2612             return;
2613         }
2614         auto originalMatrix = geoPtr->GetMatrix();
2615         auto matrix = Drawing::Matrix();
2616         auto parent = hwcNodePtr->GetParent().lock();
2617         bool findInRoot = parent ? parent->GetId() == rootNode.GetId() : false;
2618         while (parent && parent->GetType() != RSRenderNodeType::DISPLAY_NODE) {
2619             if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
2620                 matrix.PostConcat(opt.value());
2621             } else {
2622                 break;
2623             }
2624             parent = parent->GetParent().lock();
2625             if (!parent) {
2626                 break;
2627             }
2628             findInRoot = parent->GetId() == rootNode.GetId() ? true : findInRoot;
2629         }
2630         if (!findInRoot) {
2631             continue;
2632         }
2633         if (parent) {
2634             const auto& parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
2635             if (parentGeoPtr) {
2636                 matrix.PostConcat(parentGeoPtr->GetMatrix());
2637             }
2638         }
2639         auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
2640         auto& properties = hwcNodePtr->GetMutableRenderProperties();
2641         auto offset = std::nullopt;
2642         properties.UpdateGeometryByParent(&matrix, offset);
2643         matrix.PreConcat(originalMatrix);
2644         Drawing::Rect bounds = Drawing::Rect(0, 0, properties.GetBoundsWidth(), properties.GetBoundsHeight());
2645         Drawing::Rect absRect;
2646         matrix.MapRect(absRect, bounds);
2647         RectI rect = {std::round(absRect.left_), std::round(absRect.top_),
2648             std::round(absRect.GetWidth()), std::round(absRect.GetHeight())};
2649         UpdateDstRect(*hwcNodePtr, rect, prepareClipRect_);
2650         UpdateSrcRect(*hwcNodePtr, matrix, rect);
2651         UpdateHwcNodeByTransform(*hwcNodePtr);
2652         UpdateHwcNodeEnableBySrcRect(*hwcNodePtr);
2653         UpdateHwcNodeEnableByBufferSize(*hwcNodePtr);
2654         hwcNodePtr->SetTotalMatrix(matrix);
2655         hwcNodePtr->SetOldDirtyInSurface(geoPtr->MapRect(hwcNodePtr->GetSelfDrawRect(), matrix));
2656     }
2657 }
2658 
UpdateHardwareStateByHwcNodeBackgroundAlpha(const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & hwcNodes)2659 void RSUniRenderVisitor::UpdateHardwareStateByHwcNodeBackgroundAlpha(
2660     const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes)
2661 {
2662     std::list<RectI> hwcRects;
2663     for (size_t i = 0; i < hwcNodes.size(); i++) {
2664         auto hwcNodePtr = hwcNodes[i].lock();
2665         if (!hwcNodePtr) {
2666             continue;
2667         }
2668         if (!hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled()) {
2669             hwcRects.push_back(hwcNodePtr->GetDstRect());
2670         } else if (hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled() &&
2671             hwcRects.size() != 0 && IsNodeAboveInsideOfNodeBelow(hwcNodePtr->GetDstRect(), hwcRects)) {
2672             continue;
2673         } else {
2674             hwcNodePtr->SetHardwareForcedDisabledState(true);
2675         }
2676     }
2677 }
2678 
IsNodeAboveInsideOfNodeBelow(const RectI & rectAbove,std::list<RectI> & hwcNodeRectList)2679 bool RSUniRenderVisitor::IsNodeAboveInsideOfNodeBelow(const RectI& rectAbove, std::list<RectI>& hwcNodeRectList)
2680 {
2681     for (auto rectBelow: hwcNodeRectList) {
2682         if (rectAbove.IsInsideOf(rectBelow)) {
2683             return true;
2684         }
2685     }
2686     return false;
2687 }
2688 
CalcHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode> & node,const RectI & filterRect,bool isReverseOrder)2689 void RSUniRenderVisitor::CalcHwcNodeEnableByFilterRect(
2690     std::shared_ptr<RSSurfaceRenderNode>& node, const RectI& filterRect, bool isReverseOrder)
2691 {
2692     if (!node) {
2693         return;
2694     }
2695     auto dstRect = node->GetDstRect();
2696     bool isIntersect = !dstRect.IntersectRect(filterRect).IsEmpty();
2697     if (isIntersect) {
2698         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by filter rect",
2699             node->GetName().c_str(), node->GetId());
2700         node->SetIsHwcPendingDisabled(true);
2701         node->SetHardwareForcedDisabledState(true);
2702         node->SetHardWareDisabledByReverse(isReverseOrder);
2703         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
2704             HwcDisabledReasons::DISABLED_BY_FLITER_RECT, node->GetName());
2705     }
2706 }
2707 
UpdateHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode> & node,const RectI & filterRect,bool isReverseOrder)2708 void RSUniRenderVisitor::UpdateHwcNodeEnableByFilterRect(
2709     std::shared_ptr<RSSurfaceRenderNode>& node, const RectI& filterRect, bool isReverseOrder)
2710 {
2711     if (filterRect.IsEmpty()) {
2712         return;
2713     }
2714     if (!node) {
2715         const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
2716         if (selfDrawingNodes.empty()) {
2717             return;
2718         }
2719         for (auto hwcNode : selfDrawingNodes) {
2720             CalcHwcNodeEnableByFilterRect(hwcNode, filterRect, isReverseOrder);
2721         }
2722     } else {
2723         const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
2724         if (hwcNodes.empty()) {
2725             return;
2726         }
2727         for (auto hwcNode : hwcNodes) {
2728             auto hwcNodePtr = hwcNode.lock();
2729             CalcHwcNodeEnableByFilterRect(hwcNodePtr, filterRect, isReverseOrder);
2730         }
2731     }
2732 }
2733 
UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode> & node)2734 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode>& node)
2735 {
2736     auto cleanFilter = transparentCleanFilter_.find(node->GetId());
2737     bool cleanFilterFound = (cleanFilter != transparentCleanFilter_.end());
2738     auto dirtyFilter = transparentDirtyFilter_.find(node->GetId());
2739     bool dirtyFilterFound = (dirtyFilter != transparentDirtyFilter_.end());
2740     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2741     for (auto it = curMainAndLeashSurfaces.rbegin(); it != curMainAndLeashSurfaces.rend(); ++it) {
2742         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2743         if (surfaceNode == nullptr) {
2744             continue;
2745         }
2746         if (surfaceNode->GetId() == node->GetId()) {
2747             return;
2748         }
2749         const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2750         if (hwcNodes.empty()) {
2751             continue;
2752         }
2753         for (auto hwcNode : hwcNodes) {
2754             auto hwcNodePtr = hwcNode.lock();
2755             if (!hwcNodePtr || hwcNodePtr->IsHardwareForcedDisabled() ||
2756                 !hwcNodePtr->GetRenderProperties().GetBoundsGeometry()) {
2757                 continue;
2758             }
2759             if (cleanFilterFound) {
2760                 UpdateHwcNodeEnableByGlobalCleanFilter(cleanFilter->second, *hwcNodePtr);
2761                 if (hwcNodePtr->IsHardwareForcedDisabled()) {
2762                     ProcessAncoNode(hwcNodePtr);
2763                     continue;
2764                 }
2765             }
2766             if (!dirtyFilterFound) {
2767                 continue;
2768             }
2769             for (auto filter = dirtyFilter->second.begin(); filter != dirtyFilter->second.end(); ++filter) {
2770                 if (hwcNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(filter->second)) {
2771                     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentDirtyFilter",
2772                         hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2773                     hwcNodePtr->SetHardwareForcedDisabledState(true);
2774                     ProcessAncoNode(hwcNodePtr);
2775                     hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
2776                         HwcDisabledReasons::DISABLED_BY_TRANSPARENT_DIRTY_FLITER, hwcNodePtr->GetName());
2777                     break;
2778                 }
2779             }
2780         }
2781     }
2782 }
2783 
UpdateHwcNodeEnableByGlobalCleanFilter(const std::vector<std::pair<NodeId,RectI>> & cleanFilter,RSSurfaceRenderNode & hwcNodePtr)2784 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalCleanFilter(
2785     const std::vector<std::pair<NodeId, RectI>>& cleanFilter, RSSurfaceRenderNode& hwcNodePtr)
2786 {
2787     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2788     for (auto filter = cleanFilter.begin(); filter != cleanFilter.end(); ++filter) {
2789         auto geo = hwcNodePtr.GetRenderProperties().GetBoundsGeometry();
2790         if (!geo) {
2791             return;
2792         }
2793         if (!geo->GetAbsRect().IntersectRect(filter->second).IsEmpty()) {
2794             auto& rendernode = nodeMap.GetRenderNode<RSRenderNode>(filter->first);
2795             if (rendernode == nullptr) {
2796                 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: rendernode is null");
2797                 continue;
2798             }
2799 
2800             if (rendernode->IsAIBarFilterCacheValid()) {
2801                 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: skip intersection for using cache");
2802                 continue;
2803             }
2804             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentCleanFilter",
2805                 hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId());
2806             hwcNodePtr.SetHardwareForcedDisabledState(true);
2807             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr.GetId(),
2808                 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_CLEAN_FLITER, hwcNodePtr.GetName());
2809             break;
2810         }
2811     }
2812 }
2813 
ResetSubSurfaceNodesCalState(std::vector<std::pair<NodeId,std::weak_ptr<RSSurfaceRenderNode>>> & subSurfaceNodes)2814 inline static void ResetSubSurfaceNodesCalState(
2815     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>>& subSurfaceNodes)
2816 {
2817     for (auto& [id, node] : subSurfaceNodes) {
2818         auto subSurfaceNodePtr = node.lock();
2819         if (!subSurfaceNodePtr) {
2820             continue;
2821         }
2822         subSurfaceNodePtr->SetCalcRectInPrepare(false);
2823     }
2824 }
2825 
UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode & rootNode)2826 void RSUniRenderVisitor::UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
2827 {
2828     if (!curSurfaceNode_ || !curSurfaceDirtyManager_) {
2829         return;
2830     }
2831     auto rootGeo = rootNode.GetRenderProperties().GetBoundsGeometry();
2832     if (!rootGeo) {
2833         return;
2834     }
2835 
2836     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
2837     curSurfaceNode_->GetAllSubSurfaceNodes(allSubSurfaceNodes);
2838     for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
2839         auto subSurfaceNodePtr = subSurfaceNode.lock();
2840         Drawing::Matrix absMatrix;
2841         if (!subSurfaceNodePtr || subSurfaceNodePtr->GetCalcRectInPrepare() ||
2842             !subSurfaceNodePtr->GetAbsMatrixReverse(rootNode, absMatrix)) {
2843             continue;
2844         }
2845 
2846         Drawing::RectF absDrawRect;
2847         absMatrix.MapRect(absDrawRect, RSPropertiesPainter::Rect2DrawingRect(subSurfaceNodePtr->GetSelfDrawRect()));
2848         RectI subSurfaceRect = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
2849             absDrawRect.GetWidth(), absDrawRect.GetHeight());
2850 
2851         subSurfaceNodePtr->SetOldDirtyInSurface(subSurfaceRect.IntersectRect(prepareClipRect_));
2852         UpdateNodeVisibleRegion(*subSurfaceNodePtr);
2853         UpdateDstRect(*subSurfaceNodePtr, subSurfaceRect, prepareClipRect_);
2854         subSurfaceNodePtr->SetCalcRectInPrepare(true);
2855         if (subSurfaceNodePtr->IsLeashOrMainWindow()) {
2856             curMainAndLeashWindowNodesIds_.push(subSurfaceNodePtr->GetId());
2857             curDisplayNode_->RecordMainAndLeashSurfaces(subSurfaceNodePtr);
2858             curDisplayNode_->UpdateSurfaceNodePos(
2859                 subSurfaceNodePtr->GetId(), subSurfaceNodePtr->GetOldDirtyInSurface());
2860             if (auto subSurfaceDirtyManager = subSurfaceNodePtr->GetDirtyManager()) {
2861                 subSurfaceDirtyManager->MergeDirtyRect(subSurfaceNodePtr->GetOldDirtyInSurface().IntersectRect(
2862                     curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion()));
2863             }
2864             CollectOcclusionInfoForWMS(*subSurfaceNodePtr);
2865             subSurfaceNodePtr->UpdateRenderParams();
2866         }
2867     }
2868     ResetSubSurfaceNodesCalState(allSubSurfaceNodes);
2869 }
2870 
GetVisibleEffectDirty(RSRenderNode & node) const2871 RectI RSUniRenderVisitor::GetVisibleEffectDirty(RSRenderNode& node) const
2872 {
2873     RectI childEffectRect;
2874     auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2875     for (auto& nodeId : node.GetVisibleEffectChild()) {
2876         if (auto& subnode = nodeMap.GetRenderNode<RSRenderNode>(nodeId)) {
2877             childEffectRect = childEffectRect.JoinRect(subnode->GetOldDirtyInSurface());
2878         }
2879     }
2880     return childEffectRect;
2881 }
2882 
CollectFilterInfoAndUpdateDirty(RSRenderNode & node,RSDirtyRegionManager & dirtyManager,const RectI & globalFilterRect)2883 void RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty(RSRenderNode& node,
2884     RSDirtyRegionManager& dirtyManager, const RectI& globalFilterRect)
2885 {
2886     bool isNodeAddedToTransparentCleanFilters = false;
2887     if (curSurfaceNode_) {
2888         bool isIntersect = dirtyManager.GetCurrentFrameDirtyRegion().Intersect(globalFilterRect);
2889         if (isIntersect) {
2890             dirtyManager.MergeDirtyRect(globalFilterRect);
2891         } else {
2892             curSurfaceNoBelowDirtyFilter_.insert({node.GetId(), globalFilterRect});
2893         }
2894         if (node.GetRenderProperties().GetFilter()) {
2895             node.UpdateFilterCacheWithBelowDirty(dirtyManager, true);
2896         }
2897         node.UpdateFilterCacheWithSelfDirty();
2898         if (curSurfaceNode_->IsTransparent()) {
2899             globalFilterRects_.emplace_back(globalFilterRect);
2900             if (!isIntersect || (isIntersect && (node.GetRenderProperties().GetBackgroundFilter() ||
2901                 node.GetRenderProperties().GetNeedDrawBehindWindow()) && !node.IsBackgroundInAppOrNodeSelfDirty())) {
2902                 // record nodes which has transparent clean filter
2903                 RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInfoAndUpdateDirty::surfaceNode:%s, add node[%lld] to "
2904                     "transparentCleanFilter", curSurfaceNode_->GetName().c_str(), node.GetId());
2905                 transparentCleanFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalFilterRect});
2906                 isNodeAddedToTransparentCleanFilters = true;
2907             }
2908             if (isIntersect) {
2909                 transparentDirtyFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalFilterRect});
2910                 RS_LOGD("RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty global merge transparentDirtyFilter "
2911                     "%{public}s, global dirty %{public}s, add rect %{public}s", curSurfaceNode_->GetName().c_str(),
2912                     curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
2913                     globalFilterRect.ToString().c_str());
2914                 curDisplayDirtyManager_->MergeDirtyRect(globalFilterRect);
2915             }
2916         } else {
2917             // record surface nodes and nodes in surface which has clean filter
2918             globalFilter_.insert({node.GetId(), globalFilterRect});
2919         }
2920     } else {
2921         globalFilterRects_.emplace_back(globalFilterRect);
2922         // record container nodes which need filter
2923         containerFilter_.insert({node.GetId(), globalFilterRect});
2924     }
2925     if (curSurfaceNode_ && !isNodeAddedToTransparentCleanFilters) {
2926         node.PostPrepareForBlurFilterNode(dirtyManager, needRequestNextVsync_);
2927     }
2928 }
2929 
UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode & node)2930 void RSUniRenderVisitor::UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode& node)
2931 {
2932     if (!node.IsLeashWindow()) {
2933         return;
2934     }
2935     auto& property = node.GetMutableRenderProperties();
2936     auto& geoPtr = (property.GetBoundsGeometry());
2937     if (geoPtr == nullptr) {
2938         return;
2939     }
2940     auto absMatrix = geoPtr->GetAbsMatrix();
2941     bool isScale = false;
2942     if (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) {
2943         isScale = (!ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_X), 1.f, EPSILON_SCALE) ||
2944             !ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_Y), 1.f, EPSILON_SCALE));
2945     } else {
2946         bool getMinMaxScales = false;
2947         // scaleFactors[0]-minimum scaling factor, scaleFactors[1]-maximum scaling factor
2948         Drawing::scalar scaleFactors[2];
2949         getMinMaxScales = absMatrix.GetMinMaxScales(scaleFactors);
2950         if (getMinMaxScales) {
2951             isScale = !ROSEN_EQ(scaleFactors[0], 1.f, EPSILON_SCALE) || !ROSEN_EQ(scaleFactors[1], 1.f, EPSILON_SCALE);
2952         }
2953         if (!getMinMaxScales) {
2954             RS_LOGD("getMinMaxScales fail, node:%{public}s %{public}" PRIu64 "", node.GetName().c_str(), node.GetId());
2955             const auto& dstRect = node.GetDstRect();
2956             float dstRectWidth = dstRect.GetWidth();
2957             float dstRectHeight = dstRect.GetHeight();
2958             float boundsWidth = property.GetBoundsWidth();
2959             float boundsHeight = property.GetBoundsHeight();
2960             isScale =
2961                 !ROSEN_EQ(std::min(dstRectWidth, dstRectHeight), std::min(boundsWidth, boundsHeight), EPSILON_SCALE) ||
2962                 !ROSEN_EQ(std::max(dstRectWidth, dstRectHeight), std::max(boundsWidth, boundsHeight), EPSILON_SCALE);
2963         }
2964     }
2965     node.SetIsScaleInPreFrame(node.IsScale());
2966     node.SetIsScale(isScale);
2967 }
2968 
PrepareRootRenderNode(RSRootRenderNode & node)2969 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
2970 {
2971     RS_TRACE_NAME_FMT("RSUniRender::PrepareRootRenderNode:node[%" PRIu64 "] pid[%d] subTreeDirty[%d]",
2972         node.GetId(), ExtractPid(node.GetId()), node.IsSubTreeDirty());
2973     bool dirtyFlag = dirtyFlag_;
2974     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
2975     auto prepareClipRect = prepareClipRect_;
2976 
2977     auto nodeParent = (node.GetParent().lock());
2978     const auto& property = node.GetRenderProperties();
2979     bool geoDirty = property.IsGeoDirty();
2980     auto& geoPtr = (property.GetBoundsGeometry());
2981     auto prevAlpha = curAlpha_;
2982     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
2983 
2984     if (curSurfaceDirtyManager_ == nullptr) {
2985         RS_LOGE("RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
2986         return;
2987     }
2988 
2989     dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
2990         *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
2991 
2992     if (nodeParent == curSurfaceNode_) {
2993         const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
2994         const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
2995         Drawing::Matrix gravityMatrix;
2996         (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
2997             RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
2998             rootWidth, rootHeight, gravityMatrix);
2999         // Only Apply gravityMatrix when rootNode is dirty
3000         if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
3001             geoPtr->ConcatMatrix(gravityMatrix);
3002         }
3003     }
3004 
3005     if (geoPtr != nullptr) {
3006         parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3007     }
3008 
3009     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
3010     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
3011         node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
3012     PostPrepare(node, !isSubTreeNeedPrepare);
3013 
3014     curAlpha_ = prevAlpha;
3015     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3016     dirtyFlag_ = dirtyFlag;
3017     prepareClipRect_ = prepareClipRect;
3018 }
3019 
ClearRenderGroupCache()3020 void RSUniRenderVisitor::ClearRenderGroupCache()
3021 {
3022     std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
3023     cacheRenderNodeMap.clear();
3024 }
3025 
SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams> & renderThreadParams)3026 void RSUniRenderVisitor::SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams>& renderThreadParams)
3027 {
3028     if (!renderThreadParams) {
3029         RS_LOGE("RSUniRenderVisitor::SetUniRenderThreadParam renderThreadParams is nullptr");
3030         return;
3031     }
3032     renderThreadParams->isPartialRenderEnabled_ = isPartialRenderEnabled_;
3033     renderThreadParams->isRegionDebugEnabled_ = isRegionDebugEnabled_;
3034     renderThreadParams->isDirtyRegionDfxEnabled_ = isDirtyRegionDfxEnabled_;
3035     renderThreadParams->isDisplayDirtyDfxEnabled_ = isDisplayDirtyDfxEnabled_;
3036     renderThreadParams->isOpaqueRegionDfxEnabled_ = isOpaqueRegionDfxEnabled_;
3037     renderThreadParams->isVisibleRegionDfxEnabled_ = isVisibleRegionDfxEnabled_;
3038     renderThreadParams->isAllSurfaceVisibleDebugEnabled_ = isAllSurfaceVisibleDebugEnabled_;
3039     renderThreadParams->isTargetDirtyRegionDfxEnabled_ = isTargetDirtyRegionDfxEnabled_;
3040     renderThreadParams->dirtyRegionDebugType_ = dirtyRegionDebugType_;
3041     renderThreadParams->isOpDropped_ = isOpDropped_;
3042     renderThreadParams->isUIFirstDebugEnable_ = isUIFirstDebugEnable_;
3043     renderThreadParams->dfxTargetSurfaceNames_ = std::move(dfxTargetSurfaceNames_);
3044     renderThreadParams->isVirtualDirtyEnabled_ = isVirtualDirtyEnabled_;
3045     renderThreadParams->isVirtualDirtyDfxEnabled_ = isVirtualDirtyDfxEnabled_;
3046     renderThreadParams->isExpandScreenDirtyEnabled_ = isExpandScreenDirtyEnabled_;
3047     renderThreadParams->hasMirrorDisplay_ = hasMirrorDisplay_;
3048     renderThreadParams->isForceCommitLayer_ |=
3049         RSPointerWindowManager::Instance().IsNeedForceCommitByPointer();
3050 }
3051 
SetAppWindowNum(uint32_t num)3052 void RSUniRenderVisitor::SetAppWindowNum(uint32_t num)
3053 {
3054     appWindowNum_ = num;
3055 }
3056 
SendRcdMessage(RSDisplayRenderNode & node)3057 void RSUniRenderVisitor::SendRcdMessage(RSDisplayRenderNode& node)
3058 {
3059     if ((screenInfo_.state == ScreenState::HDI_OUTPUT_ENABLE) &&
3060         RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
3061         RSRcdRenderManager::GetInstance().CheckRenderTargetNode(RSMainThread::Instance()->GetContext());
3062         RSSingleton<RoundCornerDisplayManager>::GetInstance().AddRoundCornerDisplay(node.GetId());
3063         using rcd_msg = RSSingleton<RsMessageBus>;
3064         rcd_msg::GetInstance().SendMsg<NodeId, uint32_t, uint32_t>(TOPIC_RCD_DISPLAY_SIZE,
3065             node.GetId(), screenInfo_.width, screenInfo_.height);
3066         rcd_msg::GetInstance().SendMsg<NodeId, ScreenRotation>(TOPIC_RCD_DISPLAY_ROTATION,
3067             node.GetId(), node.GetScreenRotation());
3068         rcd_msg::GetInstance().SendMsg<NodeId, int>(TOPIC_RCD_DISPLAY_NOTCH,
3069             node.GetId(), RSSystemParameters::GetHideNotchStatus());
3070     }
3071 }
3072 
ProcessUnpairedSharedTransitionNode()3073 void RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode()
3074 {
3075     static auto unpairNode = [](const std::weak_ptr<RSRenderNode>& wptr) {
3076         auto sptr = wptr.lock();
3077         if (sptr == nullptr) {
3078             return;
3079         }
3080         // make sure parent regenerates ChildrenDrawable
3081         auto parent = sptr->GetParent().lock();
3082         if (parent == nullptr) {
3083             return;
3084         }
3085         parent->AddDirtyType(RSModifierType::CHILDREN);
3086         parent->ApplyModifiers();
3087         // avoid changing the paired status or unpairedShareTransitions_
3088         auto param = sptr->GetSharedTransitionParam();
3089         if (param == nullptr) {
3090             ROSEN_LOGE("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: param is null");
3091             return;
3092         }
3093         param->paired_ = false;
3094         SharedTransitionParam::unpairedShareTransitions_.clear();
3095     };
3096     auto unpairedShareTransitions = std::move(SharedTransitionParam::unpairedShareTransitions_);
3097     for (auto& [id, wptr] : unpairedShareTransitions) {
3098         auto sharedTransitionParam = wptr.lock();
3099         // If the unpaired share transition is already deal with, do nothing
3100         if (!sharedTransitionParam) {
3101             continue;
3102         }
3103         if (!sharedTransitionParam->paired_) {
3104             sharedTransitionParam->ResetRelation();
3105             continue;
3106         }
3107         ROSEN_LOGD("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: mark %s as unpaired",
3108             sharedTransitionParam->Dump().c_str());
3109         sharedTransitionParam->paired_ = false;
3110         unpairNode(sharedTransitionParam->inNode_);
3111         unpairNode(sharedTransitionParam->outNode_);
3112         sharedTransitionParam->ResetRelation();
3113     }
3114 }
3115 
FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)3116 NodeId RSUniRenderVisitor::FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)
3117 {
3118     if (node == nullptr) {
3119         return INVALID_NODEID;
3120     }
3121     auto nodeParent = node->GetParent().lock();
3122     if (nodeParent == nullptr) {
3123         return INVALID_NODEID;
3124     }
3125     if (nodeParent->GetType() == RSRenderNodeType::DISPLAY_NODE) {
3126         return node->GetId();
3127     } else {
3128         return FindInstanceChildOfDisplay(nodeParent);
3129     }
3130 }
3131 
CheckColorFilterChange() const3132 bool RSUniRenderVisitor::CheckColorFilterChange() const
3133 {
3134     if (!RSMainThread::Instance()->IsAccessibilityConfigChanged()) {
3135         return false;
3136     }
3137     RS_LOGD("RSUniRenderVisitor::CheckColorFilterChange changed");
3138     return true;
3139 }
3140 
CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr> & surfaces)3141 void RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr>& surfaces)
3142 {
3143     // Debug dirtyregion of show current refreshRation
3144     if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
3145         RectI tempRect = {100, 100, 500, 200};   // setDirtyRegion for RealtimeRefreshRate
3146         bool surfaceNodeSet = false;
3147         for (auto surface : surfaces) {
3148             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
3149             if (surfaceNode == nullptr) {
3150                 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate surfaceNode is nullptr");
3151                 continue;
3152             }
3153             if (surfaceNode->GetName().find(RELIABLE_GESTURE_BACK_SURFACE_NAME) != std::string::npos) {
3154                 // refresh rate rect for mainwindow
3155                 auto& geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
3156                 if (!geoPtr) {
3157                     break;
3158                 }
3159                 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
3160                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
3161                 surfaceNodeSet = true;
3162                 break;
3163             }
3164         }
3165         if (!surfaceNodeSet) {
3166             auto &geoPtr = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
3167             if (!geoPtr) {
3168                 return;
3169             }
3170             tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
3171             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
3172         }
3173     }
3174 }
3175 
CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode & node)3176 void RSUniRenderVisitor::CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode& node)
3177 {
3178     bool hasAnim = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
3179     if (!node.IsScale() || hasAnim || curCornerRadius_.IsZero() || curAlpha_ < 1) {
3180         node.SetGpuOverDrawBufferOptimizeNode(false);
3181         return;
3182     }
3183 
3184     for (auto& child : *(node.GetChildren())) {
3185         if (!child || !(child->IsInstanceOf<RSSurfaceRenderNode>() &&
3186             RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashOrMainWindow())) {
3187             continue;
3188         }
3189         auto rootNode = child->GetFirstChild();
3190         if (!rootNode) {
3191             break;
3192         }
3193         auto canvasNode = rootNode->GetFirstChild();
3194         if (!canvasNode) {
3195             break;
3196         }
3197         const auto& surfaceProperties = node.GetRenderProperties();
3198         const auto& canvasProperties = canvasNode->GetRenderProperties();
3199         if (canvasProperties.GetAlpha() >= 1
3200             && canvasProperties.GetBackgroundColor().GetAlpha() >= MAX_ALPHA
3201             && canvasProperties.GetFrameWidth() == surfaceProperties.GetFrameWidth()
3202             && canvasProperties.GetFrameHeight() == surfaceProperties.GetFrameHeight()) {
3203             node.SetGpuOverDrawBufferOptimizeNode(true);
3204             node.SetOverDrawBufferNodeCornerRadius(curCornerRadius_);
3205             return;
3206         }
3207     }
3208 
3209     node.SetGpuOverDrawBufferOptimizeNode(false);
3210 }
3211 
SetHdrWhenMultiDisplayChangeInPC()3212 void RSUniRenderVisitor::SetHdrWhenMultiDisplayChangeInPC()
3213 {
3214     if (RSMainThread::Instance()->GetDeviceType() != DeviceType::PC) {
3215         return;
3216     }
3217     auto mainThread = RSMainThread::Instance();
3218     if (!mainThread->GetMultiDisplayChange()) {
3219         return;
3220     }
3221     auto isMultiDisplay = mainThread->GetMultiDisplayStatus();
3222     RS_LOGI("RSUniRenderVisitor::SetHdrWhenMultiDisplayChangeInPC closeHdrStatus: %{public}d.", isMultiDisplay);
3223     RS_TRACE_NAME_FMT("RSUniRenderVisitor::SetHdrWhenMultiDisplayChangeInPC closeHdrStatus: %d", isMultiDisplay);
3224     RSLuminanceControl::Get().ForceCloseHdr(CLOSEHDR_SCENEID::MULTI_DISPLAY, isMultiDisplay);
3225 }
3226 } // namespace Rosen
3227 } // namespace OHOS
3228