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