• 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 "draw/color.h"
26 #include "recording/recording_canvas.h"
27 #include "skia_adapter/skia_canvas.h"
28 
29 #include "src/core/SkCanvasPriv.h"
30 
31 #include "common/rs_background_thread.h"
32 #include "common/rs_common_def.h"
33 #include "common/rs_common_hook.h"
34 #include "common/rs_obj_abs_geometry.h"
35 #include "common/rs_optional_trace.h"
36 #include "common/rs_singleton.h"
37 #include "luminance/rs_luminance_control.h"
38 #include "memory/rs_tag_tracker.h"
39 #include "params/rs_display_render_params.h"
40 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
41 #include "pipeline/rs_base_render_node.h"
42 #include "pipeline/rs_base_render_util.h"
43 #include "pipeline/rs_canvas_drawing_render_node.h"
44 #include "pipeline/rs_display_render_node.h"
45 #include "pipeline/rs_draw_cmd.h"
46 #include "pipeline/rs_effect_render_node.h"
47 #include "pipeline/rs_paint_filter_canvas.h"
48 #include "pipeline/rs_processor_factory.h"
49 #include "pipeline/rs_proxy_render_node.h"
50 #include "pipeline/rs_realtime_refresh_rate_manager.h"
51 #include "pipeline/rs_root_render_node.h"
52 #include "pipeline/rs_surface_render_node.h"
53 #include "pipeline/rs_uni_render_listener.h"
54 #include "pipeline/rs_uni_render_virtual_processor.h"
55 #include "pipeline/rs_uni_render_util.h"
56 #include "pipeline/rs_uifirst_manager.h"
57 #include "pipeline/sk_resource_manager.h"
58 #include "platform/common/rs_log.h"
59 #include "platform/common/rs_system_properties.h"
60 #include "platform/ohos/rs_jank_stats.h"
61 #include "platform/ohos/rs_node_stats.h"
62 #include "property/rs_properties_painter.h"
63 #include "property/rs_point_light_manager.h"
64 #include "render/rs_drawing_filter.h"
65 #include "render/rs_skia_filter.h"
66 #include "system/rs_system_parameters.h"
67 #include "scene_board_judgement.h"
68 #include "hgm_core.h"
69 #include "benchmarks/rs_recording_thread.h"
70 #include "scene_board_judgement.h"
71 #include "metadata_helper.h"
72 #include <v1_0/buffer_handle_meta_key_type.h>
73 #include <v1_0/cm_color_space.h>
74 
75 #include "pipeline/round_corner_display/rs_round_corner_display.h"
76 #include "pipeline/round_corner_display/rs_message_bus.h"
77 
78 #include "rs_profiler.h"
79 #ifdef RS_PROFILER_ENABLED
80 #include "rs_profiler_capture_recorder.h"
81 #endif
82 
83 namespace OHOS {
84 namespace Rosen {
85 namespace {
86 constexpr uint32_t PHONE_MAX_APP_WINDOW_NUM = 1;
87 constexpr int32_t CACHE_MAX_UPDATE_TIME = 2;
88 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
89 constexpr int MAX_ALPHA = 255;
90 constexpr int TRACE_LEVEL_THREE = 3;
91 constexpr float EPSILON_SCALE = 0.00001f;
92 constexpr float CACHE_FILL_ALPHA = 0.2f;
93 constexpr float CACHE_UPDATE_FILL_ALPHA = 0.8f;
94 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
95 constexpr const char* CLEAR_GPU_CACHE = "ClearGpuCache";
96 constexpr const char* RELIABLE_GESTURE_BACK_SURFACE_NAME = "SCBGestureBack";
97 constexpr int MIN_OVERLAP = 2;
98 static std::map<NodeId, uint32_t> cacheRenderNodeMap = {};
99 static uint32_t cacheReuseTimes = 0;
100 static std::mutex cacheRenderNodeMapMutex;
101 static const std::map<DirtyRegionType, std::string> DIRTY_REGION_TYPE_MAP {
102     { DirtyRegionType::UPDATE_DIRTY_REGION, "UPDATE_DIRTY_REGION" },
103     { DirtyRegionType::OVERLAY_RECT, "OVERLAY_RECT" },
104     { DirtyRegionType::FILTER_RECT, "FILTER_RECT" },
105     { DirtyRegionType::SHADOW_RECT, "SHADOW_RECT" },
106     { DirtyRegionType::PREPARE_CLIP_RECT, "PREPARE_CLIP_RECT" },
107     { DirtyRegionType::REMOVE_CHILD_RECT, "REMOVE_CHILD_RECT" },
108     { DirtyRegionType::RENDER_PROPERTIES_RECT, "RENDER_PROPERTIES_RECT" },
109     { DirtyRegionType::CANVAS_NODE_SKIP_RECT, "CANVAS_NODE_SKIP_RECT" },
110     { DirtyRegionType::OUTLINE_RECT, "OUTLINE_RECT" },
111 };
112 
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)113 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
114 {
115     if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
116         auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
117         const auto& property = rootNode->GetRenderProperties();
118         if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
119             return true;
120         }
121     }
122     return false;
123 }
124 
CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)125 bool CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
126 {
127     if (child != nullptr && child->IsInstanceOf<RSCanvasRenderNode>()) {
128         auto canvasRenderNode = child->ReinterpretCastTo<RSCanvasRenderNode>();
129         const auto& property = canvasRenderNode->GetRenderProperties();
130         if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0) {
131             return true;
132         }
133     }
134     return false;
135 }
136 
IsFirstFrameReadyToDraw(const RSSurfaceRenderNode & node)137 bool IsFirstFrameReadyToDraw(const RSSurfaceRenderNode& node)
138 {
139     bool result = false;
140     auto sortedChildren = node.GetSortedChildren();
141     if (node.IsScbScreen() || node.IsSCBNode()) {
142         for (const auto& child : *sortedChildren) {
143             result = CheckScbReadyToDraw(child);
144         }
145         return result;
146     }
147     for (auto& child : *sortedChildren) {
148         result = CheckRootNodeReadyToDraw(child);
149         // when appWindow has abilityComponent node
150         if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
151             for (const auto& surfaceNodeChild : *child->GetSortedChildren()) {
152                 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
153             }
154         }
155     }
156     return result;
157 }
158 
VisibleDataToString(const VisibleData & val)159 std::string VisibleDataToString(const VisibleData& val)
160 {
161     std::stringstream ss;
162     ss << "VisibleData[name, nodeId, visibleLevel]:";
163     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
164     for (const auto& v : val) {
165         auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(v.first);
166         auto name = surfaceNode ? surfaceNode->GetName() : "";
167         ss << "[" << name << ", " << v.first << ", " << v.second << "], ";
168     }
169     return ss.str();
170 }
171 } // namespace
172 
DoScreenRcdTask(std::shared_ptr<RSProcessor> & processor,std::unique_ptr<RcdInfo> & rcdInfo,ScreenInfo & screenInfo_)173 void DoScreenRcdTask(std::shared_ptr<RSProcessor>& processor, std::unique_ptr<RcdInfo>& rcdInfo,
174     ScreenInfo& screenInfo_)
175 {
176     if (screenInfo_.state != ScreenState::HDI_OUTPUT_ENABLE) {
177         RS_LOGD("DoScreenRcdTask is not at HDI_OUPUT mode");
178         return;
179     }
180     if (RSSingleton<RoundCornerDisplay>::GetInstance().GetRcdEnable()) {
181         RSSingleton<RoundCornerDisplay>::GetInstance().RunHardwareTask(
182             [&processor, &rcdInfo]() {
183                 auto hardInfo = RSSingleton<RoundCornerDisplay>::GetInstance().GetHardwareInfo();
184                 rcdInfo->processInfo = {processor, hardInfo.topLayer, hardInfo.bottomLayer,
185                     hardInfo.resourceChanged};
186                 RSRcdRenderManager::GetInstance().DoProcessRenderTask(rcdInfo->processInfo);
187             }
188         );
189     }
190 }
191 
RSUniRenderVisitor()192 RSUniRenderVisitor::RSUniRenderVisitor()
193     : curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
194 {
195     PartialRenderOptionInit();
196     auto mainThread = RSMainThread::Instance();
197     renderEngine_ = mainThread->GetRenderEngine();
198     hasMirrorDisplay_ = mainThread->HasMirrorDisplay();
199     quickSkipPrepareType_ = RSSystemParameters::GetQuickSkipPrepareType();
200     // when occlusion enabled is false, subTree do not skip, but not influence visible region
201     isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
202     isQuickSkipPreparationEnabled_ = (quickSkipPrepareType_ != QuickSkipPrepareType::DISABLED);
203     isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
204 #ifdef DDGR_ENABLE_FEATURE_OPINC
205     autoCacheEnable_ = RSSystemProperties::IsDdgrOpincEnable();
206 #endif
207     RSTagTracker::UpdateReleaseResourceEnabled(RSSystemProperties::GetReleaseResourceEnabled());
208     isScreenRotationAnimating_ = RSSystemProperties::GetCacheEnabledForRotation();
209     isSubSurfaceEnabled_ = RSSystemProperties::GetSubSurfaceEnabled() && RSSystemProperties::IsPhoneType();
210     isSkipCanvasNodeOutOfScreen_ = RSSystemParameters::GetSkipCanvasNodeOutofScreenEnabled();
211     if (RSRcdRenderManager::GetInstance().GetRcdRenderEnabled()) {
212         rcdInfo_ = std::make_unique<RcdInfo>();
213     }
214 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
215     if (renderEngine_ && renderEngine_->GetRenderContext()) {
216         auto subThreadManager = RSSubThreadManager::Instance();
217         subThreadManager->Start(renderEngine_->GetRenderContext().get());
218     }
219 #endif
220     isUIFirst_ = RSMainThread::Instance()->IsUIFirstOn();
221     isUIFirstDebugEnable_ = RSSystemProperties::GetUIFirstDebugEnabled();
222     isPhone_ = RSMainThread::Instance()->GetDeviceType() == DeviceType::PHONE;
223     isPc_ = RSMainThread::Instance()->GetDeviceType() == DeviceType::PC;
224     isCurtainScreenOn_ = RSMainThread::Instance()->IsCurtainScreenOn();
225     isPrevalidateHwcNodeEnable_ = RSSystemParameters::GetPrevalidateHwcNodeEnabled() &&
226         RSUniHwcPrevalidateUtil::GetInstance().IsLoadSuccess();
227     isOverdrawDfxOn_ = RSOverdrawController::GetInstance().IsEnabled();
228 }
229 
PartialRenderOptionInit()230 void RSUniRenderVisitor::PartialRenderOptionInit()
231 {
232     partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
233     isPartialRenderEnabled_ = (partialRenderType_ != PartialRenderType::DISABLED);
234     isCompleteRenderEnabled_ = (partialRenderType_ == PartialRenderType::SET_DAMAGE_BUT_COMPLETE_RENDER);
235     dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
236     surfaceRegionDebugType_ = RSSystemProperties::GetSurfaceRegionDfxType();
237     isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_) &&
238         (surfaceRegionDebugType_ == SurfaceRegionDebugType::DISABLED);
239     isRegionDebugEnabled_ = (dirtyRegionDebugType_ != DirtyRegionDebugType::DISABLED) ||
240         (surfaceRegionDebugType_ != SurfaceRegionDebugType::DISABLED) || (dfxTargetSurfaceNames_.size() > 0);
241     isVisibleRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::VISIBLE_REGION);
242     isOpaqueRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::OPAQUE_REGION);
243     isAllSurfaceVisibleDebugEnabled_ = RSSystemProperties::GetAllSurfaceVisibleDebugEnabled();
244     isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
245         (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
246     isDisplayDirtyDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
247         (dirtyRegionDebugType_ == DirtyRegionDebugType::DISPLAY_DIRTY);
248     isCanvasNodeSkipDfxEnabled_ = (dirtyRegionDebugType_ == DirtyRegionDebugType::CANVAS_NODE_SKIP_RECT);
249     isOpDropped_ = isPartialRenderEnabled_ &&
250         (partialRenderType_ != PartialRenderType::SET_DAMAGE) && !isRegionDebugEnabled_;
251     isCacheBlurPartialRenderEnabled_ = RSSystemProperties::GetCachedBlurPartialRenderEnabled();
252     isVirtualDirtyDfxEnabled_ = RSSystemProperties::GetVirtualDirtyDebugEnabled();
253     isVirtualDirtyEnabled_ = RSSystemProperties::GetVirtualDirtyEnabled() &&
254         (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL);
255     isExpandScreenDirtyEnabled_ = RSSystemProperties::GetExpandScreenDirtyEnabled();
256 }
257 
RSUniRenderVisitor(const RSUniRenderVisitor & visitor)258 RSUniRenderVisitor::RSUniRenderVisitor(const RSUniRenderVisitor& visitor) : RSUniRenderVisitor()
259 {
260     currentVisitDisplay_ = visitor.currentVisitDisplay_;
261     screenInfo_ = visitor.screenInfo_;
262     displayHasSecSurface_ = visitor.displayHasSecSurface_;
263     displayHasSkipSurface_ = visitor.displayHasSkipSurface_;
264     displayHasProtectedSurface_ = visitor.displayHasProtectedSurface_;
265     displaySpecailSurfaceChanged_ = visitor.displaySpecailSurfaceChanged_;
266     hasCaptureWindow_ = visitor.hasCaptureWindow_;
267     parentSurfaceNodeMatrix_ = visitor.parentSurfaceNodeMatrix_;
268     curAlpha_ = visitor.curAlpha_;
269     dirtyFlag_ = visitor.dirtyFlag_;
270     curDisplayNode_ = visitor.curDisplayNode_;
271     currentFocusedNodeId_ = visitor.currentFocusedNodeId_;
272     prepareClipRect_ = visitor.prepareClipRect_;
273     isOpDropped_ = visitor.isOpDropped_;
274     isPartialRenderEnabled_ = visitor.isPartialRenderEnabled_;
275     isAllSurfaceVisibleDebugEnabled_ = visitor.isAllSurfaceVisibleDebugEnabled_;
276     isHardwareForcedDisabled_ = visitor.isHardwareForcedDisabled_;
277     doAnimate_ = visitor.doAnimate_;
278     isDirty_ = visitor.isDirty_;
279 }
280 
~RSUniRenderVisitor()281 RSUniRenderVisitor::~RSUniRenderVisitor() {}
282 
CopyVisitorInfos(std::shared_ptr<RSUniRenderVisitor> visitor)283 void RSUniRenderVisitor::CopyVisitorInfos(std::shared_ptr<RSUniRenderVisitor> visitor)
284 {
285     std::unique_lock<std::mutex> lock(copyVisitorInfosMutex_);
286     currentVisitDisplay_ = visitor->currentVisitDisplay_;
287     screenInfo_ = visitor->screenInfo_;
288     displayHasSecSurface_ = visitor->displayHasSecSurface_;
289     displayHasSkipSurface_ = visitor->displayHasSkipSurface_;
290     displayHasProtectedSurface_ = visitor->displayHasProtectedSurface_;
291     displaySpecailSurfaceChanged_ = visitor->displaySpecailSurfaceChanged_;
292     hasCaptureWindow_ = visitor->hasCaptureWindow_;
293     parentSurfaceNodeMatrix_ = visitor->parentSurfaceNodeMatrix_;
294     curAlpha_ = visitor->curAlpha_;
295     dirtyFlag_ = visitor->dirtyFlag_;
296     curDisplayNode_ = visitor->curDisplayNode_;
297     currentFocusedNodeId_ = visitor->currentFocusedNodeId_;
298     prepareClipRect_ = visitor->prepareClipRect_;
299     isOpDropped_ = visitor->isOpDropped_;
300     isPartialRenderEnabled_ = visitor->isPartialRenderEnabled_;
301     isAllSurfaceVisibleDebugEnabled_ = visitor->isAllSurfaceVisibleDebugEnabled_;
302     isHardwareForcedDisabled_ = visitor->isHardwareForcedDisabled_;
303     doAnimate_ = visitor->doAnimate_;
304     isDirty_ = visitor->isDirty_;
305 }
306 
UpdateSubTreeInCache(const std::shared_ptr<RSRenderNode> & cacheRootNode,const std::vector<RSRenderNode::SharedPtr> & children)307 void RSUniRenderVisitor::UpdateSubTreeInCache(const std::shared_ptr<RSRenderNode>& cacheRootNode,
308     const std::vector<RSRenderNode::SharedPtr>& children)
309 {
310     for (auto& child : children) {
311         if (child == nullptr) {
312             continue;
313         }
314         auto isDirty = child->IsDirty();
315         if (isDirty) {
316             curDirty_ = isDirty;
317             child->Prepare(shared_from_this());
318             continue;
319         }
320         // set flag for surface node whose children contain shared transition node
321         if (child->GetSharedTransitionParam() && curSurfaceNode_) {
322             SetHasSharedTransitionNode(*curSurfaceNode_, true);
323         }
324         // [planning] pay attention to outofparent case
325         if (auto surfaceNode = child->ReinterpretCastTo<RSSurfaceRenderNode>()) {
326             // fully prepare hwcLayer Layer and its subnodes
327             if (surfaceNode->IsHardwareEnabledType()) {
328                 PrepareSurfaceRenderNode(*surfaceNode);
329                 return;
330             }
331         } else if (auto effectNode = child->ReinterpretCastTo<RSEffectRenderNode>()) {
332             // effectNode need to update effectRegion so effectNode and use-effect child should be updated
333             PrepareEffectNodeIfCacheReuse(cacheRootNode, effectNode);
334             return;
335         }
336         const auto& property =  child->GetRenderProperties();
337         if (property.NeedFilter() || property.GetUseEffect()) {
338             child->Update(*curSurfaceDirtyManager_, cacheRootNode, dirtyFlag_, prepareClipRect_);
339         }
340         if (property.NeedFilter()) {
341             UpdateForegroundFilterCacheWithDirty(*child, *curSurfaceDirtyManager_);
342             if (curSurfaceNode_ && curSurfaceNode_->GetId() == child->GetInstanceRootNodeId()) {
343                 curSurfaceNode_->UpdateChildrenFilterRects(child, child->GetOldDirtyInSurface(),
344                     child->IsFilterCacheValid());
345             }
346         }
347         UpdateSubTreeInCache(child, *child->GetSortedChildren());
348     }
349 }
350 
PrepareEffectNodeIfCacheReuse(const std::shared_ptr<RSRenderNode> & cacheRootNode,std::shared_ptr<RSEffectRenderNode> effectNode)351 void RSUniRenderVisitor::PrepareEffectNodeIfCacheReuse(const std::shared_ptr<RSRenderNode>& cacheRootNode,
352     std::shared_ptr<RSEffectRenderNode> effectNode)
353 {
354     if (effectNode == nullptr || curSurfaceDirtyManager_ == nullptr) {
355         return;
356     }
357     // set rotationChanged true when screen is rotating or folding/expanding screen.
358     UpdateRotationStatusForEffectNode(*effectNode);
359     effectNode->SetVisitedFilterCacheStatus(curSurfaceDirtyManager_->IsCacheableFilterRectEmpty());
360     effectNode->Update(*curSurfaceDirtyManager_, cacheRootNode, dirtyFlag_, prepareClipRect_);
361     UpdateSubTreeInCache(effectNode, *effectNode->GetSortedChildren());
362     if (effectNode->GetRenderProperties().NeedFilter()) {
363         UpdateForegroundFilterCacheWithDirty(*effectNode, *curSurfaceDirtyManager_);
364         if (curSurfaceNode_ && curSurfaceNode_->GetId() == effectNode->GetInstanceRootNodeId()) {
365             curSurfaceNode_->UpdateChildrenFilterRects(effectNode, effectNode->GetOldDirtyInSurface(),
366                 effectNode->IsFilterCacheValid());
367         }
368     }
369 }
370 
PrepareChildren(RSRenderNode & node)371 void RSUniRenderVisitor::PrepareChildren(RSRenderNode& node)
372 {
373     // GetSortedChildren() may remove disappearingChildren_ when transition animation end.
374     // So the judgement whether node has removed child should be executed after this.
375     // NOTE: removal of transition node is moved to RSMainThread::Animate
376     MergeRemovedChildDirtyRegion(node);
377     // backup environment variables.
378     node.ResetChildrenRect();
379     const auto& properties = node.GetRenderProperties();
380 
381     if (!isSubNodeOfSurfaceInPrepare_) {
382         Vector4f::Max(properties.GetCornerRadius(), curCornerRadius_, curCornerRadius_);
383     }
384     if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
385         node.SetGlobalCornerRadius(curCornerRadius_);
386     }
387 
388     float alpha = curAlpha_;
389     curAlpha_ *= properties.GetAlpha();
390     node.SetGlobalAlpha(curAlpha_);
391     const auto& children = node.GetSortedChildren();
392     // check curSurfaceDirtyManager_ for SubTree updates
393     if (curSurfaceDirtyManager_ != nullptr && isCachedSurfaceReuse_ && !node.HasMustRenewedInfo()) {
394         RS_OPTIONAL_TRACE_NAME_FMT("CachedSurfaceReuse node %llu quickSkip subtree", node.GetId());
395     } else if (curSurfaceDirtyManager_ != nullptr && curDisplayNode_ != nullptr &&
396         (isCachedSurfaceReuse_ || isSurfaceDirtyNodeLimited_ || !UpdateCacheChangeStatus(node))) {
397         RS_OPTIONAL_TRACE_NAME_FMT("UpdateCacheChangeStatus node %llu simply update subtree, isCachedSurfaceReuse_ %d,"
398             " isSurfaceDirtyNodeLimited_ %d, hasUseEffect %d", node.GetId(), isCachedSurfaceReuse_,
399             isSurfaceDirtyNodeLimited_, node.ChildHasVisibleEffect());
400         UpdateSubTreeInCache(node.ReinterpretCastTo<RSRenderNode>(), *children);
401         node.UpdateEffectRegion(effectRegion_,
402             (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE && node.ChildHasVisibleEffect()));
403     } else {
404         // Get delay flag to restore geo changes
405         if (node.GetGeoUpdateDelay()) {
406             dirtyFlag_ = true;
407         }
408         node.SetChildHasVisibleEffect(false);
409         for (auto& child : *children) {
410             SaveCurSurface();
411             curDirty_ = child->IsDirty();
412             child->Prepare(shared_from_this());
413             if (child->ChildHasVisibleEffect()) {
414                 node.SetChildHasVisibleEffect(true);
415             }
416             RestoreCurSurface();
417         }
418         // Reset delay flag
419         node.ResetGeoUpdateDelay();
420         SetNodeCacheChangeStatus(node);
421     }
422 
423     node.SetSubTreeDirty(false);
424     curAlpha_ = alpha;
425     // restore environment variables
426 }
427 
MergeRemovedChildDirtyRegion(RSRenderNode & node,bool needMap)428 void RSUniRenderVisitor::MergeRemovedChildDirtyRegion(RSRenderNode& node, bool needMap)
429 {
430     if (!node.HasRemovedChild()) {
431         return;
432     }
433     RectI dirtyRect = node.GetChildrenRect();
434     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
435     if (dirtyManager == nullptr || dirtyRect.IsEmpty()) {
436         node.ResetHasRemovedChild();
437         return;
438     }
439 
440     // [planning] merge removed child's rect instead
441     if (needMap) {
442         if (auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry()) {
443             dirtyRect = geoPtr->MapAbsRect(dirtyRect.ConvertTo<float>());
444         }
445         if (!node.HasChildrenOutOfRect()) {
446             dirtyRect = dirtyRect.IntersectRect(node.GetOldClipRect());
447         }
448     } else {
449         dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
450     }
451     dirtyManager->MergeDirtyRect(dirtyRect);
452     RS_OPTIONAL_TRACE_NAME_FMT("MergeRemovedChildDirtyRegion NodeId:%" PRIu64 ", dirty rect:%s",
453         node.GetId(), dirtyRect.ToString().c_str());
454     if (dirtyManager->IsTargetForDfx()) {
455         // since childRect includes multiple rects, defaultly marked as canvas_node
456         dirtyManager->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
457             DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
458     }
459     node.ResetHasRemovedChild();
460 }
461 
IsDrawingCacheStatic(RSRenderNode & node)462 bool RSUniRenderVisitor::IsDrawingCacheStatic(RSRenderNode& node)
463 {
464     // since this function only called by drawing group root
465     // if cache valid, cacheRenderNodeMapCnt > 0
466     // check all dirtynodes of app instance if there's any in cache subtree
467     if (curContentDirty_ || node.GetDrawingCacheChanged() || !node.IsCacheCompletedSurfaceValid() ||
468         curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetInstanceRootNodeId() ||
469         RSMainThread::Instance()->IsDrawingGroupChanged(node)) {
470         return false;
471     }
472     // skip targeted cache node when first visited node is forced cache
473     if (node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE && firstVisitedCache_ != node.GetId() &&
474         IsFirstVisitedCacheForced()) {
475         return false;
476     }
477     // simplify Cache status reset
478     node.GetFilterRectsInCache(allCacheFilterRects_);
479     node.SetDrawingCacheChanged(false);
480     node.SetGeoUpdateDelay(dirtyFlag_);
481     if (allCacheFilterRects_.count(node.GetId())) {
482         node.SetChildHasVisibleFilter(true);
483         if (const auto directParent = node.GetParent().lock()) {
484             directParent->SetChildHasVisibleFilter(true);
485         }
486     }
487     return true;
488 }
489 
UpdateCacheChangeStatus(RSRenderNode & node)490 bool RSUniRenderVisitor::UpdateCacheChangeStatus(RSRenderNode& node)
491 {
492     node.SetChildHasVisibleFilter(false);
493     if (!isDrawingCacheEnabled_) {
494         return true;
495     }
496     node.CheckDrawingCacheType();
497     if (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE && !node.IsStaticCached() &&
498         (!node.ShouldPaint() || isScreenRotationAnimating_)) {
499         node.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
500     }
501     // skip status check if there is no upper cache mark
502     if (node.GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE && firstVisitedCache_ == INVALID_NODEID) {
503         return true;
504     }
505     // subroot's dirty and cached filter should be count for parent root
506     if (!isDrawingCacheChanged_.empty()) {
507         // Any child node dirty causes cache change
508         RS_OPTIONAL_TRACE_NAME_FMT("UpdateCacheChangeStatus child:%" PRIu64 "", node.GetId());
509         isDrawingCacheChanged_.top() = isDrawingCacheChanged_.top() || curDirty_;
510     }
511     const auto& properties = node.GetRenderProperties();
512     if (!curCacheFilterRects_.empty() && !node.IsInstanceOf<RSEffectRenderNode>() &&
513         (properties.GetBackgroundFilter() || properties.GetUseEffect() ||
514         properties.GetShadowColorStrategy() != SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE)) {
515         curCacheFilterRects_.top().emplace(node.GetId());
516     }
517     // drawing group root node
518     if (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE) {
519         // if firstVisitedCache_ valid, upper cache should be updated so sub cache shouldn't skip
520         // [planning] static subcache could be skip and reuse
521         if ((quickSkipPrepareType_ >= QuickSkipPrepareType::STATIC_CACHE) &&
522             (firstVisitedCache_ == INVALID_NODEID) && IsDrawingCacheStatic(node)) {
523             return false;
524         }
525         // For rootnode, init drawing changes only if there is any content dirty
526         isDrawingCacheChanged_.push(curContentDirty_);
527         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateCacheChangeStatus: cachable node %" PRIu64 ""
528             "contentDirty(cacheChanged): %d", node.GetId(), static_cast<int>(isDrawingCacheChanged_.top()));
529         curCacheFilterRects_.push({});
530         if (firstVisitedCache_ == INVALID_NODEID) {
531             firstVisitedCache_ = node.GetId();
532         }
533     }
534     return true;
535 }
536 
DisableNodeCacheInSetting(RSRenderNode & node)537 void RSUniRenderVisitor::DisableNodeCacheInSetting(RSRenderNode& node)
538 {
539     if (node.IsStaticCached()) {
540         return;
541     }
542     // Attention: filter node should be marked. Only enable lowest suggested cached node
543     if (node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
544         auto childrenOutOfRect = node.HasChildrenOutOfRect();
545         auto firstVisitedCacheForced = IsFirstVisitedCacheForced();
546         // if target cached is reused, keep enable -- prepareskip
547         // disable cache if it has outOfParent -- cannot cache right
548         // [planning] if there is dirty subcache, disable upper targetcache
549         // disable targeted cache node when first visited node is forced cache to avoid problem in case with blur
550         if (childrenOutOfRect || (firstVisitedCache_ != node.GetId() && firstVisitedCacheForced)) {
551             node.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
552             allCacheFilterRects_[firstVisitedCache_].insert(allCacheFilterRects_[node.GetId()].begin(),
553                 allCacheFilterRects_[node.GetId()].end());
554             allCacheFilterRects_.erase(node.GetId());
555             RS_OPTIONAL_TRACE_NAME_FMT("Disable cache %llu: outofparent %d, firstVisitedCache_ %llu & cacheforce %d",
556                 node.GetId(), childrenOutOfRect, firstVisitedCache_, firstVisitedCacheForced);
557         }
558     }
559     if (firstVisitedCache_ == INVALID_NODEID) {
560         node.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
561         std::stack<bool>().swap(isDrawingCacheChanged_);
562         visitedCacheNodeIds_.clear();
563     }
564 }
565 
IsFirstVisitedCacheForced() const566 bool RSUniRenderVisitor::IsFirstVisitedCacheForced() const
567 {
568     if (firstVisitedCache_ != INVALID_NODEID) {
569         auto firstVisitedNode = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode<RSRenderNode>(
570             firstVisitedCache_);
571         if (firstVisitedNode && firstVisitedNode->GetDrawingCacheType() == RSDrawingCacheType::FORCED_CACHE) {
572             return true;
573         }
574     }
575     return false;
576 }
577 
SaveCurSurface()578 void RSUniRenderVisitor::SaveCurSurface()
579 {
580     if (!isSubSurfaceEnabled_) {
581         return;
582     }
583     surfaceDirtyManager_.push(curSurfaceDirtyManager_);
584     surfaceNode_.push(curSurfaceNode_);
585 }
586 
RestoreCurSurface()587 void RSUniRenderVisitor::RestoreCurSurface()
588 {
589     if (!isSubSurfaceEnabled_) {
590         return;
591     }
592     curSurfaceDirtyManager_ = surfaceDirtyManager_.top();
593     curSurfaceNode_ = surfaceNode_.top();
594     surfaceDirtyManager_.pop();
595     surfaceNode_.pop();
596 }
597 
PrepareSubSurfaceNodes(RSSurfaceRenderNode & node)598 void RSUniRenderVisitor::PrepareSubSurfaceNodes(RSSurfaceRenderNode& node)
599 {
600     if (!isSubSurfaceEnabled_) {
601         return;
602     }
603     for (auto &nodes : node.GetSubSurfaceNodes()) {
604         for (auto &node : nodes.second) {
605             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.lock());
606             if (surfaceNode != nullptr) {
607                 SaveCurSurface();
608                 PrepareSurfaceRenderNode(*surfaceNode);
609                 RestoreCurSurface();
610             }
611         }
612     }
613 }
614 
ProcessSubSurfaceNodes(RSSurfaceRenderNode & node)615 void RSUniRenderVisitor::ProcessSubSurfaceNodes(RSSurfaceRenderNode& node)
616 {
617     if (!isSubSurfaceEnabled_) {
618         return;
619     }
620     for (auto &nodes : node.GetSubSurfaceNodes()) {
621         for (auto &node : nodes.second) {
622             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.lock());
623             if (surfaceNode != nullptr) {
624                 SaveCurSurface();
625                 ProcessSurfaceRenderNode(*surfaceNode);
626                 RestoreCurSurface();
627             }
628         }
629     }
630 }
631 
SetNodeCacheChangeStatus(RSRenderNode & node)632 void RSUniRenderVisitor::SetNodeCacheChangeStatus(RSRenderNode& node)
633 {
634     if (node.ChildHasVisibleFilter()) {
635         auto directParent = node.GetParent().lock();
636         if (directParent != nullptr) {
637             directParent->SetChildHasVisibleFilter(true);
638         }
639     }
640     auto drawingCacheType = node.GetDrawingCacheType();
641     if (!isDrawingCacheEnabled_ ||
642         drawingCacheType == RSDrawingCacheType::DISABLED_CACHE) {
643         return;
644     }
645     if (!curCacheFilterRects_.empty()) {
646         allCacheFilterRects_[node.GetId()].insert(curCacheFilterRects_.top().begin(),
647             curCacheFilterRects_.top().end());
648         node.ResetFilterRectsInCache(allCacheFilterRects_[node.GetId()]);
649         curCacheFilterRects_.pop();
650     }
651     DisableNodeCacheInSetting(node);
652     if (drawingCacheType != RSDrawingCacheType::DISABLED_CACHE) {
653         // update visited cache roots including itself
654         visitedCacheNodeIds_.emplace(node.GetId());
655         node.SetVisitedCacheRootIds(visitedCacheNodeIds_);
656         if (curSurfaceNode_) {
657             curSurfaceNode_->UpdateDrawingCacheNodes(node.ReinterpretCastTo<RSRenderNode>());
658         }
659     }
660     bool isDrawingCacheChanged = isDrawingCacheChanged_.empty() || isDrawingCacheChanged_.top();
661     RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::SetNodeCacheChangeStatus: node %" PRIu64 " drawingtype %d, "
662         "staticCache %d, cacheChange %d, childHasVisibleFilter|effect: %d|%d, outofparent: %d, "
663         "visitedCacheNodeIds num: %lu",
664         node.GetId(), static_cast<int>(node.GetDrawingCacheType()), node.IsStaticCached(),
665         static_cast<int>(isDrawingCacheChanged), node.ChildHasVisibleFilter(), node.ChildHasVisibleEffect(),
666         static_cast<int>(node.HasChildrenOutOfRect()), visitedCacheNodeIds_.size());
667     node.SetDrawingCacheChanged(!node.IsStaticCached() && isDrawingCacheChanged);
668     // reset counter after executing the very first marked node
669     if (firstVisitedCache_ == node.GetId()) {
670         std::stack<bool>().swap(isDrawingCacheChanged_);
671         firstVisitedCache_ = INVALID_NODEID;
672         visitedCacheNodeIds_.clear();
673     } else if (!isDrawingCacheChanged_.empty()) {
674         bool isChildChanged = isDrawingCacheChanged_.top();
675         isDrawingCacheChanged_.pop();
676         if (!isDrawingCacheChanged_.empty()) {
677             isDrawingCacheChanged_.top() = isDrawingCacheChanged_.top() || isChildChanged;
678         }
679     }
680 }
681 
CheckColorSpace(RSSurfaceRenderNode & node)682 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
683 {
684     // currently, P3 is the only supported wide color gamut, this may be modified later.
685     if (node.IsAppWindow() && node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
686         newColorSpace_ = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
687         RS_LOGD("RSUniRenderVisitor::CheckColorSpace: node(%{public}s) set new colorgamut %{public}d",
688             node.GetName().c_str(), newColorSpace_);
689     }
690 }
691 
CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode & node)692 void RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode& node)
693 {
694     if (!node.IsOnTheTree()) {
695         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is not on the tree",
696             node.GetName().c_str());
697         return;
698     }
699     if (!node.IsHardwareForcedDisabled()) {
700         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is hardware-enabled",
701             node.GetName().c_str());
702         return;
703     }
704     // currently, P3 is the only supported wide color gamut, this may be modified later.
705     node.UpdateColorSpaceWithMetadata();
706     if (node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
707         newColorSpace_ = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
708         RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) set new colorgamut %{public}d",
709             node.GetName().c_str(), newColorSpace_);
710     }
711 }
712 
UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode & node)713 void RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode& node)
714 {
715     const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
716     for (const auto& selfDrawingNode : selfDrawingNodes) {
717         if (newColorSpace_ == GRAPHIC_COLOR_GAMUT_DISPLAY_P3) {
718             RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc: newColorSpace is already DISPLAY_P3.");
719             return;
720         }
721         if (!selfDrawingNode || !selfDrawingNode->GetAncestorDisplayNode().lock()) {
722             RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc selfDrawingNode or ancestorNode is nullptr");
723             continue;
724         }
725         auto ancestor = selfDrawingNode->GetAncestorDisplayNode().lock()->ReinterpretCastTo<RSDisplayRenderNode>();
726         if (ancestor != nullptr && node.GetId() == ancestor->GetId()) {
727             CheckColorSpaceWithSelfDrawingNode(*selfDrawingNode);
728         }
729     }
730 }
731 
HandleColorGamuts(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)732 void RSUniRenderVisitor::HandleColorGamuts(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
733 {
734     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
735     if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
736         RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen type failed.");
737         return;
738     }
739 
740     if (screenType == VIRTUAL_TYPE_SCREEN) {
741         ScreenColorGamut screenColorGamut;
742         if (screenManager->GetScreenColorGamut(node.GetScreenId(), screenColorGamut) != SUCCESS) {
743             RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen color gamut failed.");
744             return;
745         }
746         newColorSpace_ = static_cast<GraphicColorGamut>(screenColorGamut);
747     }
748 
749     auto stagingDisplayParams = static_cast<RSDisplayRenderParams*>(node.GetStagingRenderParams().get());
750     if (stagingDisplayParams) {
751         stagingDisplayParams->SetNewColorSpace(newColorSpace_);
752     }
753     newColorSpace_ = GRAPHIC_COLOR_GAMUT_SRGB;
754 }
755 
CheckPixelFormat(RSSurfaceRenderNode & node)756 void RSUniRenderVisitor::CheckPixelFormat(RSSurfaceRenderNode& node)
757 {
758     if (node.GetHDRPresent()) {
759         RS_LOGD("SetHDRPresent true, surfaceNode: %{public}" PRIu64 "", node.GetId());
760         hasUniRenderHdrSurface_ = true;
761     }
762     if (hasFingerprint_) {
763         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat hasFingerprint is true.");
764         return;
765     }
766     if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
767         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat node(%{public}s) did not have buffer.", node.GetName().c_str());
768         return;
769     }
770 
771     const sptr<SurfaceBuffer>& buffer = node.GetRSSurfaceHandler()->GetBuffer();
772 
773     if (node.GetFingerprint()) {
774         hasFingerprint_ = true;
775         newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_1010102;
776         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat newPixelFormat_ is set 1010102 for fingerprint.");
777         return;
778     }
779 
780     auto bufferPixelFormat = buffer->GetFormat();
781     if ((bufferPixelFormat == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
782         bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCBCR_P010 ||
783         bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCRCB_P010) && !IsHardwareComposerEnabled()) {
784         newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_1010102;
785         RS_LOGD("RSUniRenderVisitor::CheckPixelFormat pixelformat is set to 1010102 for 10bit buffer");
786     }
787 }
788 
HandlePixelFormat(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)789 void RSUniRenderVisitor::HandlePixelFormat(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
790 {
791     if (!RSSystemProperties::GetHDRImageEnable()) {
792         hasUniRenderHdrSurface_ = false;
793     }
794     auto stagingDisplayParams = static_cast<RSDisplayRenderParams*>(node.GetStagingRenderParams().get());
795     if (!stagingDisplayParams) {
796         RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get StagingRenderParams failed.");
797         return;
798     }
799     ScreenId screenId = stagingDisplayParams->GetScreenId();
800     RSLuminanceControl::Get().SetHdrStatus(screenId, hasUniRenderHdrSurface_);
801     bool isHdrOn = RSLuminanceControl::Get().IsHdrOn(screenId);
802     float brightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
803     RS_TRACE_NAME_FMT("HDR:%d, in Unirender:%d brightnessRatio:%f", isHdrOn, hasUniRenderHdrSurface_, brightnessRatio);
804     RS_LOGD("RSUniRenderVisitor::HandlePixelFormat HDR isHdrOn:%{public}d hasUniRenderHdrSurface:%{public}d "
805         "brightnessRatio:%{public}f", isHdrOn, hasUniRenderHdrSurface_, brightnessRatio);
806     if (!hasUniRenderHdrSurface_) {
807         isHdrOn = false;
808     }
809     node.SetHDRPresent(isHdrOn);
810     RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
811     if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
812         RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen type failed.");
813         return;
814     }
815 
816     if (screenType == VIRTUAL_TYPE_SCREEN) {
817         if (screenManager->GetPixelFormat(node.GetScreenId(), newPixelFormat_) != SUCCESS) {
818             RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen color gamut failed.");
819         }
820     }
821     stagingDisplayParams->SetNewPixelFormat(newPixelFormat_);
822 }
823 
PrepareDisplayRenderNode(RSDisplayRenderNode & node)824 void RSUniRenderVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode& node)
825 {
826     currentVisitDisplay_ = node.GetScreenId();
827     displayHasSecSurface_.emplace(currentVisitDisplay_, false);
828     displayHasSkipSurface_.emplace(currentVisitDisplay_, false);
829     displayHasProtectedSurface_.emplace(currentVisitDisplay_, false);
830     displaySpecailSurfaceChanged_.emplace(currentVisitDisplay_, false);
831     hasCaptureWindow_.emplace(currentVisitDisplay_, false);
832     node.GetDirtySurfaceNodeMap().clear();
833 
834     RS_TRACE_NAME("RSUniRender:PrepareDisplay " + std::to_string(currentVisitDisplay_));
835     curDisplayDirtyManager_ = node.GetDirtyManager();
836     if (!curDisplayDirtyManager_) {
837         return;
838     }
839     // set 1st elem for display dirty
840     accumulatedDirtyRegions_.emplace_back(RectI());
841     curDisplayDirtyManager_->Clear();
842     curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
843 
844     dirtyFlag_ = isDirty_;
845     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
846     if (!screenManager) {
847         RS_LOGE("RSUniRenderVisitor::PrepareDisplayRenderNode ScreenManager is nullptr");
848         return;
849     }
850     screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
851     prepareClipRect_.SetAll(0, 0, screenInfo_.width, screenInfo_.height);
852     SendRcdMessage(node);
853     parentSurfaceNodeMatrix_ = Drawing::Matrix();
854     auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
855     if (geoPtr != nullptr) {
856         geoPtr->UpdateByMatrixFromSelf();
857         parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
858         if (geoPtr->IsNeedClientCompose()) {
859             isHardwareForcedDisabled_ = true;
860         }
861     }
862     dirtyFlag_ = dirtyFlag_ || node.IsRotationChanged();
863     // when display is in rotation state, occlusion relationship will be ruined,
864     // hence partial-render quick-reject should be disabled.
865     if (node.IsRotationChanged()) {
866         isOpDropped_ = false;
867         RS_TRACE_NAME("ClosePartialRender 1 RotationChanged");
868     }
869     node.UpdateRotation();
870     curAlpha_ = node.GetRenderProperties().GetAlpha();
871     newColorSpace_ = GRAPHIC_COLOR_GAMUT_SRGB;
872     hasFingerprint_ = false;
873     newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_8888;
874     PrepareChildren(node);
875     auto mirrorNode = node.GetMirrorSource().lock();
876     if (mirrorNode) {
877         mirroredDisplays_.insert(mirrorNode->GetScreenId());
878     }
879 
880     node.GetCurAllSurfaces(false).clear();
881     node.GetCurAllSurfaces(true).clear();
882     node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(false), true, false);
883     node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(true), true, true);
884 
885     HandleColorGamuts(node, screenManager);
886     HandlePixelFormat(node, screenManager);
887     RSRcdRenderManager::GetInstance().DoPrepareRenderTask(rcdInfo_->prepareInfo);
888 }
889 
CheckIfSurfaceRenderNodeStatic(RSSurfaceRenderNode & node)890 bool RSUniRenderVisitor::CheckIfSurfaceRenderNodeStatic(RSSurfaceRenderNode& node)
891 {
892     // dirtyFlag_ includes leashWindow dirty
893     // window layout change(e.g. move or zooming) | proxyRenderNode's cmd
894     // temporary cannot deal with leashWindow and scbScreen, restricted to mainwindow
895     if (dirtyFlag_ || node.IsDirty() || !node.IsMainWindowType() || curDisplayNode_ == nullptr) {
896         return false;
897     }
898     if (curDisplayDirtyManager_) {
899         accumulatedDirtyRegions_[0] = curDisplayDirtyManager_->GetCurrentFrameDirtyRegion();
900     }
901     // if node has to be prepared, it's not static
902     bool isClassifyByRootNode = (quickSkipPrepareType_ >= QuickSkipPrepareType::STATIC_APP_INSTANCE);
903     NodeId rootId = node.GetInstanceRootNodeId();
904     if (RSMainThread::Instance()->CheckNodeHasToBePreparedByPid(
905         isClassifyByRootNode ? rootId : node.GetId(), isClassifyByRootNode)) {
906         return false;
907     }
908     // [Attention] node's ability pid could be different but should have same rootId
909     auto abilityNodeIds = node.GetAbilityNodeIds();
910     bool result = isClassifyByRootNode
911         ? RSMainThread::Instance()->CheckNodeHasToBePreparedByPid(rootId, true)
912         : std::any_of(abilityNodeIds.begin(), abilityNodeIds.end(), [&](uint64_t nodeId) {
913             return RSMainThread::Instance()->CheckNodeHasToBePreparedByPid(nodeId, false);
914         });
915     if (result) {
916         return false;
917     }
918     node.UpdateSurfaceCacheContentStatic();
919     RS_OPTIONAL_TRACE_NAME("Skip static surface " + node.GetName() + " nodeid - pid: " +
920         std::to_string(node.GetId()) + " - " + std::to_string(ExtractPid(node.GetId())));
921     // static node's dirty region is empty
922     auto& dirtyManager = node.GetDirtyManager();
923     if (dirtyManager) {
924         dirtyManager->Clear();
925         if (node.IsTransparent()) {
926             dirtyManager->UpdateVisitedDirtyRects(accumulatedDirtyRegions_);
927         }
928         node.UpdateFilterCacheStatusIfNodeStatic(prepareClipRect_, curDisplayNode_->IsRotationChanged());
929     }
930     node.ResetDrawingCacheStatusIfNodeStatic(allCacheFilterRects_);
931     // Attention: curSurface info would be reset as upper surfaceParent if it has
932     ResetCurSurfaceInfoAsUpperSurfaceParent(node);
933     // static surface keeps same position
934     curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), curDisplayNode_->GetLastFrameSurfacePos(node.GetId()));
935     curDisplayNode_->AddSurfaceNodePosByDescZOrder(
936         node.GetId(), curDisplayNode_->GetLastFrameSurfacePos(node.GetId()));
937     return true;
938 }
939 
ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode & node)940 void RSUniRenderVisitor::ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode& node)
941 {
942     // record current frame mainwindow or leashwindow node
943     if (node.IsMainWindowType() || node.IsLeashWindow()) {
944         curMainAndLeashWindowNodesIds_.push(node.GetId());
945         curDisplayNode_->RecordMainAndLeashSurfaces(node.shared_from_this());
946     }
947     // only reset for instance node
948     if (curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetId()) {
949         return;
950     }
951     if (auto directParent = node.GetParent().lock()) {
952         if (auto parentInstance = directParent->GetInstanceRootNode()) {
953             // in case leashwindow is not directParent
954             auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
955             if (surfaceParent && (surfaceParent->IsLeashWindow() || surfaceParent->IsMainWindowType())) {
956                 curSurfaceNode_ = surfaceParent;
957                 curSurfaceDirtyManager_ = surfaceParent->GetDirtyManager();
958                 filterInGlobal_ = surfaceParent->IsTransparent();
959                 return;
960             }
961             curSurfaceNode_ = nullptr;
962             curSurfaceDirtyManager_ = nullptr;
963             filterInGlobal_ = true;
964         }
965     }
966 }
967 
IsHardwareComposerEnabled()968 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
969 {
970     return !isHardwareForcedDisabled_;
971 }
972 
ClearTransparentBeforeSaveLayer()973 void RSUniRenderVisitor::ClearTransparentBeforeSaveLayer()
974 {
975     RS_TRACE_NAME("ClearTransparentBeforeSaveLayer");
976     if (!IsHardwareComposerEnabled()) {
977         return;
978     }
979     for (auto& node : hardwareEnabledNodes_) {
980         if (!node->ShouldPaint()) {
981             continue;
982         }
983         auto dstRect = node->GetDstRect();
984         if (dstRect.IsEmpty()) {
985             continue;
986         }
987         canvas_->Save();
988         canvas_->ClipRect({ static_cast<float>(dstRect.GetLeft()), static_cast<float>(dstRect.GetTop()),
989                               static_cast<float>(dstRect.GetRight()), static_cast<float>(dstRect.GetBottom()) },
990             Drawing::ClipOp::INTERSECT, false);
991         canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
992         canvas_->Restore();
993     }
994 }
995 
MarkSubHardwareEnableNodeState(RSSurfaceRenderNode & surfaceNode)996 void RSUniRenderVisitor::MarkSubHardwareEnableNodeState(RSSurfaceRenderNode& surfaceNode)
997 {
998     if (!IsHardwareComposerEnabled()) {
999         return;
1000     }
1001 
1002     // hardware enabled type case: mark self
1003     if (surfaceNode.IsHardwareEnabledType()) {
1004         surfaceNode.SetHardwareForcedDisabledState(true);
1005         return;
1006     }
1007 
1008     if (!surfaceNode.IsAppWindow() && !surfaceNode.IsAbilityComponent() && !surfaceNode.IsLeashWindow()) {
1009         return;
1010     }
1011 
1012     // ability component type case: check pid
1013     if (surfaceNode.IsAbilityComponent()) {
1014         pid_t pid = ExtractPid(surfaceNode.GetId());
1015         for (auto& childNode : hardwareEnabledNodes_) {
1016             pid_t childPid = ExtractPid(childNode->GetId());
1017             if (pid == childPid) {
1018                 childNode->SetHardwareForcedDisabledState(true);
1019             }
1020         }
1021         return;
1022     }
1023     std::vector<std::weak_ptr<RSSurfaceRenderNode>> hardwareEnabledNodes;
1024     if (surfaceNode.IsAppWindow()) {
1025         hardwareEnabledNodes = surfaceNode.GetChildHardwareEnabledNodes();
1026     } else {
1027         for (auto& child : *surfaceNode.GetChildren()) {
1028             auto appNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1029             if (appNode && appNode->IsAppWindow()) {
1030                 hardwareEnabledNodes = appNode->GetChildHardwareEnabledNodes();
1031                 break;
1032             }
1033         }
1034     }
1035     // app window type case: mark all child hardware enabled nodes
1036     for (auto& node : hardwareEnabledNodes) {
1037         auto childNode = node.lock();
1038         if (childNode) {
1039             childNode->SetHardwareForcedDisabledState(true);
1040         }
1041     }
1042 }
1043 
CollectAppNodeForHwc(std::shared_ptr<RSSurfaceRenderNode> surfaceNode)1044 void RSUniRenderVisitor::CollectAppNodeForHwc(std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
1045 {
1046     if (!IsHardwareComposerEnabled() || !surfaceNode || surfaceNode->GetChildHardwareEnabledNodes().empty()) {
1047         return;
1048     }
1049     if (surfaceNode->IsHardwareEnabledTopSurface()) {
1050         hardwareEnabledTopNodes_.emplace_back(surfaceNode);
1051     } else {
1052         appWindowNodesInZOrder_.emplace_back(surfaceNode);
1053     }
1054 }
1055 
PrepareTypesOfSurfaceRenderNodeBeforeUpdate(RSSurfaceRenderNode & node)1056 void RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeBeforeUpdate(RSSurfaceRenderNode& node)
1057 {
1058     // if current surfacenode is a main window type, reset the curSurfaceDirtyManager
1059     // reset leash window's dirtyManager pointer to avoid curSurfaceDirtyManager mis-pointing
1060     if (node.IsLeashOrMainWindow()) {
1061         node.SetFilterCacheFullyCovered(false);
1062         node.ResetFilterNodes();
1063         // [planning] check if it is not reset recursively
1064         firstVisitedCache_ = INVALID_NODEID;
1065         curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1066         RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1067         curSurfaceDirtyManager_ = node.GetDirtyManager();
1068         if (curSurfaceDirtyManager_ == nullptr) {
1069             RS_LOGE("RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeBeforeUpdate %{public}s has no"
1070                 " SurfaceDirtyManager", node.GetName().c_str());
1071             return;
1072         }
1073         curSurfaceDirtyManager_->Clear();
1074         if (node.IsTransparent()) {
1075             curSurfaceDirtyManager_->UpdateVisitedDirtyRects(accumulatedDirtyRegions_);
1076         }
1077         curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1078         if (isTargetDirtyRegionDfxEnabled_ && CheckIfSurfaceTargetedForDFX(node.GetName())) {
1079             curSurfaceDirtyManager_->MarkAsTargetForDfx();
1080         }
1081         ClassifyUIFirstSurfaceDirtyStatus(node);
1082     }
1083 
1084     // collect app window node's child hardware enabled node
1085     if (node.IsHardwareEnabledType() && curSurfaceNode_) {
1086         curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
1087         node.SetLocalZOrder(localZOrder_++);
1088     }
1089 }
1090 
ClassifyUIFirstSurfaceDirtyStatus(RSSurfaceRenderNode & node)1091 void RSUniRenderVisitor::ClassifyUIFirstSurfaceDirtyStatus(RSSurfaceRenderNode& node)
1092 {
1093     if (node.IsMainWindowType()) {
1094         isCachedSurfaceReuse_ = (quickSkipPrepareType_ >= QuickSkipPrepareType::STATIC_CACHE_SURFACE) &&
1095             (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) &&
1096             CheckIfUIFirstSurfaceContentReusable(curSurfaceNode_, isSurfaceDirtyNodeLimited_);
1097         // The condition of childHasVisibleFilter in QuerySubAssignable can not be used here
1098         // Because child node's filter is not collected yet, so disable prepare optimization when node is transparent
1099         // [planning]: detect the filter change before prepare, and use the last frame result
1100         isSurfaceDirtyNodeLimited_ = (quickSkipPrepareType_ == QuickSkipPrepareType::CONTENT_DIRTY_CACHE_SURFACE) &&
1101             !node.IsTransparent() && isSurfaceDirtyNodeLimited_ &&
1102             node.IsOnlyBasicGeoTransform() && node.IsContentDirtyNodeLimited();
1103         if (isCachedSurfaceReuse_) {
1104             node.SetGeoUpdateDelay(dirtyFlag_);
1105         }
1106     }
1107 }
1108 
CheckIfUIFirstSurfaceContentReusable(std::shared_ptr<RSSurfaceRenderNode> & node,bool & isAssigned)1109 bool RSUniRenderVisitor::CheckIfUIFirstSurfaceContentReusable(std::shared_ptr<RSSurfaceRenderNode>& node,
1110     bool& isAssigned)
1111 {
1112     if (!isUIFirst_ || node == nullptr) {
1113         return false;
1114     }
1115     auto deviceType = RSMainThread::Instance()->GetDeviceType();
1116     if (auto directParent = node->GetParent().lock()) {
1117         if (auto parentInstance = directParent->GetInstanceRootNode()) {
1118             auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
1119             if (surfaceParent && surfaceParent->IsLeashWindow()) {
1120                 isAssigned =
1121                     RSUniRenderUtil::IsNodeAssignSubThread(surfaceParent, curDisplayNode_->IsRotationChanged());
1122                 RS_OPTIONAL_TRACE_NAME_FMT("%s CheckIfUIFirstSurfaceContentReusable(leash): %d, isAssigned %d",
1123                     surfaceParent->GetName().c_str(), surfaceParent->IsUIFirstCacheReusable(deviceType), isAssigned);
1124                 return isAssigned && surfaceParent->IsUIFirstCacheReusable(deviceType);
1125             }
1126         }
1127     }
1128     isAssigned = RSUniRenderUtil::IsNodeAssignSubThread(node, curDisplayNode_->IsRotationChanged());
1129     RS_OPTIONAL_TRACE_NAME_FMT("%s CheckIfUIFirstSurfaceContentReusable(mainwindow): %d, isAssigned %d",
1130         node->GetName().c_str(), node->IsUIFirstCacheReusable(deviceType), isAssigned);
1131     return isAssigned && node->IsUIFirstCacheReusable(deviceType);
1132 }
1133 
PrepareTypesOfSurfaceRenderNodeAfterUpdate(RSSurfaceRenderNode & node)1134 void RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeAfterUpdate(RSSurfaceRenderNode& node)
1135 {
1136     if (!curSurfaceDirtyManager_) {
1137         return;
1138     }
1139     const auto& properties = node.GetRenderProperties();
1140     if (properties.NeedFilter()) {
1141         UpdateForegroundFilterCacheWithDirty(node, *curSurfaceDirtyManager_);
1142         if (auto parentNode = node.GetParent().lock()) {
1143             parentNode->SetChildHasVisibleFilter(true);
1144         }
1145         if (curSurfaceNode_) {
1146             curSurfaceNode_->UpdateFilterNodes(node.shared_from_this());
1147         }
1148     }
1149     if (node.IsLeashWindow()) {
1150         auto children = node.GetSortedChildren();
1151         for (auto& child : *children) {
1152             if (child->ChildHasVisibleFilter()) {
1153                 node.SetChildHasVisibleFilter(true);
1154                 break;
1155             }
1156         }
1157     } else if (node.IsMainWindowType()) {
1158         isCachedSurfaceReuse_ = false;
1159         isSurfaceDirtyNodeLimited_ = false;
1160         bool hasFilter = node.IsTransparent() && properties.NeedFilter();
1161         bool hasHardwareNode = !node.GetChildHardwareEnabledNodes().empty();
1162         bool hasAbilityComponent = !node.GetAbilityNodeIds().empty();
1163         auto rsParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1164         if (rsParent && rsParent->IsLeashWindow()) {
1165             rsParent->SetHasFilter(hasFilter);
1166             rsParent->SetHasHardwareNode(hasHardwareNode);
1167             rsParent->SetHasAbilityComponent(hasAbilityComponent);
1168             // [uifirst] leashWindow add or clear abilityNodeId for checking subthread node status
1169             if (hasAbilityComponent) {
1170                 rsParent->AddAbilityComponentNodeIds(node.GetAbilityNodeIds());
1171             } else {
1172                 rsParent->ResetAbilityNodeIds();
1173             }
1174         } else {
1175             node.SetHasFilter(hasFilter);
1176             node.SetHasHardwareNode(hasHardwareNode);
1177             node.SetHasAbilityComponent(hasAbilityComponent);
1178         }
1179         if (node.IsTransparent() &&
1180             curSurfaceDirtyManager_->IfCacheableFilterRectFullyCover(node.GetOldDirtyInSurface())) {
1181             node.SetFilterCacheFullyCovered(true);
1182             RS_LOGD("SetFilterCacheFullyCovered surfacenode %{public}" PRIu64 " [%{public}s]",
1183                 node.GetId(), node.GetName().c_str());
1184         }
1185         node.CalcFilterCacheValidForOcclusion();
1186         RS_OPTIONAL_TRACE_NAME(node.GetName() + " PreparedNodes: " +
1187             std::to_string(preparedCanvasNodeInCurrentSurface_));
1188         preparedCanvasNodeInCurrentSurface_ = 0;
1189     }
1190     // accumulate all visited dirty rects including leash window's shadow dirty
1191     if (node.IsLeashOrMainWindow() && curSurfaceDirtyManager_->IsCurrentFrameDirty()) {
1192         accumulatedDirtyRegions_.emplace_back(curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion());
1193     }
1194 }
1195 
UpdateSecuritySkipAndProtectedLayersRecord(RSSurfaceRenderNode & node)1196 void RSUniRenderVisitor::UpdateSecuritySkipAndProtectedLayersRecord(RSSurfaceRenderNode& node)
1197 {
1198     if (node.GetHasSecurityLayer()) {
1199         displayHasSecSurface_[currentVisitDisplay_] = true;
1200         curDisplayNode_->AddSecurityLayer(node.IsLeashWindow() ? node.GetLeashPersistentId() : node.GetId());
1201     }
1202     if (node.GetHasSkipLayer() && node.GetName().find(CAPTURE_WINDOW_NAME) == std::string::npos) {
1203         displayHasSkipSurface_[currentVisitDisplay_] = true;
1204     }
1205     if (node.GetHasProtectedLayer()) {
1206         displayHasProtectedSurface_[currentVisitDisplay_] = true;
1207     }
1208     if (node.IsSpecialLayerChanged()) {
1209         displaySpecailSurfaceChanged_[currentVisitDisplay_] = true;
1210     }
1211 }
1212 
UpdateForegroundFilterCacheWithDirty(RSRenderNode & node,RSDirtyRegionManager & dirtyManager,bool isForeground)1213 void RSUniRenderVisitor::UpdateForegroundFilterCacheWithDirty(RSRenderNode& node,
1214     RSDirtyRegionManager& dirtyManager, bool isForeground)
1215 {
1216     node.UpdateFilterCacheWithBelowDirty(dirtyManager, isForeground);
1217     node.UpdateFilterCacheWithSelfDirty();
1218 }
1219 
UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode & node)1220 void RSUniRenderVisitor::UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode& node)
1221 {
1222     if (!node.IsMainWindowType()) {
1223         return;
1224     }
1225     auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
1226     if (!geoPtr) {
1227         return;
1228     }
1229     if (RSUniRenderUtil::GetRotationDegreeFromMatrix(geoPtr->GetAbsMatrix()) % RS_ROTATION_90 != 0) {
1230         node.SetIsRotating(true);
1231     }
1232 }
1233 
IsSubTreeOccluded(RSRenderNode & node) const1234 bool RSUniRenderVisitor::IsSubTreeOccluded(RSRenderNode& node) const
1235 {
1236     if (!isOcclusionEnabled_) {
1237         return false;
1238     }
1239     // step1. apply occlusion info for surfacenode and skip fully covered subtree
1240     if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
1241         auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1242         if (surfaceNode.IsMainWindowType()) {
1243             RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::IsSubTreeOccluded node[%s]"
1244                 "name:[%s] visibleRegionIsEmpty[%d]",
1245                 std::to_string(node.GetId()).c_str(), surfaceNode.GetName().c_str(),
1246                 surfaceNode.GetVisibleRegion().IsEmpty());
1247             auto isOccluded = hasMirrorDisplay_ ?
1248                 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
1249             if (isOccluded && curSurfaceDirtyManager_) {
1250                 curSurfaceDirtyManager_->Clear();
1251             }
1252             surfaceNode.AccmulateDirtyInOcclusion(isOccluded);
1253             return isOccluded;
1254         }
1255     }
1256     // step2.1 For partial visible surface, intersected region->rects in surface
1257     // step2.2 check if clean subtree in occlusion rects
1258     return false;
1259 }
1260 
ResetDisplayDirtyRegion()1261 void RSUniRenderVisitor::ResetDisplayDirtyRegion()
1262 {
1263     if (!curDisplayDirtyManager_) {
1264         return;
1265     }
1266     bool isNeedNotchUpdate = RSSingleton<RoundCornerDisplay>::GetInstance().IsNotchNeedUpdate(
1267         RSSystemParameters::GetHideNotchStatus());
1268     bool ret = CheckScreenPowerChange() ||
1269         CheckColorFilterChange() ||
1270         CheckCurtainScreenUsingStatusChange() ||
1271         IsFirstFrameOfPartialRender() ||
1272         IsWatermarkFlagChanged() ||
1273         zoomStateChange_ ||
1274         isCompleteRenderEnabled_ ||
1275         CheckLuminanceStatusChange() ||
1276         IsFirstFrameOfOverdrawSwitch() ||
1277         isNeedNotchUpdate;
1278     if (ret) {
1279         curDisplayDirtyManager_->ResetDirtyAsSurfaceSize();
1280         RS_LOGD("RSUniRenderVisitor::ResetDisplayDirtyRegion on");
1281     }
1282 }
1283 
CheckScreenPowerChange() const1284 bool RSUniRenderVisitor::CheckScreenPowerChange() const
1285 {
1286     if (!RSMainThread::Instance()->GetScreenPowerOnChanged()) {
1287         return false;
1288     }
1289     RS_LOGD("RSUniRenderVisitor::CheckScreenPowerChange changed");
1290     return true;
1291 }
1292 
CheckCurtainScreenUsingStatusChange() const1293 bool RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange() const
1294 {
1295     if (!RSMainThread::Instance()->IsCurtainScreenUsingStatusChanged()) {
1296         return false;
1297     }
1298     RS_LOGD("RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange changed");
1299     return true;
1300 }
1301 
CheckLuminanceStatusChange()1302 bool RSUniRenderVisitor::CheckLuminanceStatusChange()
1303 {
1304     if (!RSMainThread::Instance()->ExchangeLuminanceChangingStatus()) {
1305         return false;
1306     }
1307     RS_LOGD("RSUniRenderVisitor::CheckLuminanceStatusChange changed");
1308     return true;
1309 }
1310 
IsFirstFrameOfPartialRender() const1311 bool RSUniRenderVisitor::IsFirstFrameOfPartialRender() const
1312 {
1313     if (!RSMainThread::Instance()->IsFirstFrameOfPartialRender()) {
1314         return false;
1315     }
1316     RS_LOGD("FirstFrameOfPartialRender");
1317     return true;
1318 }
1319 
IsFirstFrameOfOverdrawSwitch() const1320 bool RSUniRenderVisitor::IsFirstFrameOfOverdrawSwitch() const
1321 {
1322     if (!RSMainThread::Instance()->IsFirstFrameOfOverdrawSwitch()) {
1323         return false;
1324     }
1325     RS_LOGD("IsFirstFrameOfOverdrawSwitch");
1326     return true;
1327 }
1328 
IsWatermarkFlagChanged() const1329 bool RSUniRenderVisitor::IsWatermarkFlagChanged() const
1330 {
1331     if (RSMainThread::Instance()->IsWatermarkFlagChanged()) {
1332         RS_LOGD("FirstOrLastFrameOfWatermark");
1333         return true;
1334     } else {
1335         return false;
1336     }
1337 }
1338 
UpdateDisplayZoomState()1339 void RSUniRenderVisitor::UpdateDisplayZoomState()
1340 {
1341     if (!curDisplayNode_) {
1342         return;
1343     }
1344     auto scale = curDisplayNode_->GetRenderProperties().GetScale();
1345     bool curZoomState = scale.x_ > 1.f || scale.y_ > 1.f;
1346     curDisplayNode_->UpdateZoomState(curZoomState);
1347     zoomStateChange_ = curZoomState || curDisplayNode_->IsZoomStateChange();
1348 }
1349 
UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode & node)1350 void RSUniRenderVisitor::UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode& node)
1351 {
1352     // only for virtual screen
1353     if (!(node.IsMirrorDisplay())) {
1354         return;
1355     }
1356     auto mirrorNode = node.GetMirrorSource().lock();
1357     if (mirrorNode == nullptr || screenManager_ == nullptr) {
1358         return;
1359     }
1360     auto securityExemptionList = screenManager_->GetVirtualScreenSecurityExemptionList(node.GetScreenId());
1361     if (securityExemptionList.size() == 0) {
1362         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:false",
1363             node.GetId());
1364         node.SetSecurityExemption(false);
1365         mirrorNode->ClearSecurityLayerList();
1366         return;
1367     }
1368     auto securityLayerList = mirrorNode->GetSecurityLayerList();
1369     for (const auto& exemptionLayer : securityExemptionList) {
1370         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
1371             "securityExemption nodeId %{public}" PRIu64 ".", node.GetId(), exemptionLayer);
1372     }
1373     for (const auto& secLayer : securityLayerList) {
1374         RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
1375             "securityLayer nodeId %{public}" PRIu64 ".", mirrorNode->GetId(), secLayer);
1376     }
1377     bool isSecurityExemption = false;
1378     if (securityExemptionList.size() >= securityLayerList.size()) {
1379         isSecurityExemption = true;
1380         for (const auto& secLayer : securityLayerList) {
1381             if (std::find(securityExemptionList.begin(), securityExemptionList.end(), secLayer) ==
1382                 securityExemptionList.end()) {
1383                 isSecurityExemption = false;
1384                 break;
1385             }
1386         }
1387     }
1388     RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:%{public}d",
1389         node.GetId(), isSecurityExemption);
1390     node.SetSecurityExemption(isSecurityExemption);
1391     mirrorNode->ClearSecurityLayerList();
1392 }
1393 
QuickPrepareDisplayRenderNode(RSDisplayRenderNode & node)1394 void RSUniRenderVisitor::QuickPrepareDisplayRenderNode(RSDisplayRenderNode& node)
1395 {
1396     // 0. init display info
1397     RS_TRACE_NAME("RSUniRender:QuickPrepareDisplayRenderNode " + std::to_string(node.GetScreenId()));
1398     if (!InitDisplayInfo(node)) {
1399         return;
1400     }
1401     UpdateDisplayZoomState();
1402     SendRcdMessage(node);
1403     UpdateVirtualScreenSecurityExemption(node);
1404     ancestorNodeHasAnimation_ = false;
1405     displayNodeRotationChanged_ = node.IsRotationChanged();
1406     dirtyFlag_ = isDirty_ || displayNodeRotationChanged_ || zoomStateChange_;
1407     prepareClipRect_ = screenRect_;
1408     hasAccumulatedClip_ = false;
1409 
1410     curAlpha_ = 1.0f;
1411     globalZOrder_ = 0.0f;
1412     hasSkipLayer_ = false;
1413     node.UpdateRotation();
1414     if (!(RSMainThread::Instance()->IsRequestedNextVSync() || RSMainThread::Instance()->GetNextDVsyncAnimateFlag())) {
1415         RS_OPTIONAL_TRACE_NAME_FMT("do not request next vsync");
1416         needRequestNextVsync_ = false;
1417     }
1418     RSUifirstManager::Instance().SetRotationChanged(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1419     if (node.IsSubTreeDirty() || node.IsRotationChanged()) {
1420         QuickPrepareChildren(node);
1421     }
1422     PostPrepare(node);
1423     UpdateHwcNodeEnable();
1424     UpdateSurfaceDirtyAndGlobalDirty();
1425     UpdateSurfaceOcclusionInfo();
1426     if (needRecalculateOcclusion_) {
1427         // Callback for registered self drawing surfacenode
1428         RSMainThread::Instance()->SurfaceOcclusionCallback();
1429     }
1430     //UIFirst layer must be above displayNode, so use zorder + 1
1431     RSUifirstManager::Instance().UpdateUIFirstLayerInfo(screenInfo_, globalZOrder_ + 1);
1432     curDisplayNode_->UpdatePartialRenderParams();
1433     RSDisplayRenderNode::ScreenRenderParams screenRenderParams;
1434     screenRenderParams.screenInfo = std::move(screenInfo_);
1435     screenRenderParams.displayHasSecSurface = std::move(displayHasSecSurface_);
1436     screenRenderParams.displayHasSkipSurface = std::move(displayHasSkipSurface_);
1437     screenRenderParams.displayHasProtectedSurface = std::move(displayHasProtectedSurface_);
1438     screenRenderParams.displaySpecailSurfaceChanged = std::move(displaySpecailSurfaceChanged_);
1439     screenRenderParams.hasCaptureWindow = std::move(hasCaptureWindow_);
1440     curDisplayNode_->UpdateScreenRenderParams(screenRenderParams);
1441     curDisplayNode_->UpdateOffscreenRenderParams(curDisplayNode_->IsRotationChanged());
1442     UpdateColorSpaceAfterHwcCalc(node);
1443     HandleColorGamuts(node, screenManager_);
1444     HandlePixelFormat(node, screenManager_);
1445     if (UNLIKELY(!SharedTransitionParam::unpairedShareTransitions_.empty())) {
1446         ProcessUnpairedSharedTransitionNode();
1447     }
1448     node.RenderTraceDebug();
1449 }
1450 
CheckFilterCacheNeedForceClearOrSave(RSRenderNode & node)1451 void RSUniRenderVisitor::CheckFilterCacheNeedForceClearOrSave(RSRenderNode& node)
1452 {
1453     if (!node.HasBlurFilter()) {
1454         return;
1455     }
1456     bool rotationChanged = curDisplayNode_ ?
1457         curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
1458     bool rotationStatusChanged = curDisplayNode_ ?
1459         curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
1460     node.CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
1461 }
1462 
1463 // private method, curDisplayNode_ or curSurfaceNode_ will not be nullptr
CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet & filterSet,bool isGlobalDirty)1464 void RSUniRenderVisitor::CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet& filterSet, bool isGlobalDirty)
1465 {
1466     // Recursively traverses until the globalDirty do not change
1467     auto dirtyManager = isGlobalDirty ? curDisplayNode_->GetDirtyManager() : curSurfaceNode_->GetDirtyManager();
1468     if (dirtyManager == nullptr) {
1469         return;
1470     }
1471     for (auto it = filterSet.begin(); it != filterSet.end();) {
1472         auto dirtyRect = dirtyManager->GetCurrentFrameDirtyRegion();
1473         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
1474         auto dirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
1475         auto filterDirtyRegion = filterRegion.And(dirtyRegion);
1476         if (!filterDirtyRegion.IsEmpty()) {
1477             if (isGlobalDirty) {
1478                 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
1479                     "global dirty %{public}s, add filterRegion %{public}s",
1480                     dirtyRect.ToString().c_str(), (it->second).ToString().c_str());
1481             }
1482             dirtyManager->MergeDirtyRect(it->second);
1483             it = filterSet.erase(it);
1484             if (dirtyRect != dirtyManager->GetCurrentFrameDirtyRegion()) {
1485                 // When dirtyRegion is changed, collect dirty filter region from begin.
1486                 // After all filter region is added, the cycle will definitely stop.
1487                 it = filterSet.begin();
1488             }
1489         } else {
1490             ++it;
1491         }
1492     }
1493     filterSet.clear();
1494 }
1495 
QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode & node)1496 void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
1497 {
1498     RS_OPTIONAL_TRACE_NAME_FMT("RSUniRender::QuickPrepare:[%s] nodeId[%" PRIu64 "]"
1499         "pid[%d] nodeType[%u] subTreeDirty[%d]", node.GetName().c_str(), node.GetId(), ExtractPid(node.GetId()),
1500         static_cast<uint>(node.GetSurfaceNodeType()), node.IsSubTreeDirty());
1501     RS_LOGD("RSUniRender::QuickPrepareSurfaceRenderNode:[%{public}s] nodeid:[%{public}" PRIu64 "]"
1502         "pid:[%{public}d] nodeType:[%{public}d] subTreeDirty[%{public}d]", node.GetName().c_str(), node.GetId(),
1503         ExtractPid(node.GetId()), static_cast<int>(node.GetSurfaceNodeType()), node.IsSubTreeDirty());
1504 
1505     // 0. init curSurface info and check node info
1506     auto curCornerRadius = curCornerRadius_;
1507     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
1508     if (!BeforeUpdateSurfaceDirtyCalc(node)) {
1509         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode BeforeUpdateSurfaceDirtyCalc fail");
1510         RSUifirstManager::Instance().DisableUifirstNode(node);
1511         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1512         return;
1513     }
1514 
1515     if (curSurfaceDirtyManager_ == nullptr) {
1516         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
1517             node.GetName().c_str());
1518         return;
1519     }
1520 
1521     // 1. Update matrix and collect dirty region
1522     auto dirtyFlag = dirtyFlag_;
1523     auto prepareClipRect = prepareClipRect_;
1524     bool hasAccumulatedClip = hasAccumulatedClip_;
1525     auto prevAlpha = curAlpha_;
1526     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1527     node.SetGlobalAlpha(curAlpha_);
1528     CheckFilterCacheNeedForceClearOrSave(node);
1529     node.CheckContainerDirtyStatusAndUpdateDirty(curContainerDirty_);
1530     dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
1531         *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix);
1532     auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
1533     if (!geoPtr) {
1534         return;
1535     }
1536     parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
1537     if (!AfterUpdateSurfaceDirtyCalc(node)) {
1538         RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode AfterUpdateSurfaceDirtyCalc fail");
1539         RSUifirstManager::Instance().DisableUifirstNode(node);
1540         node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1541         return;
1542     }
1543     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1544     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_, IsSubTreeOccluded(node)) ||
1545         ForcePrepareSubTree();
1546     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1547         node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
1548 
1549     // Update whether leash window's visible region is empty after prepare children
1550     UpdateLeashWindowVisibleRegionEmpty(node);
1551 
1552     if (node.IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()) {
1553         CheckIsGpuOverDrawBufferOptimizeNode(node);
1554     }
1555     PostPrepare(node, !isSubTreeNeedPrepare);
1556     CheckMergeFilterDirtyByIntersectWithDirty(curSurfaceNoBelowDirtyFilter_, false);
1557     curAlpha_ = prevAlpha;
1558     prepareClipRect_ = prepareClipRect;
1559     hasAccumulatedClip_ = hasAccumulatedClip;
1560     dirtyFlag_ = dirtyFlag;
1561 
1562     PrepareForUIFirstNode(node);
1563     node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1564     ResetCurSurfaceInfoAsUpperSurfaceParent(node);
1565     curCornerRadius_ = curCornerRadius;
1566     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
1567     node.RenderTraceDebug();
1568     node.SetNeedOffscreen(isScreenRotationAnimating_);
1569 }
1570 
PrepareForUIFirstNode(RSSurfaceRenderNode & node)1571 void RSUniRenderVisitor::PrepareForUIFirstNode(RSSurfaceRenderNode& node)
1572 {
1573     MultiThreadCacheType lastFlag = node.GetLastFrameUifirstFlag();
1574     RSUifirstManager::Instance().UpdateUifirstNodes(node, ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation());
1575     RSUifirstManager::Instance().UpdateUIFirstNodeUseDma(node, globalSurfaceBounds_);
1576     if (node.GetLastFrameUifirstFlag() == MultiThreadCacheType::LEASH_WINDOW &&
1577         !node.IsHardwareForcedDisabled()) {
1578         if (auto& geo = node.GetRenderProperties().GetBoundsGeometry()) {
1579             UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
1580         }
1581         UpdateHwcNodeByTransform(node);
1582     }
1583     if (RSUifirstManager::Instance().GetUseDmaBuffer(node.GetName()) && curSurfaceDirtyManager_ &&
1584         (node.GetLastFrameUifirstFlag() != lastFlag ||
1585         !node.IsHardwareForcedDisabled() != node.GetIsLastFrameHwcEnabled())) {
1586         curSurfaceDirtyManager_->MergeDirtyRect(node.GetOldDirty());
1587     }
1588 }
1589 
UpdateNodeVisibleRegion(RSSurfaceRenderNode & node)1590 void RSUniRenderVisitor::UpdateNodeVisibleRegion(RSSurfaceRenderNode& node)
1591 {
1592     Occlusion::Rect selfDrawRect = node.GetSurfaceOcclusionRect(true);
1593     Occlusion::Region selfDrawRegion { selfDrawRect };
1594     if (needRecalculateOcclusion_) {
1595         Occlusion::Region subResult = selfDrawRegion.Sub(accumulatedOcclusionRegion_);
1596         node.SetVisibleRegion(subResult);
1597         Occlusion::Region subResultWithoutSkipLayer = selfDrawRegion.Sub(occlusionRegionWithoutSkipLayer_);
1598         node.SetVisibleRegionInVirtual(subResultWithoutSkipLayer);
1599     }
1600     RS_OPTIONAL_TRACE_NAME_FMT_LEVEL(TRACE_LEVEL_THREE,
1601         "RSUniRenderVisitor::UpdateNodeVisibleRegion name[%s] visibleRegion[%s]",
1602         node.GetName().c_str(), node.GetVisibleRegion().GetRegionInfo().c_str());
1603 }
1604 
CalculateOcclusion(RSSurfaceRenderNode & node)1605 void RSUniRenderVisitor::CalculateOcclusion(RSSurfaceRenderNode& node)
1606 {
1607     if (!curDisplayNode_) {
1608         RS_LOGE("RSUniRenderVisitor::CalculateOcclusion curDisplayNode is nullptr");
1609         return;
1610     }
1611     // CheckAndUpdateOpaqueRegion only in mainWindow
1612     auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1613     auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
1614         (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
1615     node.CheckAndUpdateOpaqueRegion(screenRect_, curDisplayNode_->GetRotation(), isFocused);
1616     if (!needRecalculateOcclusion_) {
1617         needRecalculateOcclusion_ = node.CheckIfOcclusionChanged();
1618     }
1619     // Update node visibleRegion
1620     hasSkipLayer_ = hasSkipLayer_ || node.GetSkipLayer();
1621     UpdateNodeVisibleRegion(node);
1622     auto mainThread = RSMainThread::Instance();
1623     node.SetOcclusionInSpecificScenes(mainThread->GetDeviceType() == DeviceType::PC &&
1624         mainThread->IsPCThreeFingerScenesListScene());
1625     // check current surface Participate In Occlusion
1626     if (node.CheckParticipateInOcclusion() && !isAllSurfaceVisibleDebugEnabled_) {
1627         accumulatedOcclusionRegion_.OrSelf(node.GetOpaqueRegion());
1628         std::unordered_set<NodeId> currentBlackList = GetCurrentBlackList();
1629         if (IsValidInVirtualScreen(node) && currentBlackList.find(node.GetId()) == currentBlackList.end()) {
1630             occlusionRegionWithoutSkipLayer_.OrSelf(node.GetOpaqueRegion());
1631         }
1632     }
1633     node.SetOcclusionInSpecificScenes(false);
1634     CollectOcclusionInfoForWMS(node);
1635 }
1636 
CollectOcclusionInfoForWMS(RSSurfaceRenderNode & node)1637 void RSUniRenderVisitor::CollectOcclusionInfoForWMS(RSSurfaceRenderNode& node)
1638 {
1639     if (!node.IsMainWindowType()) {
1640         return;
1641     }
1642     // collect mainWindow occlusion visibleLevel
1643     Occlusion::Region selfDrawRegion { node.GetSurfaceOcclusionRect(true) };
1644     auto visibleLevel = GetRegionVisibleLevel(node.GetVisibleRegion(), selfDrawRegion);
1645     // wms default all visible about sefdrawing node and AbilityComponent node
1646     auto instanceNode = node.GetInstanceRootNode() ?
1647         node.GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1648     if (instanceNode == nullptr) {
1649         return;
1650     }
1651     if ((node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
1652         !instanceNode->GetVisibleRegion().IsEmpty()) || node.IsAbilityComponent()) {
1653         dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1654             WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1655         return;
1656     }
1657     dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1658         node.GetVisibleLevelForWMS(visibleLevel)));
1659 }
1660 
SurfaceOcclusionCallbackToWMS()1661 void RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS()
1662 {
1663     if (RSSystemParameters::GetOcclusionCallBackToWMSDebugType()) {
1664         allDstCurVisVec_.clear();
1665         const auto& curAllSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1666         for (const auto& surfacePtr : curAllSurfaces) {
1667             if (surfacePtr == nullptr) {
1668                 continue;
1669             }
1670             const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*surfacePtr);
1671             if (surfaceNode.IsMainWindowType()) {
1672                 allDstCurVisVec_.emplace_back(std::make_pair(surfacePtr->GetId(),
1673                     WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1674             }
1675         }
1676     }
1677     if (allDstCurVisVec_ != allLastVisVec_) {
1678         RSMainThread::Instance()->SurfaceOcclusionChangeCallback(allDstCurVisVec_);
1679         RS_LOGI("RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS %{public}s",
1680             VisibleDataToString(allDstCurVisVec_).c_str());
1681         allLastVisVec_ = std::move(allDstCurVisVec_);
1682     }
1683 }
1684 
GetCurrentBlackList() const1685 std::unordered_set<NodeId> RSUniRenderVisitor::GetCurrentBlackList() const
1686 {
1687     if (!screenManager_ || !curDisplayNode_) {
1688         return std::unordered_set<NodeId>();
1689     }
1690 
1691     std::unordered_set<NodeId> currentBlackList;
1692     if (screenManager_->GetCastScreenEnableSkipWindow(curDisplayNode_->GetScreenId())) {
1693         screenManager_->GetCastScreenBlackList(currentBlackList);
1694     } else {
1695         currentBlackList = screenManager_->GetVirtualScreenBlackList(curDisplayNode_->GetScreenId());
1696     }
1697     return currentBlackList;
1698 }
1699 
GetRegionVisibleLevel(const Occlusion::Region & visibleRegion,const Occlusion::Region & selfDrawRegion)1700 RSVisibleLevel RSUniRenderVisitor::GetRegionVisibleLevel(const Occlusion::Region& visibleRegion,
1701     const Occlusion::Region& selfDrawRegion)
1702 {
1703     if (visibleRegion.IsEmpty()) {
1704         return RSVisibleLevel::RS_INVISIBLE;
1705     } else if (visibleRegion.Area() == selfDrawRegion.Area()) {
1706         return RSVisibleLevel::RS_ALL_VISIBLE;
1707     } else if (static_cast<uint>(visibleRegion.Area()) <
1708         (static_cast<uint>(selfDrawRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
1709         return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
1710     }
1711     return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
1712 }
1713 
QuickPrepareEffectRenderNode(RSEffectRenderNode & node)1714 void RSUniRenderVisitor::QuickPrepareEffectRenderNode(RSEffectRenderNode& node)
1715 {
1716     // 0. check current node need to tranverse
1717     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
1718     if (!dirtyManager) {
1719         RS_LOGE("RSUniRenderVisitor::QuickPrepareEffectRenderNode dirtyManager is nullptr");
1720         return;
1721     }
1722     auto dirtyFlag = dirtyFlag_;
1723     auto prevAlpha = curAlpha_;
1724     auto curCornerRadius = curCornerRadius_;
1725     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1726     UpdateRotationStatusForEffectNode(node);
1727     CheckFilterCacheNeedForceClearOrSave(node);
1728     RectI prepareClipRect = prepareClipRect_;
1729     bool hasAccumulatedClip = hasAccumulatedClip_;
1730     dirtyFlag_ =
1731         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1732     node.UpdateCurCornerRadius(curCornerRadius_);
1733     // 1. Recursively traverse child nodes
1734     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1735     bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
1736     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1737         node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1738 
1739     PostPrepare(node, !isSubTreeNeedPrepare);
1740     prepareClipRect_ = prepareClipRect;
1741     hasAccumulatedClip_ = hasAccumulatedClip;
1742     dirtyFlag_ = dirtyFlag;
1743     curAlpha_ = prevAlpha;
1744     curCornerRadius_ = curCornerRadius;
1745     node.RenderTraceDebug();
1746 }
1747 
QuickPrepareCanvasRenderNode(RSCanvasRenderNode & node)1748 void RSUniRenderVisitor::QuickPrepareCanvasRenderNode(RSCanvasRenderNode& node)
1749 {
1750     // 0. check current node need to traverse
1751     auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
1752     auto dirtyFlag = dirtyFlag_;
1753     auto prevAlpha = curAlpha_;
1754     auto curCornerRadius = curCornerRadius_;
1755     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1756     CheckFilterCacheNeedForceClearOrSave(node);
1757     if (isDrawingCacheEnabled_) {
1758         node.UpdateDrawingCacheInfoBeforeChildren(isScreenRotationAnimating_);
1759     }
1760     node.OpincQuickMarkStableNode(unchangeMarkInApp_, unchangeMarkEnable_);
1761 
1762     RectI prepareClipRect = prepareClipRect_;
1763     bool hasAccumulatedClip = hasAccumulatedClip_;
1764 
1765     if (!dirtyManager) {
1766         return;
1767     }
1768     dirtyFlag_ =
1769         node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1770     // update prepare clip before children
1771     UpdatePrepareClip(node);
1772     node.UpdateCurCornerRadius(curCornerRadius_);
1773 
1774     // 1. Recursively traverse child nodes if above curSurfaceNode and subnode need draw
1775     hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1776     bool isSubTreeNeedPrepare = !curSurfaceNode_ || node.IsSubTreeNeedPrepare(filterInGlobal_) ||
1777         ForcePrepareSubTree() || node.OpincForcePrepareSubTree();
1778     isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1779         node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1780 
1781     PostPrepare(node, !isSubTreeNeedPrepare);
1782     prepareClipRect_ = prepareClipRect;
1783     hasAccumulatedClip_ = hasAccumulatedClip;
1784     dirtyFlag_ = dirtyFlag;
1785     curAlpha_ = prevAlpha;
1786     curCornerRadius_ = curCornerRadius;
1787     node.OpincUpdateRootFlag(unchangeMarkEnable_);
1788     node.RenderTraceDebug();
1789 }
1790 
UpdateRotationStatusForEffectNode(RSEffectRenderNode & node)1791 void RSUniRenderVisitor::UpdateRotationStatusForEffectNode(RSEffectRenderNode& node)
1792 {
1793      // folding/expanding screen force invalidate cache.
1794     node.SetFoldStatusChanged(doAnimate_ &&
1795         curDisplayNode_->GetScreenId() != node.GetCurrentAttachedScreenId());
1796     node.SetCurrentAttachedScreenId(curDisplayNode_->GetScreenId());
1797     node.SetRotationChanged(curDisplayNode_->IsRotationChanged());
1798 }
1799 
UpdatePrepareClip(RSRenderNode & node)1800 void RSUniRenderVisitor::UpdatePrepareClip(RSRenderNode& node)
1801 {
1802     const auto& property = node.GetRenderProperties();
1803     auto& geoPtr = property.GetBoundsGeometry();
1804     if (geoPtr == nullptr) {
1805         return;
1806     }
1807     // Dirty Region use abstract coordinate, property of node use relative coordinate
1808     // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
1809     if (property.GetClipToBounds()) {
1810         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
1811     }
1812     // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
1813     if (property.GetClipToFrame()) {
1814         // MapAbsRect do not handle the translation of OffsetX and OffsetY
1815         RectF frameRect{
1816             property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
1817             property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
1818             property.GetFrameWidth(), property.GetFrameHeight()};
1819         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
1820     }
1821     if (property.GetClipToRRect()) {
1822         RectF rect = property.GetClipRRect().rect_;
1823         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(rect));
1824     }
1825 }
1826 
IsLeashAndHasMainSubNode(RSRenderNode & node) const1827 bool RSUniRenderVisitor::IsLeashAndHasMainSubNode(RSRenderNode& node) const
1828 {
1829     if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1830         return false;
1831     }
1832     const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1833     if (!surfaceNode.IsLeashWindow()) {
1834         return false;
1835     }
1836     // check leashWindow surface has first level mainwindow node
1837     auto children = node.GetSortedChildren();
1838     auto iter = std::find_if((*children).begin(), (*children).end(),
1839         [](const std::shared_ptr<RSRenderNode>& node) {
1840         if (node && node->GetType() == RSRenderNodeType::SURFACE_NODE) {
1841             const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*node);
1842             return surfaceNode.IsMainWindowType();
1843         }
1844         return false;
1845     });
1846     return iter != (*children).end();
1847 }
1848 
NeedPrepareChindrenInReverseOrder(RSRenderNode & node) const1849 bool RSUniRenderVisitor::NeedPrepareChindrenInReverseOrder(RSRenderNode& node) const
1850 {
1851     if (!curSurfaceNode_ && node.GetType() != RSRenderNodeType::RS_NODE) {
1852         return true;
1853     }
1854     return IsLeashAndHasMainSubNode(node);
1855 }
1856 
QuickPrepareChildren(RSRenderNode & node)1857 void RSUniRenderVisitor::QuickPrepareChildren(RSRenderNode& node)
1858 {
1859     MergeRemovedChildDirtyRegion(node, true);
1860     if (node.LastFrameSubTreeSkipped() && curSurfaceDirtyManager_) {
1861         node.ForceMergeSubTreeDirtyRegion(*curSurfaceDirtyManager_, prepareClipRect_);
1862     }
1863     bool animationBackup = ancestorNodeHasAnimation_;
1864     ancestorNodeHasAnimation_ = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
1865     node.ResetChildRelevantFlags();
1866     node.ResetChildUifirstSupportFlag();
1867     auto children = node.GetSortedChildren();
1868     if (NeedPrepareChindrenInReverseOrder(node)) {
1869         std::for_each((*children).rbegin(), (*children).rend(), [this](const std::shared_ptr<RSRenderNode>& node) {
1870             if (!node) {
1871                 return;
1872             }
1873             auto containerDirty = curContainerDirty_;
1874             curDirty_ = node->IsDirty();
1875             curContainerDirty_ = curContainerDirty_ || node->IsDirty();
1876             node->QuickPrepare(shared_from_this());
1877             curContainerDirty_ = containerDirty;
1878         });
1879     } else {
1880         std::for_each((*children).begin(), (*children).end(), [this](const std::shared_ptr<RSRenderNode>& node) {
1881             if (!node) {
1882                 return;
1883             }
1884             curDirty_ = node->IsDirty();
1885             node->QuickPrepare(shared_from_this());
1886         });
1887     }
1888     ancestorNodeHasAnimation_ = animationBackup;
1889     node.ResetGeoUpdateDelay();
1890 }
1891 
InitDisplayInfo(RSDisplayRenderNode & node)1892 bool RSUniRenderVisitor::InitDisplayInfo(RSDisplayRenderNode& node)
1893 {
1894     // 1 init curDisplay and curDisplayDirtyManager
1895     currentVisitDisplay_ = node.GetScreenId();
1896     displayHasSecSurface_.emplace(currentVisitDisplay_, false);
1897     displayHasSkipSurface_.emplace(currentVisitDisplay_, false);
1898     displayHasProtectedSurface_.emplace(currentVisitDisplay_, false);
1899     displaySpecailSurfaceChanged_.emplace(currentVisitDisplay_, false);
1900     hasCaptureWindow_.emplace(currentVisitDisplay_, false);
1901     curDisplayDirtyManager_ = node.GetDirtyManager();
1902     curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
1903     if (!curDisplayDirtyManager_ || !curDisplayNode_) {
1904         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo dirtyMgr or node ptr is nullptr");
1905         return false;
1906     }
1907     curDisplayDirtyManager_->Clear();
1908     transparentCleanFilter_.clear();
1909     transparentDirtyFilter_.clear();
1910 
1911     // 2 init screenManager info
1912     screenManager_ = CreateOrGetScreenManager();
1913     if (!screenManager_) {
1914         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo screenManager_ is nullptr");
1915         return false;
1916     }
1917     screenInfo_ = screenManager_->QueryScreenInfo(node.GetScreenId());
1918     curDisplayDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1919     screenRect_ = RectI{0, 0, screenInfo_.width, screenInfo_.height};
1920 
1921     // 3 init Occlusion info
1922     needRecalculateOcclusion_ = false;
1923     accumulatedOcclusionRegion_.Reset();
1924     occlusionRegionWithoutSkipLayer_.Reset();
1925     if (!curMainAndLeashWindowNodesIds_.empty()) {
1926         std::queue<NodeId>().swap(curMainAndLeashWindowNodesIds_);
1927     }
1928 
1929     // 4. check isHardwareForcedDisabled
1930     auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1931     if (geoPtr == nullptr) {
1932         RS_LOGE("RSUniRenderVisitor::InitDisplayInfo geoPtr is nullptr");
1933         return false;
1934     }
1935     if (geoPtr->IsNeedClientCompose()) {
1936         isHardwareForcedDisabled_ = true;
1937     }
1938 
1939     // 5. check compositeType
1940     auto mirrorNode = node.GetMirrorSource().lock();
1941     switch (screenInfo_.state) {
1942         case ScreenState::SOFTWARE_OUTPUT_ENABLE:
1943             node.SetCompositeType(mirrorNode ?
1944                 RSDisplayRenderNode::CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1945                 RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1946             break;
1947         case ScreenState::HDI_OUTPUT_ENABLE:
1948             node.SetCompositeType(node.IsForceSoftComposite() ?
1949                 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
1950                 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
1951             break;
1952         default:
1953             return false;
1954     }
1955 
1956     return true;
1957 }
1958 
BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1959 bool RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1960 {
1961     // 1. init and record surface info
1962     if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1963         hasCaptureWindow_[currentVisitDisplay_] = true;
1964     }
1965     UpdateSecuritySkipAndProtectedLayersRecord(node);
1966     node.UpdateUIFirstFrameGravity();
1967     if (node.IsMainWindowType() || node.IsLeashWindow()) {
1968         // UpdateCurCornerRadius must process before curSurfaceNode_ update
1969         node.UpdateCurCornerRadius(curCornerRadius_);
1970         curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1971         curSurfaceDirtyManager_ = node.GetDirtyManager();
1972         if (!curSurfaceDirtyManager_ || !curSurfaceNode_) {
1973             RS_LOGE("RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc %{public}s has invalid"
1974                 " SurfaceDirtyManager or node ptr", node.GetName().c_str());
1975             return false;
1976         }
1977         curSurfaceDirtyManager_->Clear();
1978         curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1979         filterInGlobal_ = curSurfaceNode_->IsTransparent();
1980         // update surfaceNode contentDirty and subTreeDirty flag for UIFirst purging policy
1981         RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1982         curSurfaceNode_->UpdateSurfaceCacheContentStaticFlag();
1983         curSurfaceNode_->UpdateSurfaceSubTreeDirtyFlag();
1984         curSurfaceNode_->SetLeashWindowVisibleRegionEmpty(false);
1985     } else if (node.IsAbilityComponent()) {
1986         if (auto nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>()) {
1987             RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(nodePtr);
1988             nodePtr->UpdateSurfaceCacheContentStaticFlag();
1989         }
1990     }
1991     // 2. update surface info and CheckIfOcclusionReusable
1992     node.SetAncestorDisplayNode(curDisplayNode_); // set for boot animation
1993     node.UpdateAncestorDisplayNodeInRenderParams();
1994     node.CleanDstRectChanged();
1995     // [planning] check node isDirty can be optimized.
1996     needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.IsDirty() ||
1997         node.CheckIfOcclusionReusable(preMainAndLeashWindowNodesIds_);
1998     if (autoCacheEnable_ && node.IsAppWindow()) {
1999         node.OpincSetInAppStateStart(unchangeMarkInApp_);
2000     }
2001     // 3. check color space pixelFormat and update RelMatrix
2002     CheckColorSpace(node);
2003     CheckPixelFormat(node);
2004     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
2005         node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
2006     }
2007     return true;
2008 }
2009 
AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)2010 bool RSUniRenderVisitor::AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
2011 {
2012     // 1. Update surfaceNode info and AppWindow gravity
2013     const auto& property = node.GetRenderProperties();
2014     if (node.IsAppWindow()) {
2015         boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
2016         frameGravity_ = property.GetFrameGravity();
2017     }
2018     auto& geoPtr = property.GetBoundsGeometry();
2019     if (geoPtr == nullptr) {
2020         return false;
2021     }
2022     UpdateDstRect(node, geoPtr->GetAbsRect(), prepareClipRect_);
2023     node.UpdatePositionZ();
2024     if (node.IsHardwareEnabledType() && node.GetZorderChanged() && curSurfaceNode_) {
2025         curSurfaceNode_->SetNeedCollectHwcNode(true);
2026     }
2027     UpdateSurfaceRenderNodeScale(node);
2028     UpdateSurfaceRenderNodeRotate(node);
2029     if (node.IsMainWindowType() || node.IsLeashWindow()) {
2030         curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
2031         curDisplayNode_->AddSurfaceNodePosByDescZOrder(node.GetId(), node.GetOldDirtyInSurface());
2032     }
2033     // 2. Update Occlusion info before children preparation
2034     if (node.IsMainWindowType()) {
2035         CalculateOcclusion(node);
2036         if (node.GetFirstLevelNodeId() == node.GetId()) {
2037             globalSurfaceBounds_.emplace_back(node.GetAbsDrawRect());
2038         }
2039     }
2040     // 3. Update HwcNode Info for appNode
2041     UpdateHwcNodeInfoForAppNode(node);
2042     return true;
2043 }
2044 
UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode & node)2045 void RSUniRenderVisitor::UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode& node)
2046 {
2047     if (!node.IsLeashWindow()) {
2048         return;
2049     }
2050     bool isVisibleRegionEmpty = true;
2051     for (const auto& child : *node.GetSortedChildren()) {
2052         const auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
2053         if (childSurfaceNode && childSurfaceNode->IsAppWindow()) {
2054             // leash window is visible when child app has visible region
2055             if (!childSurfaceNode->GetVisibleRegion().IsEmpty()) {
2056                 isVisibleRegionEmpty = false;
2057             } else {
2058                 RS_OPTIONAL_TRACE_NAME_FMT("%s's visible region is empty", childSurfaceNode->GetName().c_str());
2059             }
2060         } else {
2061             // leash window is visible when child is not app window node
2062             isVisibleRegionEmpty = false;
2063         }
2064         if (!isVisibleRegionEmpty) {
2065             break;
2066         }
2067     }
2068     node.SetLeashWindowVisibleRegionEmpty(isVisibleRegionEmpty);
2069 }
2070 
UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode & node)2071 void RSUniRenderVisitor::UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode& node)
2072 {
2073     // app node
2074     if (node.GetNeedCollectHwcNode()) {
2075         node.ResetChildHardwareEnabledNodes();
2076     }
2077     // hwc node
2078     if (node.IsHardwareEnabledType() && curSurfaceNode_) {
2079         if (curSurfaceNode_->GetNeedCollectHwcNode()) {
2080             curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
2081         }
2082         if (!node.GetHardWareDisabledByReverse()) {
2083             node.SetHardwareForcedDisabledState(false);
2084         }
2085         node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
2086         if (!IsHardwareComposerEnabled() || !node.IsDynamicHardwareEnable() ||
2087             curSurfaceNode_->GetVisibleRegion().IsEmpty() ||
2088             !node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
2089             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by param/invisible/no buffer",
2090                 node.GetName().c_str(), node.GetId());
2091             node.SetHardwareForcedDisabledState(true);
2092             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2093                 HwcDisabledReasons::DISABLED_BY_INVALID_PARAM, node.GetName());
2094             if (!node.GetFixRotationByUser()) {
2095                 return;
2096             }
2097         }
2098         auto& geo = node.GetRenderProperties().GetBoundsGeometry();
2099         if (geo == nullptr) {
2100             return;
2101         }
2102         UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
2103         UpdateHwcNodeByTransform(node);
2104         UpdateHwcNodeEnableByBackgroundAlpha(node);
2105         UpdateHwcNodeEnableByBufferSize(node);
2106         UpdateHwcNodeEnableBySrcRect(node);
2107     }
2108 }
2109 
UpdateSrcRect(RSSurfaceRenderNode & node,const Drawing::Matrix & absMatrix,const RectI & absRect)2110 void RSUniRenderVisitor::UpdateSrcRect(RSSurfaceRenderNode& node,
2111     const Drawing::Matrix& absMatrix, const RectI& absRect)
2112 {
2113     auto canvas = std::make_unique<Rosen::Drawing::Canvas>(screenInfo_.phyWidth, screenInfo_.phyHeight);
2114     canvas->ConcatMatrix(absMatrix);
2115 
2116     const auto& dstRect = node.GetDstRect();
2117     Drawing::RectI dst = { std::round(dstRect.GetLeft()), std::round(dstRect.GetTop()), std::round(dstRect.GetRight()),
2118                            std::round(dstRect.GetBottom()) };
2119     node.UpdateSrcRect(*canvas.get(), dst);
2120     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
2121         RSUniRenderUtil::UpdateRealSrcRect(node, absRect);
2122     }
2123 }
2124 
UpdateDstRect(RSSurfaceRenderNode & node,const RectI & absRect,const RectI & clipRect)2125 void RSUniRenderVisitor::UpdateDstRect(RSSurfaceRenderNode& node, const RectI& absRect, const RectI& clipRect)
2126 {
2127     auto dstRect = absRect;
2128     // If the screen is expanded, intersect the destination rectangle with the screen rectangle
2129     dstRect = dstRect.IntersectRect(RectI(curDisplayNode_->GetDisplayOffsetX(), curDisplayNode_->GetDisplayOffsetY(),
2130         screenInfo_.width, screenInfo_.height));
2131     // Remove the offset of the screen
2132     dstRect.left_ = dstRect.left_ - curDisplayNode_->GetDisplayOffsetX();
2133     dstRect.top_ = dstRect.top_ - curDisplayNode_->GetDisplayOffsetY();
2134     // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
2135     if (node.IsHardwareEnabledType()) {
2136         dstRect = dstRect.IntersectRect(clipRect);
2137         if (curSurfaceNode_ && (node.GetId() != curSurfaceNode_->GetId())) {
2138             dstRect = dstRect.IntersectRect(curSurfaceNode_->GetDstRect());
2139         }
2140     }
2141     dstRect.left_ = static_cast<int>(std::round(dstRect.left_ * screenInfo_.GetRogWidthRatio()));
2142     dstRect.top_ = static_cast<int>(std::round(dstRect.top_ * screenInfo_.GetRogHeightRatio()));
2143     dstRect.width_ = static_cast<int>(std::round(dstRect.width_ * screenInfo_.GetRogWidthRatio()));
2144     dstRect.height_ = static_cast<int>(std::round(dstRect.height_ * screenInfo_.GetRogHeightRatio()));
2145     // Set the destination rectangle of the node
2146     node.SetDstRect(dstRect);
2147 }
2148 
UpdateHwcNodeByTransform(RSSurfaceRenderNode & node)2149 void RSUniRenderVisitor::UpdateHwcNodeByTransform(RSSurfaceRenderNode& node)
2150 {
2151     if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
2152         return;
2153     }
2154     node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
2155     RSUniRenderUtil::DealWithNodeGravity(node, screenInfo_);
2156     RSUniRenderUtil::LayerRotate(node, screenInfo_);
2157     RSUniRenderUtil::LayerCrop(node, screenInfo_);
2158     RSUniRenderUtil::DealWithScalingMode(node);
2159     node.SetCalcRectInPrepare(true);
2160 }
2161 
UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode & node)2162 void RSUniRenderVisitor::UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode& node)
2163 {
2164     bool bgTransport = !node.GetAncoForceDoDirect() &&
2165         (static_cast<uint8_t>(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX);
2166     if (bgTransport) {
2167         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by background color alpha < 1",
2168             node.GetName().c_str(), node.GetId());
2169         // use in skip updating hardware state for hwcnode with background alpha in specific situation
2170         if (!RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag()) {
2171             node.SetHardwareForcedDisabledState(true);
2172         }
2173         node.SetNodeHasBackgroundColorAlpha(true);
2174         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2175             HwcDisabledReasons::DISABLED_BY_BACKGROUND_ALPHA, node.GetName());
2176     }
2177 }
2178 
UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode & node)2179 void RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode& node)
2180 {
2181     if (!node.IsRosenWeb() || node.IsHardwareForcedDisabled()) {
2182         return;
2183     }
2184     if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
2185         return;
2186     }
2187     const auto& property = node.GetRenderProperties();
2188     auto gravity = property.GetFrameGravity();
2189     if (gravity != Gravity::TOP_LEFT) {
2190         return;
2191     }
2192     auto surfaceHandler = node.GetRSSurfaceHandler();
2193     auto consumer = surfaceHandler->GetConsumer();
2194     if (consumer == nullptr) {
2195         return;
2196     }
2197 
2198     auto buffer = surfaceHandler->GetBuffer();
2199     const auto bufferWidth = buffer->GetSurfaceBufferWidth();
2200     const auto bufferHeight = buffer->GetSurfaceBufferHeight();
2201     auto boundsWidth = property.GetBoundsWidth();
2202     auto boundsHeight = property.GetBoundsHeight();
2203 
2204     auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
2205     if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
2206         RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize GetSurfaceBufferTransformType failed");
2207     }
2208     if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
2209         transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
2210         std::swap(boundsWidth, boundsHeight);
2211     }
2212     if ((bufferWidth < boundsWidth) || (bufferHeight < boundsHeight)) {
2213         RS_OPTIONAL_TRACE_NAME_FMT(
2214             "hwc debug: name:%s id:%" PRIu64 " buffer:[%d, %d] bounds:[%f, %f] disabled by buffer nonmatching",
2215             node.GetName().c_str(), node.GetId(), bufferWidth, bufferHeight, boundsWidth, boundsHeight);
2216         node.SetHardwareForcedDisabledState(true);
2217         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(
2218             node.GetId(), HwcDisabledReasons::DISABLED_BY_BUFFER_NONMATCH, node.GetName());
2219     }
2220 }
2221 
UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode & node)2222 void RSUniRenderVisitor::UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode& node)
2223 {
2224     if (node.IsHardwareForcedDisabled()) {
2225         return;
2226     }
2227     bool hasRotation = false;
2228     if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetConsumer()) {
2229         const auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
2230         auto rotation = RSBaseRenderUtil::GetRotateTransform(
2231             RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, node.GetRSSurfaceHandler()->GetBuffer()));
2232         hasRotation = rotation == GRAPHIC_ROTATE_90 || rotation == GRAPHIC_ROTATE_270;
2233     }
2234     node.UpdateHwcDisabledBySrcRect(hasRotation);
2235     if (node.IsHardwareDisabledBySrcRect()) {
2236         node.SetHardwareForcedDisabledState(true);
2237         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2238             HwcDisabledReasons::DISABLED_BY_SRC_PIXEL, node.GetName());
2239     }
2240 }
2241 
UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2242 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector<RectI>& hwcRects,
2243     std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2244 {
2245     if (hwcNode->IsHardwareForcedDisabled()) {
2246         return;
2247     }
2248     auto dst = hwcNode->GetDstRect();
2249     if (hwcNode->GetAncoForceDoDirect()) {
2250         hwcRects.emplace_back(dst);
2251         return;
2252     }
2253     for (auto rect : hwcRects) {
2254         if (dst.Intersect(rect) && !RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
2255             if (RsCommonHook::Instance().GetVideoSurfaceFlag() &&
2256                 ((dst.GetBottom() - rect.GetTop() <= MIN_OVERLAP && dst.GetBottom() - rect.GetTop() >= 0) ||
2257                 (rect.GetBottom() - dst.GetTop() <= MIN_OVERLAP && rect.GetBottom() - dst.GetTop() >= 0))) {
2258                 return;
2259             }
2260             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by hwc node above",
2261                 hwcNode->GetName().c_str(), hwcNode->GetId());
2262             hwcNode->SetHardwareForcedDisabledState(true);
2263             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2264                 HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
2265             return;
2266         }
2267     }
2268     hwcRects.emplace_back(dst);
2269 }
2270 
UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)2271 void RSUniRenderVisitor::UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)
2272 {
2273     auto hwcNodeGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2274     if (!hwcNodeGeo) {
2275         RS_LOGE("hwcNode Geometry is not prepared.");
2276         return;
2277     }
2278     bool hasCornerRadius = !hwcNode->GetRenderProperties().GetCornerRadius().IsZero();
2279     std::vector<RectI> currIntersectedRoundCornerAABBs = {};
2280     float alpha = hwcNode->GetRenderProperties().GetAlpha();
2281     Drawing::Matrix totalMatrix = hwcNodeGeo->GetMatrix();
2282     auto hwcNodeRect = hwcNodeGeo->GetAbsRect();
2283     bool isNodeRenderByDrawingCache = false;
2284     RSUniRenderUtil::TraverseParentNodeAndReduce(hwcNode,
2285         [&isNodeRenderByDrawingCache](std::shared_ptr<RSRenderNode> parent) {
2286             if (isNodeRenderByDrawingCache) {
2287                 return;
2288             }
2289             // if the parent node of hwcNode is marked freeze or nodegroup, RS closes hardware composer of hwcNode.
2290             isNodeRenderByDrawingCache = isNodeRenderByDrawingCache || parent->IsStaticCached() ||
2291                 (parent->GetNodeGroupType() != RSRenderNode::NodeGroupType::NONE);
2292         },
2293         [&alpha](std::shared_ptr<RSRenderNode> parent) {
2294             auto& parentProperty = parent->GetRenderProperties();
2295             alpha *= parentProperty.GetAlpha();
2296         },
2297         [&totalMatrix](std::shared_ptr<RSRenderNode> parent) {
2298             if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
2299                 totalMatrix.PostConcat(opt.value());
2300             } else {
2301                 return;
2302             }
2303         },
2304         [&currIntersectedRoundCornerAABBs, hwcNodeRect](std::shared_ptr<RSRenderNode> parent) {
2305             auto& parentProperty = parent->GetRenderProperties();
2306             auto cornerRadius = parentProperty.GetCornerRadius();
2307             auto maxCornerRadius = *std::max_element(std::begin(cornerRadius.data_), std::end(cornerRadius.data_));
2308             auto parentGeo = parentProperty.GetBoundsGeometry();
2309             static const std::array offsetVecs {
2310                 UIPoint { 0, 0 },
2311                 UIPoint { 1, 0 },
2312                 UIPoint { 0, 1 },
2313                 UIPoint { 1, 1 }
2314             };
2315 
2316             // The logic here is to calculate whether the HWC Node affects
2317             // the round corner property of the parent node.
2318             // The method is calculating the rounded AABB of each HWC node
2319             // with respect to all parent nodes above it and storing the results.
2320             // When a HWC node is found below, the AABBs and the HWC node
2321             // are checked for intersection. If there is an intersection,
2322             // the node above it is disabled from taking the HWC pipeline.
2323             auto checkIntersectWithRoundCorner = [&currIntersectedRoundCornerAABBs, hwcNodeRect](
2324                 const RectI& rect, float radiusX, float radiusY) {
2325                 if (radiusX <= 0 || radiusY <= 0) {
2326                     return;
2327                 }
2328                 UIPoint offset { rect.GetWidth() - radiusX, rect.GetHeight() - radiusY };
2329                 UIPoint anchorPoint { rect.GetLeft(), rect.GetTop() };
2330                 std::for_each(std::begin(offsetVecs), std::end(offsetVecs),
2331                     [&currIntersectedRoundCornerAABBs, hwcNodeRect, offset,
2332                         radiusX, radiusY, anchorPoint](auto offsetVec) {
2333                         auto res = anchorPoint + offset * offsetVec;
2334                         auto roundCornerAABB = RectI(res.x_, res.y_, radiusX, radiusY);
2335                         if (!roundCornerAABB.IntersectRect(hwcNodeRect).IsEmpty()) {
2336                             currIntersectedRoundCornerAABBs.push_back(roundCornerAABB);
2337                         }
2338                     }
2339                 );
2340             };
2341             if (parentGeo) {
2342                 auto parentRect = parentGeo->GetAbsRect();
2343                 checkIntersectWithRoundCorner(parentRect, maxCornerRadius, maxCornerRadius);
2344 
2345                 if (parentProperty.GetClipToRRect()) {
2346                     RRect parentClipRRect = parentProperty.GetClipRRect();
2347                     RectI parentClipRect = parentGeo->MapAbsRect(parentClipRRect.rect_);
2348                     float maxClipRRectCornerRadiusX = 0, maxClipRRectCornerRadiusY = 0;
2349                     constexpr size_t radiusVecSize = 4;
2350                     for (size_t i = 0; i < radiusVecSize; ++i) {
2351                         maxClipRRectCornerRadiusX = std::max(maxClipRRectCornerRadiusX, parentClipRRect.radius_[i].x_);
2352                         maxClipRRectCornerRadiusY = std::max(maxClipRRectCornerRadiusY, parentClipRRect.radius_[i].y_);
2353                     }
2354                     checkIntersectWithRoundCorner(parentClipRect, maxClipRRectCornerRadiusX, maxClipRRectCornerRadiusY);
2355                 }
2356             }
2357         }
2358     );
2359     if (isNodeRenderByDrawingCache) {
2360         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by drawing cache",
2361             hwcNode->GetName().c_str(), hwcNode->GetId());
2362         hwcNode->SetHardwareForcedDisabledState(isNodeRenderByDrawingCache);
2363     }
2364     hwcNode->SetTotalMatrix(totalMatrix);
2365     hwcNode->SetGlobalAlpha(alpha);
2366     hwcNode->SetIntersectedRoundCornerAABBs(std::move(currIntersectedRoundCornerAABBs));
2367 }
2368 
UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2369 void RSUniRenderVisitor::UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2370 {
2371     auto alpha = hwcNode->GetGlobalAlpha();
2372     auto totalMatrix = hwcNode->GetTotalMatrix();
2373     if (alpha < 1.0f) {
2374         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by accumulated alpha:%.2f",
2375             hwcNode->GetName().c_str(), hwcNode->GetId(), alpha);
2376         hwcNode->SetHardwareForcedDisabledState(true);
2377         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2378             HwcDisabledReasons::DISABLED_BY_ACCUMULATED_ALPHA, hwcNode->GetName());
2379         return;
2380     }
2381     // [planning] degree only multiples of 90 now
2382     int degree = RSUniRenderUtil::GetRotationDegreeFromMatrix(totalMatrix);
2383     bool hasRotate = degree % RS_ROTATION_90 != 0 || RSUniRenderUtil::Is3DRotation(totalMatrix);
2384     if (hasRotate) {
2385         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by rotation:%d",
2386             hwcNode->GetName().c_str(), hwcNode->GetId(), degree);
2387         hwcNode->SetHardwareForcedDisabledState(true);
2388         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2389             HwcDisabledReasons::DISABLED_BY_ROTATION, hwcNode->GetName());
2390         return;
2391     }
2392 }
2393 
ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode> & hwcNodePtr)2394 void RSUniRenderVisitor::ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr)
2395 {
2396     if ((hwcNodePtr->GetAncoFlags() & static_cast<uint32_t>(AncoFlags::IS_ANCO_NODE)) == 0) {
2397         return;
2398     }
2399     ancoNodes_.insert(hwcNodePtr);
2400     auto alpha = hwcNodePtr->GetGlobalAlpha();
2401     RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 "src %{public}s dst %{public}s "
2402         "alpha:%{public}.2f", hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(),
2403         hwcNodePtr->GetSrcRect().ToString().c_str(), hwcNodePtr->GetDstRect().ToString().c_str(), alpha);
2404     if (ROSEN_EQ(alpha, 0.0f)) {
2405         return;
2406     }
2407 
2408     if (!hwcNodePtr->GetRSSurfaceHandler() || !hwcNodePtr->GetRSSurfaceHandler()->GetBuffer()) {
2409         RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 " handler or buffer is null, skip",
2410             hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2411         return;
2412     }
2413 
2414     ancoHasGpu_ = (ancoHasGpu_ || hwcNodePtr->IsHardwareForcedDisabled());
2415 }
2416 
InitAncoStatus()2417 void RSUniRenderVisitor::InitAncoStatus()
2418 {
2419     ancoHasGpu_ = false;
2420     ancoNodes_.clear();
2421 }
2422 
UpdateHwcNodeEnable()2423 void RSUniRenderVisitor::UpdateHwcNodeEnable()
2424 {
2425     InitAncoStatus();
2426 
2427     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2428     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2429         [this](RSBaseRenderNode::SharedPtr& nodePtr) {
2430         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2431         if (!surfaceNode) {
2432             return;
2433         }
2434         UpdateHwcNodeEnableByGlobalFilter(surfaceNode);
2435         surfaceNode->ResetNeedCollectHwcNode();
2436         const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2437         if (hwcNodes.empty()) {
2438             return;
2439         }
2440         std::vector<RectI> hwcRects;
2441         for (const auto& hwcNode : hwcNodes) {
2442             auto hwcNodePtr = hwcNode.lock();
2443             if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2444                 continue;
2445             }
2446             if (hwcNodePtr->GetProtectedLayer()) {
2447                 drmNodes_.emplace_back(hwcNode);
2448             }
2449             UpdateHwcNodeProperty(hwcNodePtr);
2450             UpdateHwcNodeEnableByRotateAndAlpha(hwcNodePtr);
2451             UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(hwcRects, hwcNodePtr);
2452 
2453             ProcessAncoNode(hwcNodePtr);
2454         }
2455     });
2456     UpdateAncoNodeHWCDisabledState();
2457     PrevalidateHwcNode();
2458     UpdateHwcNodeEnableByNodeBelow();
2459 }
2460 
UpdateAncoNodeHWCDisabledState()2461 void RSUniRenderVisitor::UpdateAncoNodeHWCDisabledState()
2462 {
2463     if (ancoHasGpu_) {
2464         for (const auto& hwcNodePtr : ancoNodes_) {
2465             hwcNodePtr->SetHardwareForcedDisabledState(true);
2466         }
2467     }
2468 
2469     InitAncoStatus();
2470 }
2471 
PrevalidateHwcNode()2472 void RSUniRenderVisitor::PrevalidateHwcNode()
2473 {
2474     if (!isPrevalidateHwcNodeEnable_) {
2475         RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate close");
2476         return;
2477     }
2478     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2479     std::vector<RequestLayerInfo> prevalidLayers;
2480     uint32_t curFps = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(curDisplayNode_->GetScreenId());
2481     uint32_t zOrder = static_cast<uint32_t>(globalZOrder_);
2482     // add surfaceNode layer
2483     RSUniHwcPrevalidateUtil::GetInstance().CollectSurfaceNodeLayerInfo(
2484         prevalidLayers, curMainAndLeashSurfaces, curFps, zOrder, screenInfo_);
2485     std::vector<RequestLayerInfo> uiFirstLayers;
2486     // collect uifirst layer
2487     // zOrder + 1.f is displayNode, UIFirst layer must be above displayNode(zorder + 2.f)
2488     RSUniHwcPrevalidateUtil::GetInstance().CollectUIFirstLayerInfo(
2489         uiFirstLayers, curFps, static_cast<float>(zOrder) + 2.f, screenInfo_);
2490     RS_TRACE_NAME_FMT("PrevalidateHwcNode hwcLayer: %u, uifirstLayer: %u", prevalidLayers.size(), uiFirstLayers.size());
2491     if (prevalidLayers.size() == 0 && uiFirstLayers.size() == 0) {
2492         RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode no hardware layer");
2493         return;
2494     }
2495     // add display layer
2496     RequestLayerInfo displayLayer;
2497     if (RSUniHwcPrevalidateUtil::GetInstance().CreateDisplayNodeLayerInfo(
2498         zOrder++, curDisplayNode_, screenInfo_, curFps, displayLayer)) {
2499         prevalidLayers.emplace_back(displayLayer);
2500     }
2501     // add uiFirst layer
2502     prevalidLayers.insert(prevalidLayers.end(), uiFirstLayers.begin(), uiFirstLayers.end());
2503     // add rcd layer
2504     RequestLayerInfo rcdLayer;
2505     if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(
2506         RSRcdRenderManager::GetInstance().GetBackgroundSurfaceNode(), screenInfo_, curFps, rcdLayer)) {
2507         prevalidLayers.emplace_back(rcdLayer);
2508     }
2509     if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(
2510         RSRcdRenderManager::GetInstance().GetContentSurfaceNode(), screenInfo_, curFps, rcdLayer)) {
2511         prevalidLayers.emplace_back(rcdLayer);
2512     }
2513     std::map<uint64_t, RequestCompositionType> strategy;
2514     if (!RSUniHwcPrevalidateUtil::GetInstance().PreValidate(screenInfo_.id, prevalidLayers, strategy)) {
2515         RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate failed");
2516         return;
2517     }
2518     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2519     for (auto it : strategy) {
2520         RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode id: %{public}" PRIu64 ","
2521             " result: %{public}d", it.first, it.second);
2522         if (it.second == RequestCompositionType::DEVICE) {
2523             continue;
2524         }
2525         auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(it.first);
2526         if (node == nullptr) {
2527             continue;
2528         }
2529         if (it.second == RequestCompositionType::DEVICE_VSCF) {
2530             node->SetArsrTag(false);
2531             continue;
2532         }
2533         if (node->IsInFixedRotation() || node->GetProtectedLayer()) {
2534             continue;
2535         }
2536         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by prevalidate",
2537             node->GetName().c_str(), node->GetId());
2538         node->SetHardwareForcedDisabledState(true);
2539         if (node->GetRSSurfaceHandler()) {
2540             node->GetRSSurfaceHandler()->SetGlobalZOrder(-1.f);
2541         }
2542         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
2543             HwcDisabledReasons::DISABLED_BY_PREVALIDATE, node->GetName());
2544     }
2545 }
2546 
UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode> & node)2547 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode>& node)
2548 {
2549     const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
2550     if (hwcNodes.empty()) {
2551         return;
2552     }
2553     std::shared_ptr<RSSurfaceRenderNode> pointWindow;
2554     std::vector<std::shared_ptr<RSSurfaceRenderNode>> topLayers;
2555     for (auto hwcNode : hwcNodes) {
2556         auto hwcNodePtr = hwcNode.lock();
2557         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2558             continue;
2559         }
2560         auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
2561         if (hwcNodePtr->IsLayerTop()) {
2562             topLayers.emplace_back(hwcNodePtr);
2563             continue;
2564         }
2565         if (node->IsHardwareEnabledTopSurface()) {
2566             pointWindow = hwcNodePtr;
2567             continue;
2568         }
2569         if (hasUniRenderHdrSurface_) {
2570             hwcNodePtr->SetHardwareForcedDisabledState(true);
2571         }
2572         UpdateHwcNodeDirtyRegionForApp(node, hwcNodePtr);
2573         hwcNodePtr->SetCalcRectInPrepare(false);
2574         hwcNodePtr->SetHardWareDisabledByReverse(false);
2575         surfaceHandler->SetGlobalZOrder(hwcNodePtr->IsHardwareForcedDisabled() && !hwcNodePtr->GetProtectedLayer()
2576             ? -1.f : globalZOrder_++);
2577         auto transform = RSUniRenderUtil::GetLayerTransform(*hwcNodePtr, screenInfo_);
2578         hwcNodePtr->UpdateHwcNodeLayerInfo(transform);
2579     }
2580     curDisplayNode_->SetDisplayGlobalZOrder(globalZOrder_);
2581     if (!topLayers.empty()) {
2582         UpdateTopLayersDirtyStatus(topLayers);
2583     }
2584     if (pointWindow) {
2585         UpdatePointWindowDirtyStatus(pointWindow);
2586     }
2587 }
2588 
UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode> & pointWindow)2589 void RSUniRenderVisitor::UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode>& pointWindow)
2590 {
2591     std::shared_ptr<RSSurfaceHandler> pointSurfaceHandler = pointWindow->GetMutableRSSurfaceHandler();
2592     if (pointSurfaceHandler) {
2593         // globalZOrder_ + 2 is displayNode layer, point window must be at the top.
2594         pointSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 2);
2595         pointWindow->SetHardwareForcedDisabledState(!IsHardwareComposerEnabled() || !pointWindow->ShouldPaint() ||
2596             hasUniRenderHdrSurface_);
2597         auto transform = RSUniRenderUtil::GetLayerTransform(*pointWindow, screenInfo_);
2598         pointWindow->UpdateHwcNodeLayerInfo(transform);
2599     }
2600 }
2601 
UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & topLayers)2602 void RSUniRenderVisitor::UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& topLayers)
2603 {
2604     for (const auto& topLayer : topLayers) {
2605         std::shared_ptr<RSSurfaceHandler> topLayerSurfaceHandler = topLayer->GetMutableRSSurfaceHandler();
2606         if (topLayerSurfaceHandler) {
2607             topLayerSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 1);
2608             topLayer->SetCalcRectInPrepare(false);
2609             topLayer->SetHardwareForcedDisabledState(!IsHardwareComposerEnabled() || !topLayer->ShouldPaint() ||
2610                 hasUniRenderHdrSurface_);
2611             auto transform = RSUniRenderUtil::GetLayerTransform(*topLayer, screenInfo_);
2612             topLayer->UpdateHwcNodeLayerInfo(transform);
2613         }
2614     }
2615 }
2616 
UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode> & appNode,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2617 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode>& appNode,
2618     std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2619 {
2620     // if current frame hwc enable status not equal with last frame
2621     // or current frame do gpu composition and has buffer consumed,
2622     // we need merge hwc node dst rect to dirty region.
2623     if (!hwcNode->IsHardwareForcedDisabled() != hwcNode->GetIsLastFrameHwcEnabled()) {
2624         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
2625         return;
2626     }
2627     if (!hwcNode->GetRSSurfaceHandler()) {
2628         return;
2629     }
2630     if (hwcNode->IsHardwareForcedDisabled() && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
2631         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetOldDirtyInSurface());
2632     }
2633     if (hasMirrorDisplay_ && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2634         !appNode->GetVisibleRegion().IsEmpty()) {
2635         // merge hwc node dst rect for virtual screen dirty, in case the main display node skip
2636         curDisplayDirtyManager_->MergeHwcDirtyRect(hwcNode->GetDstRect());
2637     }
2638 }
2639 
UpdateSurfaceDirtyAndGlobalDirty()2640 void RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty()
2641 {
2642     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2643     // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
2644     Occlusion::Region accumulatedDirtyRegion;
2645     bool hasMainAndLeashSurfaceDirty = false;
2646     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2647         [this, &accumulatedDirtyRegion, &hasMainAndLeashSurfaceDirty](RSBaseRenderNode::SharedPtr& nodePtr) {
2648         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2649         if (!surfaceNode) {
2650             RS_LOGE("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surfaceNode is nullptr");
2651             return;
2652         }
2653         auto dirtyManager = surfaceNode->GetDirtyManager();
2654         RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
2655         // 0. update hwc node dirty region and create layer
2656         UpdateHwcNodeDirtyRegionAndCreateLayer(surfaceNode);
2657         // 1. calculate abs dirtyrect and update partialRenderParams
2658         // currently only sync visible region info
2659         surfaceNode->UpdatePartialRenderParams();
2660         if (dirtyManager && dirtyManager->IsCurrentFrameDirty()) {
2661             hasMainAndLeashSurfaceDirty = true;
2662         }
2663         if (surfaceNode->IsMainWindowType() && IfSkipInCalcGlobalDirty(*surfaceNode)) {
2664             RS_LOGD("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surface:%{public}s "
2665                 "which is occluded don't need to process global dirty", surfaceNode->GetName().c_str());
2666             return;
2667         }
2668         // 2. check surface node dirtyrect need merge into displayDirtyManager
2669         CheckMergeSurfaceDirtysForDisplay(surfaceNode);
2670         // 3. check merge transparent filter when it intersects with pre-dirty
2671         CheckMergeDisplayDirtyByTransparentFilter(surfaceNode, accumulatedDirtyRegion);
2672     });
2673     curDisplayNode_->SetMainAndLeashSurfaceDirty(hasMainAndLeashSurfaceDirty);
2674     CheckMergeDebugRectforRefreshRate(curMainAndLeashSurfaces);
2675     CheckMergeGlobalFilterForDisplay(accumulatedDirtyRegion);
2676     ResetDisplayDirtyRegion();
2677     curDisplayNode_->ClearCurrentSurfacePos();
2678     std::swap(preMainAndLeashWindowNodesIds_, curMainAndLeashWindowNodesIds_);
2679 
2680 #ifdef RS_PROFILER_ENABLED
2681     RS_PROFILER_SET_DIRTY_REGION(accumulatedDirtyRegion);
2682 #endif
2683 }
UpdateHwcNodeEnableByNodeBelow()2684 void RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow()
2685 {
2686     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2687     // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order travelsal
2688     std::vector<RectI> hwcRects;
2689     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2690         [this, &hwcRects](RSBaseRenderNode::SharedPtr& nodePtr) {
2691         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2692         if (!surfaceNode) {
2693             RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow surfaceNode is nullptr");
2694             return;
2695         }
2696         // use in temporary scheme to realize DSS
2697         auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2698         if (!hwcNodes.empty() && RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag() &&
2699             RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
2700             UpdateHardwareStateByHwcNodeBackgroundAlpha(hwcNodes);
2701         }
2702         // use end
2703         // disable hwc node with corner radius if intersects with hwc node below
2704         UpdateChildHwcNodeEnableByHwcNodeBelow(hwcRects, surfaceNode);
2705     });
2706 }
2707 
UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & appNode)2708 void RSUniRenderVisitor::UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI>& hwcRects,
2709     std::shared_ptr<RSSurfaceRenderNode>& appNode)
2710 {
2711     const auto& hwcNodes = appNode->GetChildHardwareEnabledNodes();
2712     for (auto hwcNode : hwcNodes) {
2713         auto hwcNodePtr = hwcNode.lock();
2714         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2715             continue;
2716         }
2717         UpdateCornerRadiusInfoForDRM(hwcNodePtr, hwcRects);
2718         UpdateHwcNodeEnableByHwcNodeBelowSelf(hwcRects, hwcNodePtr,
2719             hwcNodePtr->GetIntersectedRoundCornerAABBsSize() != 0);
2720     }
2721 }
2722 
UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,std::vector<RectI> & hwcRects)2723 void RSUniRenderVisitor::UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,
2724     std::vector<RectI>& hwcRects)
2725 {
2726     if (!hwcNode || !hwcNode->GetProtectedLayer()) {
2727         return;
2728     }
2729     auto instanceNode = hwcNode->GetInstanceRootNode() ?
2730         hwcNode->GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
2731     if (!instanceNode) {
2732         hwcNode->SetCornerRadiusInfoForDRM({});
2733         return;
2734     }
2735     auto instanceAbsRect = instanceNode->GetAbsDrawRect();
2736     auto instanceCornerRadius = instanceNode->GetGlobalCornerRadius();
2737     if (instanceAbsRect.IsEmpty() || instanceCornerRadius.IsZero() ||
2738         ROSEN_EQ(instanceNode->GetRenderProperties().GetBoundsWidth(), 0.0f)) {
2739         hwcNode->SetCornerRadiusInfoForDRM({});
2740         return;
2741     }
2742     auto hwcGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2743     if (!hwcGeo) {
2744         hwcNode->SetCornerRadiusInfoForDRM({});
2745         return;
2746     }
2747     auto hwcAbsRect = hwcGeo->MapRect(hwcNode->GetSelfDrawRect(), hwcNode->GetTotalMatrix());
2748     hwcAbsRect = hwcAbsRect.IntersectRect(instanceAbsRect);
2749     if (hwcAbsRect.IsEmpty()) {
2750         hwcNode->SetCornerRadiusInfoForDRM({});
2751         return;
2752     }
2753     auto ratio = static_cast<float>(instanceAbsRect.GetWidth()) /
2754         instanceNode->GetRenderProperties().GetBoundsWidth();
2755     std::vector<float> ratioVector = { 0.0f, 0.0f, 0.0f, 0.0f };
2756     bool isIntersectWithRoundCorner =
2757         CheckIfRoundCornerIntersectDRM(ratio, ratioVector, instanceCornerRadius, instanceAbsRect, hwcAbsRect);
2758     // store radius information when drm overlaps with other hwc nodes
2759     if (isIntersectWithRoundCorner) {
2760         for (const auto& rect : hwcRects) {
2761             if (hwcAbsRect.Intersect(rect)) {
2762                 std::vector<float> drmCornerRadiusInfo = {
2763                     static_cast<float>(hwcAbsRect.GetLeft()), static_cast<float>(hwcAbsRect.GetTop()),
2764                     static_cast<float>(hwcAbsRect.GetWidth()), static_cast<float>(hwcAbsRect.GetHeight()),
2765                     // get corner radius num by index 0, 1, 2, 3
2766                     instanceCornerRadius[0] * ratioVector[0], instanceCornerRadius[1] * ratioVector[1],
2767                     instanceCornerRadius[2] * ratioVector[2], instanceCornerRadius[3] * ratioVector[3]};
2768                 hwcNode->SetCornerRadiusInfoForDRM(drmCornerRadiusInfo);
2769                 return;
2770             }
2771         }
2772     }
2773     hwcNode->SetCornerRadiusInfoForDRM({});
2774 }
2775 
CheckIfRoundCornerIntersectDRM(const float & ratio,std::vector<float> & ratioVector,const Vector4f & instanceCornerRadius,const RectI & instanceAbsRect,const RectI & hwcAbsRect)2776 bool RSUniRenderVisitor::CheckIfRoundCornerIntersectDRM(const float& ratio, std::vector<float>& ratioVector,
2777     const Vector4f& instanceCornerRadius, const RectI& instanceAbsRect, const RectI& hwcAbsRect)
2778 {
2779     auto maxRadius = *std::max_element(std::begin(instanceCornerRadius.data_),
2780         std::end(instanceCornerRadius.data_)) * ratio;
2781     bool isIntersectWithRoundCorner = false;
2782     static const std::vector<UIPoint> offsetVecs = { UIPoint { 0, 0 }, UIPoint { 1, 0 },
2783         UIPoint { 0, 1 }, UIPoint { 1, 1 } };
2784     UIPoint offset { instanceAbsRect.GetWidth() - maxRadius, instanceAbsRect.GetHeight() - maxRadius };
2785     UIPoint anchorPoint { instanceAbsRect.GetLeft(), instanceAbsRect.GetTop() };
2786     // if round corners intersect drm, update ratioVectors
2787     for (size_t i = 0; i < offsetVecs.size(); i++) {
2788         auto res = anchorPoint + offset * offsetVecs[i];
2789         if (RectI(res.x_, res.y_, maxRadius, maxRadius).Intersect(hwcAbsRect)) {
2790             isIntersectWithRoundCorner = true;
2791             ratioVector[i] = ratio;
2792         }
2793     }
2794     return isIntersectWithRoundCorner;
2795 }
2796 
UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & hwcNode,bool isIntersectWithRoundCorner)2797 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI>& hwcRects,
2798     std::shared_ptr<RSSurfaceRenderNode>& hwcNode, bool isIntersectWithRoundCorner)
2799 {
2800     if (hwcNode->IsHardwareForcedDisabled()) {
2801         if (RSMainThread::CheckIsHdrSurface(*hwcNode)) {
2802             hasUniRenderHdrSurface_ = true;
2803         }
2804         return;
2805     }
2806     auto absBound = RectI();
2807     if (auto geo = hwcNode->GetRenderProperties().GetBoundsGeometry()) {
2808         absBound = geo->GetAbsRect();
2809     } else {
2810         return;
2811     }
2812     if (hwcNode->GetAncoForceDoDirect() || !isIntersectWithRoundCorner) {
2813         hwcRects.emplace_back(absBound);
2814         return;
2815     }
2816     for (const auto& rect : hwcRects) {
2817         for (auto& roundCornerAABB : hwcNode->GetIntersectedRoundCornerAABBs()) {
2818             if (!roundCornerAABB.IntersectRect(rect).IsEmpty()) {
2819                 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64
2820                     " disabled by corner radius + hwc node below",
2821                     hwcNode->GetName().c_str(), hwcNode->GetId());
2822                 if (hwcNode->GetProtectedLayer()) {
2823                     continue;
2824                 }
2825                 hwcNode->SetHardwareForcedDisabledState(true);
2826                 if (RSMainThread::CheckIsHdrSurface(*hwcNode)) {
2827                     hasUniRenderHdrSurface_ = true;
2828                 }
2829                 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2830                     HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
2831                 return;
2832             }
2833         }
2834     }
2835     hwcRects.emplace_back(absBound);
2836 }
2837 
UpdateSurfaceOcclusionInfo()2838 void RSUniRenderVisitor::UpdateSurfaceOcclusionInfo()
2839 {
2840     allDstCurVisVec_.insert(allDstCurVisVec_.end(), dstCurVisVec_.begin(), dstCurVisVec_.end());
2841     dstCurVisVec_.clear();
2842 }
2843 
CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode & surfaceNode) const2844 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode& surfaceNode) const
2845 {
2846     // surfaceNode is transparent
2847     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2848     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2849     if (surfaceNode.IsTransparent()) {
2850         RectI transparentDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2851         if (!transparentDirtyRect.IsEmpty()) {
2852             RS_LOGD("CheckMergeDisplayDirtyByTransparent global merge transparent dirty "
2853                 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2854                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2855                 transparentDirtyRect.ToString().c_str());
2856             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(transparentDirtyRect);
2857         }
2858     }
2859     // surfaceNode has transparent regions
2860     CheckMergeDisplayDirtyByTransparentRegions(surfaceNode);
2861 }
2862 
CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode & surfaceNode) const2863 void RSUniRenderVisitor::CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode& surfaceNode) const
2864 {
2865     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2866     if (surfaceNode.GetZorderChanged()) {
2867         RS_LOGD("CheckMergeDisplayDirtyByZorderChanged global merge GetZorderChanged "
2868             "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2869             curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2870             oldDirtyInSurface.ToString().c_str());
2871         curDisplayNode_->GetDirtyManager()->MergeDirtyRect(oldDirtyInSurface);
2872     }
2873 }
2874 
CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode & surfaceNode) const2875 void RSUniRenderVisitor::CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode& surfaceNode) const
2876 {
2877     RectI lastFrameSurfacePos = curDisplayNode_->GetLastFrameSurfacePos(surfaceNode.GetId());
2878     RectI currentFrameSurfacePos = curDisplayNode_->GetCurrentFrameSurfacePos(surfaceNode.GetId());
2879     if (surfaceNode.GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
2880         RS_LOGD("CheckMergeDisplayDirtyByPosChanged global merge surface pos changed "
2881             "%{public}s: global dirty %{public}s, lastFrameRect %{public}s currentFrameRect %{public}s",
2882             surfaceNode.GetName().c_str(),
2883             curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2884             lastFrameSurfacePos.ToString().c_str(), currentFrameSurfacePos.ToString().c_str());
2885         if (!lastFrameSurfacePos.IsEmpty()) {
2886             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
2887         }
2888         if (!currentFrameSurfacePos.IsEmpty()) {
2889             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(currentFrameSurfacePos);
2890         }
2891     }
2892 }
2893 
CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode & surfaceNode) const2894 void RSUniRenderVisitor::CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode& surfaceNode) const
2895 {
2896     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2897     auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2898     bool isShadowDisappear = !surfaceNode.GetRenderProperties().IsShadowValid() &&
2899         surfaceNode.IsShadowValidLastFrame();
2900     if (surfaceNode.GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2901         RectI shadowDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2902         // There are two situation here:
2903         // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2904         // dirtyRect == surfaceNode.GetOldDirtyInSurface()
2905         // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2906         // dirtyRect > surfaceNode.GetOldDirtyInSurface()
2907         // So we should always merge dirtyRect here.
2908         if (!shadowDirtyRect.IsEmpty()) {
2909             RS_LOGD("CheckMergeDisplayDirtyByShadowChanged global merge ShadowValid %{public}s: "
2910                 "global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2911                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2912                 dirtyRect.ToString().c_str());
2913             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRect);
2914         }
2915         if (isShadowDisappear) {
2916             surfaceNode.SetShadowValidLastFrame(false);
2917         }
2918     }
2919 }
2920 
CheckMergeDisplayDirtyBySurfaceChanged() const2921 void RSUniRenderVisitor::CheckMergeDisplayDirtyBySurfaceChanged() const
2922 {
2923     std::vector<RectI> surfaceChangedRects = curDisplayNode_->GetSurfaceChangedRects();
2924     for (auto& surfaceChangedRect : surfaceChangedRects) {
2925         if (!surfaceChangedRect.IsEmpty()) {
2926             RS_LOGD("CheckMergeDisplayDirtyBySurfaceChanged global merge Surface closed, global dirty %{public}s,"
2927                 "add rect %{public}s",
2928                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2929                 surfaceChangedRect.ToString().c_str());
2930             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(surfaceChangedRect);
2931         }
2932     }
2933 }
2934 
CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2935 void RSUniRenderVisitor::CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2936 {
2937     if (surfaceNode->GetDirtyManager() == nullptr || curDisplayNode_->GetDirtyManager() == nullptr) {
2938         return;
2939     }
2940     // 1 Handles the case of transparent surface, merge transparent dirty rect
2941     CheckMergeDisplayDirtyByTransparent(*surfaceNode);
2942     // 2 Zorder changed case, merge surface dest Rect
2943     CheckMergeDisplayDirtyByZorderChanged(*surfaceNode);
2944     // 3 surfacePos chanded case, merge surface lastframe pos or curframe pos
2945     CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2946     // 4 shadow disappear and appear case.
2947     CheckMergeDisplayDirtyByShadowChanged(*surfaceNode);
2948     // 5 handle last and curframe surfaces which appear or disappear case
2949     CheckMergeDisplayDirtyBySurfaceChanged();
2950     // More: any other display dirty caused by surfaceNode should be added here like CheckMergeDisplayDirtByXXX
2951 }
2952 
CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode & surfaceNode) const2953 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode& surfaceNode) const
2954 {
2955     const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2956     if (surfaceNode.HasContainerWindow()) {
2957         // If a surface's dirty is intersect with container region (which can be considered transparent)
2958         // should be added to display dirty region.
2959         // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2960         auto containerRegion = surfaceNode.GetContainerRegion();
2961         auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2962         auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2963         if (!containerDirtyRegion.IsEmpty()) {
2964             RS_LOGD("CheckMergeDisplayDirtyByContainer global merge containerDirtyRegion "
2965                 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2966                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2967                 containerDirtyRegion.GetRegionInfo().c_str());
2968             // plan: we can use surfacenode's absrect as containerRegion's bound
2969             const auto& rect = containerRegion.GetBoundRef();
2970             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(
2971                 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2972         }
2973     } else {
2974         // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2975         // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
2976         // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2977         // which include transparent region but not counted in display dirtyregion)
2978         if (!surfaceNode.IsNodeDirty()) {
2979             return;
2980         }
2981         auto transparentRegion = surfaceNode.GetTransparentRegion();
2982         auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2983         Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
2984         if (!transparentDirtyRegion.IsEmpty()) {
2985             RS_LOGD("CheckMergeDisplayDirtyByTransparentRegions global merge TransparentDirtyRegion "
2986                 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2987                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2988                 transparentDirtyRegion.GetRegionInfo().c_str());
2989             const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
2990             for (const auto& rect : rects) {
2991                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(RectI{ rect.left_, rect.top_,
2992                     rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2993             }
2994         }
2995     }
2996 }
2997 
IfSkipInCalcGlobalDirty(RSSurfaceRenderNode & surfaceNode) const2998 bool RSUniRenderVisitor::IfSkipInCalcGlobalDirty(RSSurfaceRenderNode& surfaceNode) const
2999 {
3000     return hasMirrorDisplay_ ?
3001         surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
3002 }
3003 
CheckMergeDisplayDirtyByTransparentFilter(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedDirtyRegion)3004 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter(
3005     std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
3006     Occlusion::Region& accumulatedDirtyRegion)
3007 {
3008     auto disappearedSurfaceRegionBelowCurrent =
3009         curDisplayNode_->GetDisappearedSurfaceRegionBelowCurrent(surfaceNode->GetId());
3010     accumulatedDirtyRegion.OrSelf(disappearedSurfaceRegionBelowCurrent);
3011     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3012     auto filterVecIter = transparentCleanFilter_.find(surfaceNode->GetId());
3013     if (filterVecIter != transparentCleanFilter_.end()) {
3014         RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter surface:%{public}s "
3015             "has transparentCleanFilter", surfaceNode->GetName().c_str());
3016         // check accumulatedDirtyRegion influence filter nodes which in the current surface
3017         for (auto it = filterVecIter->second.begin(); it != filterVecIter->second.end(); ++it) {
3018             auto filterNode = nodeMap.GetRenderNode(it->first);
3019             if (filterNode == nullptr) {
3020                 continue;
3021             }
3022             auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
3023             auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
3024             if (!filterDirtyRegion.IsEmpty()) {
3025                 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3026                     // backgroundfilter affected by below dirty
3027                     filterNode->MarkFilterStatusChanged(false, false);
3028                 }
3029                 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter global merge filterRegion "
3030                     "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode->GetName().c_str(),
3031                     curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3032                     it->second.ToString().c_str());
3033                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
3034                 if (filterNode->GetRenderProperties().GetFilter()) {
3035                     // foregroundfilter affected by below dirty
3036                     filterNode->MarkFilterStatusChanged(true, false);
3037                 }
3038             } else {
3039                 globalFilter_.insert(*it);
3040             }
3041             filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
3042         }
3043     }
3044     auto surfaceDirtyRegion = Occlusion::Region{
3045         Occlusion::Rect{ surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion() } };
3046     accumulatedDirtyRegion.OrSelf(surfaceDirtyRegion);
3047 }
3048 
UpdateDisplayDirtyAndExtendVisibleRegion()3049 void RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion()
3050 {
3051     if (curDisplayNode_ == nullptr) {
3052         RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion curDisplayNode_ is nullptr");
3053         return;
3054     }
3055     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
3056     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3057     std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
3058         [this, &nodeMap](RSBaseRenderNode::SharedPtr& nodePtr) {
3059         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
3060         if (surfaceNode == nullptr) {
3061             RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion surfaceNode is nullptr");
3062             return;
3063         }
3064         if (!surfaceNode->IsMainWindowType()) {
3065             return;
3066         }
3067         Occlusion::Region extendRegion;
3068         if (!surfaceNode->GetVisibleRegion().IsEmpty()) {
3069             ProcessFilterNodeObscured(surfaceNode, extendRegion, nodeMap);
3070         }
3071         surfaceNode->UpdateExtendVisibleRegion(extendRegion);
3072     });
3073 }
3074 
ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & extendRegion,const RSRenderNodeMap & nodeMap)3075 void RSUniRenderVisitor::ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
3076     Occlusion::Region& extendRegion, const RSRenderNodeMap& nodeMap)
3077 {
3078     const auto& visibleFilterChild = surfaceNode->GetVisibleFilterChild();
3079     auto visibleRegion = surfaceNode->GetVisibleRegion();
3080     auto currentFrameDirtyRegion = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
3081     auto isTransparent = surfaceNode->IsTransparent();
3082     for (const auto& child : visibleFilterChild) {
3083         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3084         if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
3085             continue;
3086         }
3087         MarkBlurIntersectWithDRM(filterNode);
3088         auto filterRect = filterNode->GetOldDirtyInSurface();
3089         auto visibleRects = visibleRegion.GetRegionRectIs();
3090         auto iter = std::find_if(visibleRects.begin(), visibleRects.end(), [&filterRect](const auto& rect) {
3091             return filterRect.IsInsideOf(rect);
3092         });
3093         if (iter != visibleRects.end()) {
3094             continue;
3095         }
3096         if (!visibleRegion.IsIntersectWith(filterRect)) {
3097             continue;
3098         }
3099         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ filterRect } };
3100         extendRegion = extendRegion.Or(filterRegion);
3101         if (!isTransparent && filterRect.Intersect(currentFrameDirtyRegion)) {
3102             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(filterRect);
3103         }
3104     }
3105 }
3106 
UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const3107 void RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
3108 {
3109     if (surfaceNode == nullptr) {
3110         return;
3111     }
3112     if (surfaceNode->HasBlurFilter()) {
3113         surfaceNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
3114     }
3115     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3116     for (auto& child : surfaceNode->GetVisibleFilterChild()) {
3117         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3118         if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
3119             continue;
3120         }
3121         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode "
3122             "surfaceNode: %s, filterNode:[%lld], IsOccludedByFilterCache:%d", surfaceNode->GetName().c_str(),
3123             filterNode->GetId(), surfaceNode->IsOccludedByFilterCache());
3124         filterNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
3125     }
3126 }
3127 
CheckMergeGlobalFilterForDisplay(Occlusion::Region & accumulatedDirtyRegion)3128 void RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay(Occlusion::Region& accumulatedDirtyRegion)
3129 {
3130     // [planning] if not allowed containerNode filter, The following processing logic can be removed
3131     // Recursively traverses container nodes need filter
3132     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3133     for (auto it = containerFilter_.begin(); it != containerFilter_.end(); ++it) {
3134         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(it->first);
3135         if (filterNode == nullptr) {
3136             continue;
3137         }
3138         auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
3139         auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
3140         RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeGlobalFilterForDisplay::filternode:%" PRIu64
3141                                    ", filterRect:%s, dirtyRegion:%s",
3142             filterNode->GetId(), it->second.ToString().c_str(), accumulatedDirtyRegion.GetRegionInfo().c_str());
3143         if (!filterDirtyRegion.IsEmpty()) {
3144             RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
3145                 "global dirty %{public}s, add container filterRegion %{public}s",
3146                 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3147                 (it->second).ToString().c_str());
3148             if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3149                 filterNode->MarkFilterStatusChanged(false, false); // background filter affected by below dirty
3150             }
3151             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
3152             if (filterNode->GetRenderProperties().GetFilter()) {
3153                 filterNode->MarkFilterStatusChanged(true, false); // foreground filter affected by below dirty
3154             }
3155         } else {
3156             globalFilter_.insert(*it);
3157         }
3158         filterNode->UpdateFilterCacheWithSelfDirty();
3159         filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
3160     }
3161     UpdateDisplayDirtyAndExtendVisibleRegion();
3162     CheckMergeFilterDirtyByIntersectWithDirty(globalFilter_, true);
3163 }
3164 
CollectEffectInfo(RSRenderNode & node)3165 void RSUniRenderVisitor::CollectEffectInfo(RSRenderNode& node)
3166 {
3167     auto nodeParent = node.GetParent().lock();
3168     if (nodeParent == nullptr) {
3169         return;
3170     }
3171     if (node.GetRenderProperties().NeedFilter() || node.ChildHasVisibleFilter()) {
3172         nodeParent->SetChildHasVisibleFilter(true);
3173         nodeParent->UpdateVisibleFilterChild(node);
3174     }
3175     if (node.GetRenderProperties().GetUseEffect() || node.ChildHasVisibleEffect()) {
3176         nodeParent->SetChildHasVisibleEffect(true);
3177         nodeParent->UpdateVisibleEffectChild(node);
3178     }
3179     if (node.GetSharedTransitionParam() || node.ChildHasSharedTransition()) {
3180         nodeParent->SetChildHasSharedTransition(true);
3181     }
3182 }
3183 
PostPrepare(RSRenderNode & node,bool subTreeSkipped)3184 void RSUniRenderVisitor::PostPrepare(RSRenderNode& node, bool subTreeSkipped)
3185 {
3186     auto curDirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
3187     if (!curDirtyManager) {
3188         return;
3189     }
3190     auto isOccluded = curSurfaceNode_ ?
3191         curSurfaceNode_->IsMainWindowType() && curSurfaceNode_->GetVisibleRegion().IsEmpty() : false;
3192     if (subTreeSkipped && !isOccluded) {
3193         UpdateHwcNodeRectInSkippedSubTree(node);
3194         CheckFilterNodeInSkippedSubTreeNeedClearCache(node, *curDirtyManager);
3195         UpdateSubSurfaceNodeRectInSkippedSubTree(node);
3196     }
3197     if (node.GetRenderProperties().NeedFilter()) {
3198         UpdateHwcNodeEnableByFilterRect(
3199             curSurfaceNode_, node.GetOldDirtyInSurface(), NeedPrepareChindrenInReverseOrder(node));
3200         auto globalFilterRect = (node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren()) ?
3201             GetVisibleEffectDirty(node) : node.GetOldDirtyInSurface();
3202         node.CalVisibleFilterRect(prepareClipRect_);
3203         node.MarkClearFilterCacheIfEffectChildrenChanged();
3204         CollectFilterInfoAndUpdateDirty(node, *curDirtyManager, globalFilterRect);
3205         node.SetGlobalAlpha(curAlpha_);
3206     }
3207     CollectEffectInfo(node);
3208     node.MapAndUpdateChildrenRect();
3209     node.UpdateSubTreeInfo(prepareClipRect_);
3210     node.UpdateLocalDrawRect();
3211     node.UpdateAbsDrawRect();
3212     node.ResetChangeState();
3213     if (isDrawingCacheEnabled_) {
3214         node.UpdateDrawingCacheInfoAfterChildren();
3215     }
3216     if (auto nodeParent = node.GetParent().lock()) {
3217         nodeParent->UpdateChildUifirstSupportFlag(node.GetUifirstSupportFlag());
3218         nodeParent->OpincUpdateNodeSupportFlag(node.OpincGetNodeSupportFlag());
3219     }
3220     auto& stagingRenderParams = node.GetStagingRenderParams();
3221     if (stagingRenderParams != nullptr) {
3222         if (node.GetSharedTransitionParam() && node.GetRenderProperties().GetSandBox()) {
3223             stagingRenderParams->SetAlpha(curAlpha_);
3224         } else {
3225             stagingRenderParams->SetAlpha(node.GetRenderProperties().GetAlpha());
3226         }
3227     }
3228 
3229     // planning: only do this if node is dirty
3230     node.UpdateRenderParams();
3231 
3232     // add if node is dirty
3233     node.AddToPendingSyncList();
3234 }
3235 
MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const3236 void RSUniRenderVisitor::MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const
3237 {
3238     if (!RSSystemProperties::GetDrmMarkedFilterEnabled()) {
3239         return;
3240     }
3241     static std::vector<std::string> drmKeyWins = { "SCBVolumePanel", "SCBBannerNotification" };
3242     auto appWindowNodeId = node->GetInstanceRootNodeId();
3243     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3244     auto appWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
3245     if (appWindowNode == nullptr) {
3246         return;
3247     }
3248     for (const auto& win : drmKeyWins) {
3249         if (appWindowNode->GetName().find(win) != std::string::npos) {
3250             for (auto& drmNode : drmNodes_) {
3251                 auto drmNodePtr = drmNode.lock();
3252                 if (drmNodePtr && drmNodePtr->GetDstRect().Intersect(node->GetFilterRegion())) {
3253                     node->MarkBlurIntersectWithDRM(true, RSMainThread::Instance()->GetGlobalDarkColorMode());
3254                 }
3255             }
3256         }
3257     }
3258 }
3259 
CheckFilterNodeInSkippedSubTreeNeedClearCache(const RSRenderNode & rootNode,RSDirtyRegionManager & dirtyManager)3260 void RSUniRenderVisitor::CheckFilterNodeInSkippedSubTreeNeedClearCache(
3261     const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager)
3262 {
3263     bool rotationChanged = curDisplayNode_ ?
3264         curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
3265     bool rotationStatusChanged = curDisplayNode_ ?
3266         curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
3267     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3268     for (auto& child : rootNode.GetVisibleFilterChild()) {
3269         auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3270         if (filterNode == nullptr) {
3271             continue;
3272         }
3273         RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInSkippedSubTreeNeedClearCache node[%lld]", filterNode->GetId());
3274         if (auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode)) {
3275             UpdateRotationStatusForEffectNode(*effectNode);
3276         }
3277         filterNode->CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
3278         filterNode->MarkClearFilterCacheIfEffectChildrenChanged();
3279         if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3280             filterNode->UpdateFilterCacheWithBelowDirty(dirtyManager, false);
3281         }
3282         RectI filterRect;
3283         filterNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, prepareClipRect_);
3284         UpdateHwcNodeEnableByFilterRect(curSurfaceNode_, filterNode->GetOldDirtyInSurface());
3285         CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager, filterRect);
3286     }
3287 }
3288 
UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode & rootNode)3289 void RSUniRenderVisitor::UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3290 {
3291     if (RS_PROFILER_SHOULD_BLOCK_HWCNODE()) {
3292         return;
3293     }
3294 
3295     if (!curSurfaceNode_) {
3296         return;
3297     }
3298     const auto& hwcNodes = curSurfaceNode_->GetChildHardwareEnabledNodes();
3299     if (hwcNodes.empty()) {
3300         return;
3301     }
3302     for (auto hwcNode : hwcNodes) {
3303         auto hwcNodePtr = hwcNode.lock();
3304         if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree() || hwcNodePtr->GetCalcRectInPrepare()) {
3305             continue;
3306         }
3307         const auto& property = hwcNodePtr->GetRenderProperties();
3308         auto geoPtr = property.GetBoundsGeometry();
3309         if (geoPtr == nullptr) {
3310             return;
3311         }
3312         auto matrix = geoPtr->GetMatrix();
3313         auto parent = hwcNodePtr->GetParent().lock();
3314         bool findInRoot = parent ? parent->GetId() == rootNode.GetId() : false;
3315         while (parent && parent->GetType() != RSRenderNodeType::DISPLAY_NODE) {
3316             if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
3317                 matrix.PostConcat(opt.value());
3318             } else {
3319                 break;
3320             }
3321             parent = parent->GetParent().lock();
3322             if (!parent) {
3323                 break;
3324             }
3325             findInRoot = parent->GetId() == rootNode.GetId() ? true : findInRoot;
3326         }
3327         if (!findInRoot) {
3328             continue;
3329         }
3330         if (parent) {
3331             const auto& parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
3332             if (parentGeoPtr) {
3333                 matrix.PostConcat(parentGeoPtr->GetMatrix());
3334             }
3335         }
3336         auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
3337         const auto& properties = hwcNodePtr->GetRenderProperties();
3338         Drawing::Rect bounds = Drawing::Rect(0, 0, properties.GetBoundsWidth(), properties.GetBoundsHeight());
3339         Drawing::Rect absRect;
3340         matrix.MapRect(absRect, bounds);
3341         RectI rect = {std::round(absRect.left_), std::round(absRect.top_),
3342             std::round(absRect.GetWidth()), std::round(absRect.GetHeight())};
3343         UpdateDstRect(*hwcNodePtr, rect, prepareClipRect_);
3344         UpdateSrcRect(*hwcNodePtr, matrix, rect);
3345         UpdateHwcNodeByTransform(*hwcNodePtr);
3346         UpdateHwcNodeEnableBySrcRect(*hwcNodePtr);
3347         UpdateHwcNodeEnableByBufferSize(*hwcNodePtr);
3348         hwcNodePtr->SetTotalMatrix(matrix);
3349     }
3350 }
3351 
UpdateHardwareStateByHwcNodeBackgroundAlpha(const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & hwcNodes)3352 void RSUniRenderVisitor::UpdateHardwareStateByHwcNodeBackgroundAlpha(
3353     const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes)
3354 {
3355     std::list<RectI> hwcRects;
3356     for (size_t i = 0; i < hwcNodes.size(); i++) {
3357         auto hwcNodePtr = hwcNodes[i].lock();
3358         if (!hwcNodePtr) {
3359             continue;
3360         }
3361         if (!hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled()) {
3362             hwcRects.push_back(hwcNodePtr->GetDstRect());
3363         } else if (hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled() &&
3364             hwcRects.size() != 0 && IsNodeAboveInsideOfNodeBelow(hwcNodePtr->GetDstRect(), hwcRects)) {
3365             continue;
3366         } else {
3367             hwcNodePtr->SetHardwareForcedDisabledState(true);
3368         }
3369     }
3370 }
3371 
IsNodeAboveInsideOfNodeBelow(const RectI & rectAbove,std::list<RectI> & hwcNodeRectList)3372 bool RSUniRenderVisitor::IsNodeAboveInsideOfNodeBelow(const RectI& rectAbove, std::list<RectI>& hwcNodeRectList)
3373 {
3374     for (auto rectBelow: hwcNodeRectList) {
3375         if (rectAbove.IsInsideOf(rectBelow)) {
3376             return true;
3377         }
3378     }
3379     return false;
3380 }
3381 
CalcHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode> & node,const RectI & filterRect,bool isReverseOrder)3382 void RSUniRenderVisitor::CalcHwcNodeEnableByFilterRect(
3383     std::shared_ptr<RSSurfaceRenderNode>& node, const RectI& filterRect, bool isReverseOrder)
3384 {
3385     if (!node) {
3386         return;
3387     }
3388     auto dstRect = node->GetDstRect();
3389     bool isIntersect = !dstRect.IntersectRect(filterRect).IsEmpty();
3390     if (isIntersect) {
3391         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by filter rect",
3392             node->GetName().c_str(), node->GetId());
3393         node->SetHardwareForcedDisabledState(true);
3394         node->SetHardWareDisabledByReverse(isReverseOrder);
3395         hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
3396             HwcDisabledReasons::DISABLED_BY_FLITER_RECT, node->GetName());
3397     }
3398 }
3399 
UpdateHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode> & node,const RectI & filterRect,bool isReverseOrder)3400 void RSUniRenderVisitor::UpdateHwcNodeEnableByFilterRect(
3401     std::shared_ptr<RSSurfaceRenderNode>& node, const RectI& filterRect, bool isReverseOrder)
3402 {
3403     if (filterRect.IsEmpty()) {
3404         return;
3405     }
3406     if (!node) {
3407         const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
3408         if (selfDrawingNodes.empty()) {
3409             return;
3410         }
3411         for (auto hwcNode : selfDrawingNodes) {
3412             CalcHwcNodeEnableByFilterRect(hwcNode, filterRect, isReverseOrder);
3413         }
3414     } else {
3415         const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
3416         if (hwcNodes.empty()) {
3417             return;
3418         }
3419         for (auto hwcNode : hwcNodes) {
3420             auto hwcNodePtr = hwcNode.lock();
3421             CalcHwcNodeEnableByFilterRect(hwcNodePtr, filterRect, isReverseOrder);
3422         }
3423     }
3424 }
3425 
UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode> & node)3426 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode>& node)
3427 {
3428     auto cleanFilter = transparentCleanFilter_.find(node->GetId());
3429     bool cleanFilterFound = (cleanFilter != transparentCleanFilter_.end());
3430     auto dirtyFilter = transparentDirtyFilter_.find(node->GetId());
3431     bool dirtyFilterFound = (dirtyFilter != transparentDirtyFilter_.end());
3432     auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
3433     for (auto it = curMainAndLeashSurfaces.rbegin(); it != curMainAndLeashSurfaces.rend(); ++it) {
3434         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
3435         if (surfaceNode == nullptr) {
3436             continue;
3437         }
3438         if (surfaceNode->GetId() == node->GetId()) {
3439             return;
3440         }
3441         const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
3442         if (hwcNodes.empty()) {
3443             continue;
3444         }
3445         for (auto hwcNode : hwcNodes) {
3446             auto hwcNodePtr = hwcNode.lock();
3447             if (!hwcNodePtr || hwcNodePtr->IsHardwareForcedDisabled()) {
3448                 continue;
3449             }
3450             if (cleanFilterFound) {
3451                 UpdateHwcNodeEnableByGlobalCleanFilter(cleanFilter->second, *hwcNodePtr);
3452                 if (hwcNodePtr->IsHardwareForcedDisabled()) {
3453                     ProcessAncoNode(hwcNodePtr);
3454                     continue;
3455                 }
3456             }
3457             if (!dirtyFilterFound) {
3458                 continue;
3459             }
3460             for (auto filter = dirtyFilter->second.begin(); filter != dirtyFilter->second.end(); ++filter) {
3461                 if (hwcNodePtr->GetDstRect().Intersect(filter->second)) {
3462                     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentDirtyFilter",
3463                         hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
3464                     hwcNodePtr->SetHardwareForcedDisabledState(true);
3465                     ProcessAncoNode(hwcNodePtr);
3466                     hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
3467                         HwcDisabledReasons::DISABLED_BY_TRANSPARENT_DIRTY_FLITER, hwcNodePtr->GetName());
3468                     break;
3469                 }
3470             }
3471         }
3472     }
3473 }
3474 
UpdateHwcNodeEnableByGlobalCleanFilter(const std::vector<std::pair<NodeId,RectI>> & cleanFilter,RSSurfaceRenderNode & hwcNodePtr)3475 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalCleanFilter(
3476     const std::vector<std::pair<NodeId, RectI>>& cleanFilter, RSSurfaceRenderNode& hwcNodePtr)
3477 {
3478     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3479     for (auto filter = cleanFilter.begin(); filter != cleanFilter.end(); ++filter) {
3480         if (hwcNodePtr.GetDstRect().Intersect(filter->second)) {
3481             auto& rendernode = nodeMap.GetRenderNode<RSRenderNode>(filter->first);
3482             if (rendernode == nullptr) {
3483                 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: rendernode is null");
3484                 continue;
3485             }
3486 
3487             if (rendernode->IsAIBarFilterCacheValid()) {
3488                 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: skip intersection for using cache");
3489                 continue;
3490             }
3491             RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentCleanFilter",
3492                 hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId());
3493             hwcNodePtr.SetHardwareForcedDisabledState(true);
3494             hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr.GetId(),
3495                 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_CLEAN_FLITER, hwcNodePtr.GetName());
3496             break;
3497         }
3498     }
3499 }
3500 
ResetSubSurfaceNodesCalState(std::vector<std::pair<NodeId,std::weak_ptr<RSSurfaceRenderNode>>> & subSurfaceNodes)3501 inline static void ResetSubSurfaceNodesCalState(
3502     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>>& subSurfaceNodes)
3503 {
3504     for (auto& [id, node] : subSurfaceNodes) {
3505         auto subSurfaceNodePtr = node.lock();
3506         if (!subSurfaceNodePtr) {
3507             continue;
3508         }
3509         subSurfaceNodePtr->SetCalcRectInPrepare(false);
3510     }
3511 }
3512 
UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode & rootNode)3513 void RSUniRenderVisitor::UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3514 {
3515     if (!curSurfaceNode_) {
3516         return;
3517     }
3518     auto rootGeo = rootNode.GetRenderProperties().GetBoundsGeometry();
3519     if (!rootGeo) {
3520         return;
3521     }
3522 
3523     std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
3524     curSurfaceNode_->GetAllSubSurfaceNodes(allSubSurfaceNodes);
3525     for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
3526         auto subSurfaceNodePtr = subSurfaceNode.lock();
3527         Drawing::Matrix absMatrix;
3528         if (!subSurfaceNodePtr || subSurfaceNodePtr->GetCalcRectInPrepare() ||
3529             !subSurfaceNodePtr->GetAbsMatrixReverse(rootNode, absMatrix)) {
3530             continue;
3531         }
3532 
3533         Drawing::RectF absDrawRect;
3534         absMatrix.MapRect(absDrawRect, RSPropertiesPainter::Rect2DrawingRect(subSurfaceNodePtr->GetSelfDrawRect()));
3535         RectI subSurfaceRect = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
3536             absDrawRect.GetWidth(), absDrawRect.GetHeight());
3537 
3538         subSurfaceNodePtr->SetOldDirtyInSurface(subSurfaceRect.IntersectRect(prepareClipRect_));
3539         UpdateNodeVisibleRegion(*subSurfaceNodePtr);
3540         UpdateDstRect(*subSurfaceNodePtr, subSurfaceRect, prepareClipRect_);
3541         subSurfaceNodePtr->SetCalcRectInPrepare(true);
3542         if (subSurfaceNodePtr->IsLeashOrMainWindow()) {
3543             curMainAndLeashWindowNodesIds_.push(subSurfaceNodePtr->GetId());
3544             curDisplayNode_->RecordMainAndLeashSurfaces(subSurfaceNodePtr);
3545             CollectOcclusionInfoForWMS(*subSurfaceNodePtr);
3546         }
3547     }
3548     ResetSubSurfaceNodesCalState(allSubSurfaceNodes);
3549 }
3550 
GetVisibleEffectDirty(RSRenderNode & node) const3551 RectI RSUniRenderVisitor::GetVisibleEffectDirty(RSRenderNode& node) const
3552 {
3553     RectI childEffectRect;
3554     auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3555     for (auto& nodeId : node.GetVisibleEffectChild()) {
3556         if (auto& subnode = nodeMap.GetRenderNode<RSRenderNode>(nodeId)) {
3557             childEffectRect = childEffectRect.JoinRect(subnode->GetOldDirtyInSurface());
3558         }
3559     }
3560     return childEffectRect;
3561 }
3562 
CollectFilterInfoAndUpdateDirty(RSRenderNode & node,RSDirtyRegionManager & dirtyManager,const RectI & globalFilterRect)3563 void RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty(RSRenderNode& node,
3564     RSDirtyRegionManager& dirtyManager, const RectI& globalFilterRect)
3565 {
3566     bool isNodeAddedToTransparentCleanFilters = false;
3567     if (curSurfaceNode_) {
3568         bool isIntersect = dirtyManager.GetCurrentFrameDirtyRegion().Intersect(globalFilterRect);
3569         if (isIntersect) {
3570             dirtyManager.MergeDirtyRect(globalFilterRect);
3571         } else {
3572             curSurfaceNoBelowDirtyFilter_.insert({node.GetId(), globalFilterRect});
3573         }
3574         if (node.GetRenderProperties().GetFilter()) {
3575             node.UpdateFilterCacheWithBelowDirty(dirtyManager, true);
3576         }
3577         node.UpdateFilterCacheWithSelfDirty();
3578         if (curSurfaceNode_->IsTransparent()) {
3579             globalFilterRects_.emplace_back(globalFilterRect);
3580             if (!isIntersect || (isIntersect && node.GetRenderProperties().GetBackgroundFilter() &&
3581                 !node.IsBackgroundInAppOrNodeSelfDirty())) {
3582                 // record nodes which has transparent clean filter
3583                 RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInfoAndUpdateDirty::surfaceNode:%s, add node[%lld] to "
3584                     "transparentCleanFilter", curSurfaceNode_->GetName().c_str(), node.GetId());
3585                 transparentCleanFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalFilterRect});
3586                 isNodeAddedToTransparentCleanFilters = true;
3587             }
3588             if (isIntersect) {
3589                 transparentDirtyFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalFilterRect});
3590                 RS_LOGD("RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty global merge transparentDirtyFilter "
3591                     "%{public}s, global dirty %{public}s, add rect %{public}s", curSurfaceNode_->GetName().c_str(),
3592                     curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
3593                     globalFilterRect.ToString().c_str());
3594                 curDisplayDirtyManager_->MergeDirtyRect(globalFilterRect);
3595             }
3596         } else {
3597             // record surface nodes and nodes in surface which has clean filter
3598             globalFilter_.insert({node.GetId(), globalFilterRect});
3599         }
3600     } else {
3601         globalFilterRects_.emplace_back(globalFilterRect);
3602         // record container nodes which need filter
3603         containerFilter_.insert({node.GetId(), globalFilterRect});
3604     }
3605     if (curSurfaceNode_ && !isNodeAddedToTransparentCleanFilters) {
3606         node.PostPrepareForBlurFilterNode(dirtyManager, needRequestNextVsync_);
3607     }
3608 }
3609 
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)3610 void RSUniRenderVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
3611 {
3612     auto nodeId = node.GetId();
3613     RS_OPTIONAL_TRACE_NAME("RSUniRender::Prepare:[" + node.GetName() + "] nodeid: " +
3614         std::to_string(nodeId) +  " pid: " + std::to_string(ExtractPid(nodeId)) +
3615         ", nodeType " + std::to_string(static_cast<uint>(node.GetSurfaceNodeType())));
3616     if (curDisplayNode_ == nullptr) {
3617         ROSEN_LOGE("RSUniRenderVisitor::PrepareSurfaceRenderNode, curDisplayNode_ is nullptr.");
3618         return;
3619     }
3620     // avoid EntryView upload texture while screen rotation
3621     if (node.GetName() == "EntryView") {
3622         node.SetStaticCached(curDisplayNode_->IsRotationChanged());
3623     }
3624     node.UpdatePositionZ();
3625     if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
3626         hasCaptureWindow_[currentVisitDisplay_] = true;
3627         node.SetContentDirty(); // screen recording capsule force mark dirty
3628     }
3629 
3630     node.SetAncestorDisplayNode(curDisplayNode_);
3631     node.UpdateAncestorDisplayNodeInRenderParams();
3632     CheckColorSpace(node);
3633     CheckPixelFormat(node);
3634     // only need collect first level node's security & skip layer info
3635     if (nodeId == node.GetFirstLevelNodeId()) {
3636         UpdateSecuritySkipAndProtectedLayersRecord(node);
3637     }
3638     // stop traversal if node keeps static
3639     if (isQuickSkipPreparationEnabled_ && CheckIfSurfaceRenderNodeStatic(node)) {
3640         // node type is mainwindow.
3641         PrepareSubSurfaceNodes(node);
3642         return;
3643     }
3644     // Attension: Updateinfo before info reset
3645     node.StoreMustRenewedInfo();
3646     SetHasSharedTransitionNode(node, false);
3647     node.CleanDstRectChanged();
3648     if (node.IsHardwareEnabledTopSurface()) {
3649         node.ResetSubNodeShouldPaint();
3650         node.ResetChildHardwareEnabledNodes();
3651     }
3652     curContentDirty_ = node.IsContentDirty();
3653     bool dirtyFlag = dirtyFlag_;
3654 
3655     RectI prepareClipRect = prepareClipRect_;
3656     bool isQuickSkipPreparationEnabled = isQuickSkipPreparationEnabled_;
3657 
3658     // update geoptr with ContextMatrix
3659     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3660     auto& property = node.GetMutableRenderProperties();
3661     auto& geoPtr = (property.GetBoundsGeometry());
3662     if (geoPtr == nullptr) {
3663         return;
3664     }
3665     // before node update, prepare node's setting by types
3666     PrepareTypesOfSurfaceRenderNodeBeforeUpdate(node);
3667 
3668     if (curSurfaceDirtyManager_ == nullptr) {
3669         RS_LOGE("RSUniRenderVisitor::PrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
3670             node.GetName().c_str());
3671         return;
3672     }
3673 
3674     if (node.GetRSSurfaceHandler()->GetBuffer() != nullptr) {
3675         node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
3676     }
3677 
3678     auto skipNodeMap = RSMainThread::Instance()->GetCacheCmdSkippedNodes();
3679     // Update node properties, including position (dstrect), OldDirty()
3680     auto parentNode = node.GetParent().lock();
3681     auto rsParent = (parentNode);
3682     if (skipNodeMap.count(nodeId) != 0) {
3683         dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent, dirtyFlag_, prepareClipRect_);
3684         dirtyFlag_ = dirtyFlag;
3685         RS_TRACE_NAME(node.GetName() + " PreparedNodes cacheCmdSkiped");
3686         return;
3687     }
3688 
3689     auto rsSurfaceParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentNode);
3690     if (node.IsAppWindow() && rsSurfaceParent && rsSurfaceParent->IsLeashWindow()
3691         && rsSurfaceParent->GetDstRect().IsEmpty()) {
3692             prepareClipRect_ = RectI {0, 0, 0, 0};
3693     }
3694     dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent, dirtyFlag_, prepareClipRect_);
3695 
3696     // Calculate the absolute destination rectangle of the node, initialize with absolute bounds rect
3697     auto dstRect = geoPtr->GetAbsRect();
3698     // If the screen is expanded, intersect the destination rectangle with the screen rectangle
3699     dstRect = dstRect.IntersectRect(RectI(curDisplayNode_->GetDisplayOffsetX(), curDisplayNode_->GetDisplayOffsetY(),
3700         screenInfo_.width, screenInfo_.height));
3701     // Remove the offset of the screen
3702     dstRect = RectI(dstRect.left_ - curDisplayNode_->GetDisplayOffsetX(),
3703         dstRect.top_ - curDisplayNode_->GetDisplayOffsetY(), dstRect.GetWidth(), dstRect.GetHeight());
3704     // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
3705     if (node.IsHardwareEnabledType()) {
3706         dstRect = dstRect.IntersectRect(prepareClipRect_);
3707     }
3708     // Set the destination rectangle of the node
3709     node.SetDstRect(dstRect);
3710 
3711     if (node.IsLeashOrMainWindow()) {
3712         // record visible node position for display render node dirtyManager
3713         if (node.ShouldPaint()) {
3714             curDisplayNode_->UpdateSurfaceNodePos(nodeId, node.GetOldDirty());
3715         }
3716 
3717         if (node.IsAppWindow()) {
3718             // if update appwindow, its children should not skip
3719             localZOrder_ = 0.0f;
3720             isQuickSkipPreparationEnabled_ = false;
3721             if (isSubSurfaceEnabled_) {
3722                 isQuickSkipPreparationEnabled_ = true;
3723             }
3724             node.ResetChildHardwareEnabledNodes();
3725             boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
3726             frameGravity_ = property.GetFrameGravity();
3727         }
3728     }
3729 
3730     // [planning] Remove this after skia is upgraded, the clipRegion is supported
3731     // reset childrenFilterRects
3732     node.ResetChildrenFilterRects();
3733 
3734     dirtyFlag_ = dirtyFlag_ || node.GetDstRectChanged();
3735     parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3736     if (RSUniRenderUtil::GetRotationDegreeFromMatrix(parentSurfaceNodeMatrix_) % RS_ROTATION_90 != 0) {
3737         isSurfaceRotationChanged_ = true;
3738         doAnimate_ = true;
3739         node.SetAnimateState();
3740     }
3741 
3742     bool isSubNodeOfSurfaceInPrepare = isSubNodeOfSurfaceInPrepare_;
3743     if (node.IsLeashOrMainWindow()) {
3744         isSubNodeOfSurfaceInPrepare_ = true;
3745     }
3746     node.UpdateChildrenOutOfRectFlag(false);
3747     // [planning] ShouldPrepareSubnodes would be applied again if condition constraint ensures
3748     PrepareChildren(node);
3749     node.UpdateParentChildrenRect(rsParent);
3750 
3751     // restore flags
3752     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3753     dirtyFlag_ = dirtyFlag;
3754     isQuickSkipPreparationEnabled_ = isQuickSkipPreparationEnabled;
3755     prepareClipRect_ = prepareClipRect;
3756     if (node.IsLeashOrMainWindow()) {
3757         isSubNodeOfSurfaceInPrepare_ = isSubNodeOfSurfaceInPrepare;
3758     }
3759 
3760     PrepareTypesOfSurfaceRenderNodeAfterUpdate(node);
3761     if (node.GetDstRectChanged() || (node.GetDirtyManager() && node.GetDirtyManager()->IsCurrentFrameDirty())) {
3762         curDisplayNode_->GetDirtySurfaceNodeMap().emplace(nodeId, node.ReinterpretCastTo<RSSurfaceRenderNode>());
3763     }
3764     UpdateSurfaceRenderNodeScale(node);
3765     // Due to the alpha is updated in PrepareChildren, so PrepareChildren
3766     // needs to be done before CheckOpaqueRegionBaseInfo
3767     auto screenRotation = curDisplayNode_->GetRotation();
3768     auto screenRect = RectI(0, 0, screenInfo_.width, screenInfo_.height);
3769     Vector4f cornerRadius;
3770     Vector4f::Max(node.GetWindowCornerRadius(), node.GetGlobalCornerRadius(), cornerRadius);
3771     Vector4<int> dstCornerRadius(static_cast<int>(std::round(cornerRadius.x_)),
3772                                  static_cast<int>(std::round(cornerRadius.y_)),
3773                                  static_cast<int>(std::round(cornerRadius.z_)),
3774                                  static_cast<int>(std::round(cornerRadius.w_)));
3775     auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
3776     auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
3777         (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
3778     auto absRect = node.GetDstRect().IntersectRect(node.GetOldDirtyInSurface());
3779     if (!node.CheckOpaqueRegionBaseInfo(
3780         screenRect, absRect, screenRotation, isFocused, dstCornerRadius)
3781         && node.GetSurfaceNodeType() != RSSurfaceNodeType::SELF_DRAWING_NODE) {
3782         node.ResetSurfaceOpaqueRegion(screenRect, absRect, screenRotation, isFocused, dstCornerRadius);
3783     }
3784     node.SetOpaqueRegionBaseInfo(screenRect, absRect, screenRotation, isFocused, dstCornerRadius);
3785     if (node.IsMainWindowType()) {
3786         // Attention: curSurface info would be reset as upper surfaceParent if it has
3787         ResetCurSurfaceInfoAsUpperSurfaceParent(node);
3788     }
3789 }
3790 
UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode & node)3791 void RSUniRenderVisitor::UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode& node)
3792 {
3793     if (!node.IsLeashWindow()) {
3794         return;
3795     }
3796     auto& property = node.GetMutableRenderProperties();
3797     auto& geoPtr = (property.GetBoundsGeometry());
3798     if (geoPtr == nullptr) {
3799         return;
3800     }
3801     auto absMatrix = geoPtr->GetAbsMatrix();
3802     bool isScale = false;
3803     if (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) {
3804         isScale = (!ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_X), 1.f, EPSILON_SCALE) ||
3805             !ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_Y), 1.f, EPSILON_SCALE));
3806     } else {
3807         bool getMinMaxScales = false;
3808         // scaleFactors[0]-minimum scaling factor, scaleFactors[1]-maximum scaling factor
3809         Drawing::scalar scaleFactors[2];
3810         getMinMaxScales = absMatrix.GetMinMaxScales(scaleFactors);
3811         if (getMinMaxScales) {
3812             isScale = !ROSEN_EQ(scaleFactors[0], 1.f, EPSILON_SCALE) || !ROSEN_EQ(scaleFactors[1], 1.f, EPSILON_SCALE);
3813         }
3814         if (!getMinMaxScales) {
3815             RS_LOGD("getMinMaxScales fail, node:%{public}s %{public}" PRIu64 "", node.GetName().c_str(), node.GetId());
3816             const auto& dstRect = node.GetDstRect();
3817             float dstRectWidth = dstRect.GetWidth();
3818             float dstRectHeight = dstRect.GetHeight();
3819             float boundsWidth = property.GetBoundsWidth();
3820             float boundsHeight = property.GetBoundsHeight();
3821             isScale =
3822                 !ROSEN_EQ(std::min(dstRectWidth, dstRectHeight), std::min(boundsWidth, boundsHeight), EPSILON_SCALE) ||
3823                 !ROSEN_EQ(std::max(dstRectWidth, dstRectHeight), std::max(boundsWidth, boundsHeight), EPSILON_SCALE);
3824         }
3825     }
3826     node.SetIsScaleInPreFrame(node.IsScale());
3827     node.SetIsScale(isScale);
3828 }
3829 
PrepareProxyRenderNode(RSProxyRenderNode & node)3830 void RSUniRenderVisitor::PrepareProxyRenderNode(RSProxyRenderNode& node)
3831 {
3832     // alpha is not affected by dirty flag, always update
3833     node.SetContextAlpha(curAlpha_);
3834     // skip matrix & clipRegion update if not dirty
3835     if (!dirtyFlag_) {
3836         return;
3837     }
3838     auto rsParent = (node.GetParent().lock());
3839     if (rsParent == nullptr) {
3840         return;
3841     }
3842     auto& property = rsParent->GetMutableRenderProperties();
3843     auto& geoPtr = (property.GetBoundsGeometry());
3844 
3845     // Context matrix should be relative to the parent surface node, so we need to revert the parentSurfaceNodeMatrix_.
3846     Drawing::Matrix invertMatrix;
3847     Drawing::Matrix contextMatrix = geoPtr->GetAbsMatrix();
3848 
3849     if (parentSurfaceNodeMatrix_.Invert(invertMatrix)) {
3850         contextMatrix.PreConcat(invertMatrix);
3851     } else {
3852         ROSEN_LOGE("RSUniRenderVisitor::PrepareProxyRenderNode, invert parentSurfaceNodeMatrix_ failed");
3853     }
3854     node.SetContextMatrix(contextMatrix);
3855 
3856     // For now, we only set the clipRegion if the parent node has ClipToBounds set to true.
3857     if (!property.GetClipToBounds()) {
3858         node.SetContextClipRegion(std::nullopt);
3859     } else {
3860         // Maybe we should use prepareClipRect_ and make the clipRegion in device coordinate, but it will be more
3861         // complex to calculate the intersect, and it will make app developers confused.
3862         auto rect = property.GetBoundsRect();
3863         // Context clip region is in the parent node coordinate, so we don't need to map it.
3864         node.SetContextClipRegion(Drawing::Rect(
3865             rect.GetLeft(), rect.GetTop(), rect.GetWidth() + rect.GetLeft(), rect.GetHeight() + rect.GetTop()));
3866     }
3867 
3868     // prepare children
3869     PrepareChildren(node);
3870 }
3871 
PrepareRootRenderNode(RSRootRenderNode & node)3872 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
3873 {
3874     RS_TRACE_NAME_FMT("RSUniRender::PrepareRootRenderNode:node[%" PRIu64 "] pid[%d] subTreeDirty[%d]",
3875         node.GetId(), ExtractPid(node.GetId()), node.IsSubTreeDirty());
3876     bool dirtyFlag = dirtyFlag_;
3877     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3878     auto prepareClipRect = prepareClipRect_;
3879 
3880     auto nodeParent = (node.GetParent().lock());
3881     const auto& property = node.GetRenderProperties();
3882     bool geoDirty = property.IsGeoDirty();
3883     auto& geoPtr = (property.GetBoundsGeometry());
3884     auto prevAlpha = curAlpha_;
3885     curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
3886 
3887     if (curSurfaceDirtyManager_ == nullptr) {
3888         RS_LOGE("RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
3889         return;
3890     }
3891 
3892     if (RSSystemProperties::GetQuickPrepareEnabled()) {
3893         dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
3894             *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
3895     } else {
3896         dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, nodeParent, dirtyFlag_, prepareClipRect_);
3897     }
3898 
3899     if (nodeParent == curSurfaceNode_) {
3900         const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
3901         const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
3902         Drawing::Matrix gravityMatrix;
3903         (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
3904             RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
3905             rootWidth, rootHeight, gravityMatrix);
3906         // Only Apply gravityMatrix when rootNode is dirty
3907         if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
3908             geoPtr->ConcatMatrix(gravityMatrix);
3909         }
3910     }
3911 
3912     if (geoPtr != nullptr) {
3913         parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3914     }
3915 
3916     if (RSSystemProperties::GetQuickPrepareEnabled()) {
3917         bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
3918         isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
3919             node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
3920         PostPrepare(node, !isSubTreeNeedPrepare);
3921     } else {
3922         node.UpdateChildrenOutOfRectFlag(false);
3923         PrepareChildren(node);
3924         node.UpdateParentChildrenRect(nodeParent);
3925     }
3926 
3927     curAlpha_ = prevAlpha;
3928     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3929     dirtyFlag_ = dirtyFlag;
3930     prepareClipRect_ = prepareClipRect;
3931 }
3932 
PrepareCanvasRenderNode(RSCanvasRenderNode & node)3933 void RSUniRenderVisitor::PrepareCanvasRenderNode(RSCanvasRenderNode &node)
3934 {
3935     preparedCanvasNodeInCurrentSurface_++;
3936     curContentDirty_ = node.IsContentDirty();
3937     bool dirtyFlag = dirtyFlag_;
3938     RectI prepareClipRect = prepareClipRect_;
3939 
3940     auto nodeParent = node.GetParent().lock();
3941     while (nodeParent && nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>() &&
3942         nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>()->GetSurfaceNodeType() ==
3943         RSSurfaceNodeType::SELF_DRAWING_NODE) {
3944         nodeParent = nodeParent->GetParent().lock();
3945     }
3946     if (LIKELY(nodeParent)) {
3947         node.SetIsAncestorDirty(nodeParent->IsDirty() || nodeParent->IsAncestorDirty());
3948         auto parentSurfaceNode = nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>();
3949         if (parentSurfaceNode && parentSurfaceNode->IsLeashWindow()) {
3950             node.SetParentLeashWindow();
3951         }
3952         if (parentSurfaceNode && parentSurfaceNode->IsScbScreen()) {
3953             node.SetParentScbScreen();
3954         }
3955     }
3956     if (curSurfaceDirtyManager_ == nullptr && curDisplayDirtyManager_ == nullptr) {
3957         RS_LOGE("RSUniRenderVisitor::PrepareCanvasRenderNode curXDirtyManager is nullptr");
3958         return;
3959     }
3960     if (node.GetSharedTransitionParam()) {
3961         node.GetMutableRenderProperties().UpdateSandBoxMatrix(parentSurfaceNodeMatrix_);
3962     }
3963     if (isSubNodeOfSurfaceInPrepare_ && curSurfaceNode_ &&
3964         curSurfaceNode_->IsHardwareEnabledTopSurface() && node.ShouldPaint()) {
3965         curSurfaceNode_->SetSubNodeShouldPaint();
3966     }
3967     // if canvasNode is not sub node of surfaceNode, merge the dirtyRegion to curDisplayDirtyManager_
3968     auto& dirtyManager = isSubNodeOfSurfaceInPrepare_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
3969     dirtyFlag_ = node.Update(*dirtyManager, nodeParent, dirtyFlag_, prepareClipRect_);
3970 
3971     const auto& property = node.GetRenderProperties();
3972     auto& geoPtr = (property.GetBoundsGeometry());
3973     if (geoPtr == nullptr) {
3974         return;
3975     }
3976     // Dirty Region use abstract coordinate, property of node use relative coordinate
3977     // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
3978     if (property.GetClipToBounds()) {
3979         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
3980     }
3981     // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
3982     if (property.GetClipToFrame()) {
3983         // MapAbsRect do not handle the translation of OffsetX and OffsetY
3984         RectF frameRect{
3985             property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
3986             property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
3987             property.GetFrameWidth(), property.GetFrameHeight()};
3988         prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
3989     }
3990 
3991     node.UpdateChildrenOutOfRectFlag(false);
3992 
3993     if (isSkipCanvasNodeOutOfScreen_ && !isSubNodeOfSurfaceInPrepare_ && !node.HasSubSurface() &&
3994         IsOutOfScreenRegion(geoPtr->GetAbsRect())) {
3995         return;
3996     }
3997 
3998     PrepareChildren(node);
3999     // attention: accumulate direct parent's childrenRect
4000     node.UpdateParentChildrenRect(nodeParent);
4001     if (property.GetUseEffect()) {
4002         if (auto directParent = node.GetParent().lock()) {
4003             directParent->SetChildHasVisibleEffect(true);
4004         }
4005     }
4006 
4007     node.UpdateEffectRegion(effectRegion_);
4008     if (property.NeedFilter()) {
4009         // filterRects_ is used in RSUniRenderVisitor::CalcDirtyFilterRegion
4010         // When oldDirtyRect of node with filter has intersect with any surfaceNode or displayNode dirtyRegion,
4011         // the whole oldDirtyRect should be render in this vsync.
4012         // Partial rendering of node with filter would cause display problem.
4013         if (auto directParent = node.GetParent().lock()) {
4014             directParent->SetChildHasVisibleFilter(true);
4015         }
4016         if (curSurfaceDirtyManager_ && curSurfaceDirtyManager_->IsTargetForDfx()) {
4017             curSurfaceDirtyManager_->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
4018                 DirtyRegionType::FILTER_RECT, node.GetOldDirtyInSurface());
4019         }
4020         if (curSurfaceNode_) {
4021             curSurfaceNode_->UpdateChildrenFilterRects(node.shared_from_this(), node.GetOldDirtyInSurface(),
4022                 node.IsFilterCacheValid());
4023             curSurfaceNode_->UpdateFilterNodes(node.shared_from_this());
4024         }
4025         UpdateForegroundFilterCacheWithDirty(node, *dirtyManager);
4026     }
4027     dirtyFlag_ = dirtyFlag;
4028     prepareClipRect_ = prepareClipRect;
4029 #ifdef RS_ENABLE_STACK_CULLING
4030     if (RSSystemProperties::GetViewOcclusionCullingEnabled()) {
4031         node.SetFullSurfaceOpaqueMarks(curSurfaceNode_);
4032     }
4033 #endif
4034 }
4035 
PrepareEffectRenderNode(RSEffectRenderNode & node)4036 void RSUniRenderVisitor::PrepareEffectRenderNode(RSEffectRenderNode& node)
4037 {
4038     bool dirtyFlag = dirtyFlag_;
4039     RectI prepareClipRect = prepareClipRect_;
4040     auto effectRegion = effectRegion_;
4041     effectRegion_ = node.InitializeEffectRegion();
4042 
4043     UpdateRotationStatusForEffectNode(node);
4044     auto parentNode = node.GetParent().lock();
4045     node.SetVisitedFilterCacheStatus(curSurfaceDirtyManager_->IsCacheableFilterRectEmpty());
4046     dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, parentNode, dirtyFlag_, prepareClipRect_);
4047 
4048     node.UpdateChildrenOutOfRectFlag(false);
4049     PrepareChildren(node);
4050     node.UpdateParentChildrenRect(node.GetParent().lock());
4051     node.SetEffectRegion(effectRegion_);
4052 
4053     if (node.GetRenderProperties().NeedFilter()) {
4054         // filterRects_ is used in RSUniRenderVisitor::CalcDirtyFilterRegion
4055         // When oldDirtyRect of node with filter has intersect with any surfaceNode or displayNode dirtyRegion,
4056         // the whole oldDirtyRect should be render in this vsync.
4057         // Partial rendering of node with filter would cause display problem.
4058         if (parentNode) {
4059             parentNode->SetChildHasVisibleFilter(true);
4060         }
4061         if (curSurfaceDirtyManager_->IsTargetForDfx()) {
4062             curSurfaceDirtyManager_->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
4063                 DirtyRegionType::FILTER_RECT, node.GetOldDirtyInSurface());
4064         }
4065         if (curSurfaceNode_ && effectRegion_.has_value() && !effectRegion_->IsEmpty()) {
4066             RectI filterRect(effectRegion_->GetLeft(), effectRegion_->GetTop(),
4067                 effectRegion_->GetWidth(), effectRegion_->GetHeight());
4068             curSurfaceNode_->UpdateChildrenFilterRects(node.shared_from_this(), filterRect,
4069                 node.IsFilterCacheValid());
4070             curSurfaceNode_->UpdateFilterNodes(node.shared_from_this());
4071         }
4072         UpdateForegroundFilterCacheWithDirty(node, *curSurfaceDirtyManager_);
4073     }
4074 
4075     effectRegion_ = effectRegion;
4076     dirtyFlag_ = dirtyFlag;
4077     prepareClipRect_ = prepareClipRect;
4078 }
4079 
DrawDirtyRectForDFX(const RectI & dirtyRect,const Drawing::Color color,const RSPaintStyle fillType,float alpha,int edgeWidth=6,std::string extra)4080 void RSUniRenderVisitor::DrawDirtyRectForDFX(const RectI& dirtyRect, const Drawing::Color color,
4081     const RSPaintStyle fillType, float alpha, int edgeWidth = 6, std::string extra)
4082 {
4083     if (dirtyRect.width_ <= 0 || dirtyRect.height_ <= 0) {
4084         ROSEN_LOGD("DrawDirtyRectForDFX dirty rect is invalid.");
4085         return;
4086     }
4087     ROSEN_LOGD("DrawDirtyRectForDFX current dirtyRect = %{public}s", dirtyRect.ToString().c_str());
4088     auto rect = Drawing::Rect(dirtyRect.left_, dirtyRect.top_,
4089         dirtyRect.left_ + dirtyRect.width_, dirtyRect.top_ + dirtyRect.height_);
4090     std::string position = std::to_string(dirtyRect.left_) + ',' + std::to_string(dirtyRect.top_) + ',' +
4091         std::to_string(dirtyRect.width_) + ',' + std::to_string(dirtyRect.height_) + extra;
4092     const int defaultTextOffsetX = edgeWidth;
4093     const int defaultTextOffsetY = 30; // text position has 30 pixelSize under the Rect
4094     Drawing::Pen rectPen;
4095     Drawing::Brush rectBrush;
4096     std::shared_ptr<Drawing::Typeface> typeFace = nullptr;
4097     // font size: 24
4098     std::shared_ptr<Drawing::TextBlob> textBlob =
4099         Drawing::TextBlob::MakeFromString(position.c_str(), Drawing::Font(typeFace, 24.0f, 1.0f, 0.0f));
4100     if (fillType == RSPaintStyle::STROKE) {
4101         rectPen.SetColor(color);
4102         rectPen.SetAntiAlias(true);
4103         rectPen.SetAlphaF(alpha);
4104         rectPen.SetWidth(edgeWidth);
4105         rectPen.SetJoinStyle(Drawing::Pen::JoinStyle::ROUND_JOIN);
4106         canvas_->AttachPen(rectPen);
4107     } else {
4108         rectBrush.SetColor(color);
4109         rectBrush.SetAntiAlias(true);
4110         rectBrush.SetAlphaF(alpha);
4111         canvas_->AttachBrush(rectBrush);
4112     }
4113     canvas_->DrawRect(rect);
4114     canvas_->DetachPen();
4115     canvas_->DetachBrush();
4116     canvas_->AttachBrush(Drawing::Brush());
4117     canvas_->DrawTextBlob(textBlob.get(), dirtyRect.left_ + defaultTextOffsetX, dirtyRect.top_ + defaultTextOffsetY);
4118     canvas_->DetachBrush();
4119 }
4120 
DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects)4121 void RSUniRenderVisitor::DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects)
4122 {
4123     const float fillAlpha = 0.2;
4124     for (const auto& subRect : dirtyRects) {
4125         DrawDirtyRectForDFX(subRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::FILL, fillAlpha);
4126     }
4127 }
4128 
DrawCacheRegionForDFX(std::map<NodeId,RectI> & cacheRects)4129 void RSUniRenderVisitor::DrawCacheRegionForDFX(std::map<NodeId, RectI>& cacheRects)
4130 {
4131     for (const auto& [nodeId, subRect] : cacheRects) {
4132         auto iter = cacheRenderNodeIsUpdateMap_.find(nodeId);
4133         if ((iter != cacheRenderNodeIsUpdateMap_.end()) && (iter->second)) {
4134             DrawDirtyRectForDFX(subRect, Drawing::Color::COLOR_RED, RSPaintStyle::FILL, CACHE_UPDATE_FILL_ALPHA);
4135         } else {
4136             DrawDirtyRectForDFX(subRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::FILL, CACHE_FILL_ALPHA);
4137         }
4138     }
4139 }
4140 
DrawHwcRegionForDFX(std::vector<std::shared_ptr<RSSurfaceRenderNode>> & hwcNodes)4141 void RSUniRenderVisitor::DrawHwcRegionForDFX(std::vector<std::shared_ptr<RSSurfaceRenderNode>>& hwcNodes)
4142 {
4143     const float fillAlpha = 0.3f;
4144     for (const auto& node : hwcNodes) {
4145         if (node->IsHardwareForcedDisabled() || !IsHardwareComposerEnabled()) {
4146             RSUniRenderUtil::DrawRectForDfx(*canvas_, node->GetDstRect(), Drawing::Color::COLOR_RED, fillAlpha,
4147                 node->GetName());
4148         } else {
4149             RSUniRenderUtil::DrawRectForDfx(*canvas_, node->GetDstRect(), Drawing::Color::COLOR_BLUE, fillAlpha,
4150                 node->GetName());
4151         }
4152     }
4153 }
4154 
DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode & node,const Occlusion::Region & region)4155 void RSUniRenderVisitor::DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node, const Occlusion::Region& region)
4156 {
4157     const auto& visibleDirtyRects = region.GetRegionRects();
4158     std::vector<RectI> rects;
4159     for (auto& rect : visibleDirtyRects) {
4160         rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
4161     }
4162     DrawDirtyRegionForDFX(rects);
4163 
4164     // draw display dirtyregion with red color
4165     RectI dirtySurfaceRect = node.GetDirtyManager()->GetDirtyRegion();
4166     const float fillAlpha = 0.2;
4167     DrawDirtyRectForDFX(dirtySurfaceRect, Drawing::Color::COLOR_RED, RSPaintStyle::STROKE, fillAlpha);
4168 }
4169 
DrawAllSurfaceOpaqueRegionForDFX(RSDisplayRenderNode & node)4170 void RSUniRenderVisitor::DrawAllSurfaceOpaqueRegionForDFX(RSDisplayRenderNode& node)
4171 {
4172     for (auto& it : node.GetCurAllSurfaces()) {
4173         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(it);
4174         if (surfaceNode && surfaceNode->IsMainWindowType()) {
4175             DrawSurfaceOpaqueRegionForDFX(*surfaceNode);
4176         }
4177     }
4178 }
4179 
DrawTargetSurfaceVisibleRegionForDFX(RSDisplayRenderNode & node)4180 void RSUniRenderVisitor::DrawTargetSurfaceVisibleRegionForDFX(RSDisplayRenderNode& node)
4181 {
4182     for (auto it = node.GetCurAllSurfaces().rbegin(); it != node.GetCurAllSurfaces().rend(); ++it) {
4183         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4184         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
4185             continue;
4186         }
4187         if (CheckIfSurfaceTargetedForDFX(surfaceNode->GetName())) {
4188             const auto& visibleRegions = surfaceNode->GetVisibleRegion().GetRegionRects();
4189             std::vector<RectI> rects;
4190             for (auto& rect : visibleRegions) {
4191                 rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
4192             }
4193             DrawDirtyRegionForDFX(rects);
4194         }
4195     }
4196 }
4197 
DrawEffectRenderNodeForDFX()4198 void RSUniRenderVisitor::DrawEffectRenderNodeForDFX()
4199 {
4200     if (effectNodeMapForDfx_.empty()) {
4201         return;
4202     }
4203     const float strokeAlpha = 0.8;
4204     const int strokeWidth = 12;
4205     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
4206     for (const auto& effectNode : effectNodeMapForDfx_) {
4207         auto node = nodeMap.GetRenderNode<RSRenderNode>(effectNode.first);
4208         if (!node) {
4209             continue;
4210         }
4211         auto& geoPtr = node->GetRenderProperties().GetBoundsGeometry();
4212         if (geoPtr == nullptr) {
4213             continue;
4214         }
4215         RectI absRect = geoPtr->GetAbsRect();
4216         // draw effectNode
4217         DrawDirtyRectForDFX(absRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::STROKE, strokeAlpha, strokeWidth);
4218         // draw useEffect nodes
4219         const auto& useEffectRects = effectNode.second.first;
4220         for (const auto& rect : useEffectRects) {
4221             DrawDirtyRectForDFX(rect, Drawing::Color::COLOR_GREEN, RSPaintStyle::STROKE, strokeAlpha, strokeWidth);
4222         }
4223 
4224         // draw fallback nodes
4225         const auto fallbackRects = effectNode.second.second;
4226         for (const auto& rect : fallbackRects) {
4227             DrawDirtyRectForDFX(rect, Drawing::Color::COLOR_RED, RSPaintStyle::STROKE, strokeAlpha, strokeWidth);
4228         }
4229     }
4230 }
4231 
DrawCurrentRefreshRate(uint32_t currentRefreshRate,uint32_t realtimeRefreshRate,RSDisplayRenderNode & node)4232 void RSUniRenderVisitor::DrawCurrentRefreshRate(
4233     uint32_t currentRefreshRate, uint32_t realtimeRefreshRate, RSDisplayRenderNode& node)
4234 {
4235     std::string info = std::to_string(currentRefreshRate) + " " + std::to_string(realtimeRefreshRate);
4236     auto color = currentRefreshRate <= 60 ? SK_ColorRED : SK_ColorGREEN;
4237     std::shared_ptr<Drawing::Typeface> tf = Drawing::Typeface::MakeFromName("HarmonyOS Sans SC", Drawing::FontStyle());
4238     Drawing::Font font;
4239     font.SetSize(100);  // 100:Scalar of setting font size
4240     font.SetTypeface(tf);
4241     std::shared_ptr<Drawing::TextBlob> textBlob = Drawing::TextBlob::MakeFromString(info.c_str(), font);
4242 
4243     Drawing::Brush brush;
4244     brush.SetColor(color);
4245     brush.SetAntiAlias(true);
4246     canvas_->AttachBrush(brush);
4247     auto rotation = node.GetScreenRotation();
4248     if (RSSystemProperties::IsFoldScreenFlag() && node.GetScreenId() == 0) {
4249         if (rotation == ScreenRotation::ROTATION_270) {
4250             rotation = ScreenRotation::ROTATION_0;
4251         } else {
4252             rotation = static_cast<ScreenRotation>(static_cast<int>(rotation) + 1);
4253         }
4254     }
4255     if (rotation != ScreenRotation::ROTATION_0) {
4256         auto screenManager = CreateOrGetScreenManager();
4257         auto mainScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
4258         if (rotation == ScreenRotation::ROTATION_90) {
4259             canvas_->Rotate(-RS_ROTATION_90, 0, 0);
4260             canvas_->Translate(-(static_cast<float>(mainScreenInfo.height)), 0);
4261         } else if (rotation == ScreenRotation::ROTATION_180) {
4262             canvas_->Rotate(-RS_ROTATION_180, static_cast<float>(mainScreenInfo.width) / 2,  // half of screen width
4263                 static_cast<float>(mainScreenInfo.height) / 2);                           // half of screen height
4264         } else if (rotation == ScreenRotation::ROTATION_270) {
4265             canvas_->Rotate(-RS_ROTATION_270, 0, 0);
4266             canvas_->Translate(0, -(static_cast<float>(mainScreenInfo.width)));
4267         } else {
4268             return;
4269         }
4270     }
4271     canvas_->DrawTextBlob(
4272         textBlob.get(), 100.f, 200.f);  // 100.f:Scalar x of drawing TextBlob; 200.f:Scalar y of drawing TextBlob
4273     canvas_->DetachBrush();
4274 }
4275 
DrawAndTraceSingleDirtyRegionTypeForDFX(RSSurfaceRenderNode & node,DirtyRegionType dirtyType,bool isDrawn)4276 void RSUniRenderVisitor::DrawAndTraceSingleDirtyRegionTypeForDFX(RSSurfaceRenderNode& node,
4277     DirtyRegionType dirtyType, bool isDrawn)
4278 {
4279     auto dirtyManager = node.GetDirtyManager();
4280     auto matchType = DIRTY_REGION_TYPE_MAP.find(dirtyType);
4281     if (dirtyManager == nullptr ||  matchType == DIRTY_REGION_TYPE_MAP.end()) {
4282         return;
4283     }
4284     std::map<NodeId, RectI> dirtyInfo;
4285     float fillAlpha = 0.2;
4286     std::map<RSRenderNodeType, std::pair<std::string, SkColor>> nodeConfig = {
4287         {RSRenderNodeType::CANVAS_NODE, std::make_pair("canvas", SK_ColorRED)},
4288         {RSRenderNodeType::SURFACE_NODE, std::make_pair("surface", SK_ColorGREEN)},
4289     };
4290 
4291     std::string subInfo;
4292     for (const auto& [nodeType, info] : nodeConfig) {
4293         dirtyManager->GetDirtyRegionInfo(dirtyInfo, nodeType, dirtyType);
4294         subInfo += (" " + info.first + "node amount: " + std::to_string(dirtyInfo.size()));
4295         for (const auto& [nid, rect] : dirtyInfo) {
4296             if (isDrawn) {
4297                 DrawDirtyRectForDFX(rect, info.second, RSPaintStyle::STROKE, fillAlpha);
4298             }
4299         }
4300     }
4301     RS_TRACE_NAME("DrawAndTraceSingleDirtyRegionTypeForDFX target surface node " + node.GetName() + " - id[" +
4302         std::to_string(node.GetId()) + "] has dirtytype " + matchType->second + subInfo);
4303     ROSEN_LOGD("DrawAndTraceSingleDirtyRegionTypeForDFX target surface node %{public}s, id[%{public}" PRIu64 "]"
4304         "has dirtytype %{public}s%{public}s",
4305         node.GetName().c_str(), node.GetId(), matchType->second.c_str(), subInfo.c_str());
4306 }
4307 
DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode & node)4308 bool RSUniRenderVisitor::DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode& node)
4309 {
4310     if (dirtyRegionDebugType_ < DirtyRegionDebugType::CUR_DIRTY_DETAIL_ONLY_TRACE) {
4311         return false;
4312     }
4313     if (dirtyRegionDebugType_ == DirtyRegionDebugType::CUR_DIRTY_DETAIL_ONLY_TRACE) {
4314         auto i = DirtyRegionType::UPDATE_DIRTY_REGION;
4315         for (; i < DirtyRegionType::TYPE_AMOUNT; i = (DirtyRegionType)(i + 1)) {
4316             DrawAndTraceSingleDirtyRegionTypeForDFX(node, i, false);
4317         }
4318         return true;
4319     }
4320     const std::map<DirtyRegionDebugType, DirtyRegionType> DIRTY_REGION_DEBUG_TYPE_MAP {
4321         { DirtyRegionDebugType::UPDATE_DIRTY_REGION, DirtyRegionType::UPDATE_DIRTY_REGION },
4322         { DirtyRegionDebugType::OVERLAY_RECT, DirtyRegionType::OVERLAY_RECT },
4323         { DirtyRegionDebugType::FILTER_RECT, DirtyRegionType::FILTER_RECT },
4324         { DirtyRegionDebugType::SHADOW_RECT, DirtyRegionType::SHADOW_RECT },
4325         { DirtyRegionDebugType::PREPARE_CLIP_RECT, DirtyRegionType::PREPARE_CLIP_RECT },
4326         { DirtyRegionDebugType::REMOVE_CHILD_RECT, DirtyRegionType::REMOVE_CHILD_RECT },
4327         { DirtyRegionDebugType::RENDER_PROPERTIES_RECT, DirtyRegionType::RENDER_PROPERTIES_RECT },
4328         { DirtyRegionDebugType::CANVAS_NODE_SKIP_RECT, DirtyRegionType::CANVAS_NODE_SKIP_RECT },
4329         { DirtyRegionDebugType::OUTLINE_RECT, DirtyRegionType::OUTLINE_RECT },
4330     };
4331     auto matchType = DIRTY_REGION_DEBUG_TYPE_MAP.find(dirtyRegionDebugType_);
4332     if (matchType != DIRTY_REGION_DEBUG_TYPE_MAP.end()) {
4333         DrawAndTraceSingleDirtyRegionTypeForDFX(node, matchType->second);
4334     }
4335     return true;
4336 }
4337 
DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode & node)4338 void RSUniRenderVisitor::DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode& node)
4339 {
4340     const auto& opaqueRegionRects = node.GetOpaqueRegion().GetRegionRects();
4341     for (const auto &subRect: opaqueRegionRects) {
4342         DrawDirtyRectForDFX(subRect.ToRectI(), Drawing::Color::COLOR_GREEN,
4343             RSPaintStyle::FILL, 0.2f, 0);
4344     }
4345 }
4346 
ProcessShadowFirst(RSRenderNode & node,bool inSubThread)4347 void RSUniRenderVisitor::ProcessShadowFirst(RSRenderNode& node, bool inSubThread)
4348 {
4349     if (node.GetRenderProperties().GetUseShadowBatching()) {
4350         auto children = node.GetSortedChildren();
4351         for (auto& child : *children) {
4352             if (auto node = child->ReinterpretCastTo<RSCanvasRenderNode>()) {
4353                 node->ProcessShadowBatching(*canvas_);
4354             }
4355         }
4356     }
4357 }
4358 
CheckSkipRepeatShadow(RSRenderNode & node,const bool resetStatus)4359 void RSUniRenderVisitor::CheckSkipRepeatShadow(RSRenderNode& node, const bool resetStatus)
4360 {
4361     // In normal process, if shadow has drawn in drawCacheWithBlur, no need to draw again in children node
4362     // not comming from drawCacheWithBlur and updateCacheProcess, child has shadow,skip draw shadow child later
4363     if (!drawCacheWithBlur_ && !notRunCheckAndSetNodeCacheType_ && !allCacheFilterRects_[node.GetId()].empty() &&
4364         node.ChildHasVisibleFilter() && updateCacheProcessCnt_ == 0) {
4365         if (resetStatus) {
4366             RS_TRACE_NAME("status reset");
4367             noNeedTodrawShadowAgain_ = false;
4368             return;
4369         }
4370         noNeedTodrawShadowAgain_ = true;
4371     }
4372 }
4373 
SetNodeSkipShadow(std::shared_ptr<RSRenderNode> node,const bool resetStatus)4374 void RSUniRenderVisitor::SetNodeSkipShadow(std::shared_ptr<RSRenderNode> node, const bool resetStatus)
4375 {
4376     // skip shadow drawing in updateCacheProcess,it will draw in drawCacheWithBlur
4377     // and skip shadow repeat drawing in normal process
4378     if (!drawCacheWithBlur_ && node->GetRenderProperties().GetShadowColorStrategy() !=
4379         SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE &&
4380         (updateCacheProcessCnt_ != 0 || noNeedTodrawShadowAgain_)) {
4381         ROSEN_LOGD("skip draw shadow and text repeatly");
4382         if (resetStatus) {
4383             node->GetMutableRenderProperties().SetNeedSkipShadow(false);
4384             return;
4385         }
4386         node->GetMutableRenderProperties().SetNeedSkipShadow(true);
4387     }
4388 }
4389 
ProcessChildren(RSRenderNode & node)4390 void RSUniRenderVisitor::ProcessChildren(RSRenderNode& node)
4391 {
4392     RS_LOGE("It is update to DrawableV2 to process node now!!");
4393 }
4394 
ProcessChildrenForScreenRecordingOptimization(RSDisplayRenderNode & node,NodeId rootIdOfCaptureWindow)4395 void RSUniRenderVisitor::ProcessChildrenForScreenRecordingOptimization(
4396     RSDisplayRenderNode& node, NodeId rootIdOfCaptureWindow)
4397 {
4398     RS_LOGE("It is update to DrawableV2 to process node now!!");
4399 }
4400 
ProcessChildInner(RSRenderNode & node,const RSRenderNode::SharedPtr child)4401 void RSUniRenderVisitor::ProcessChildInner(RSRenderNode& node, const RSRenderNode::SharedPtr child)
4402 {
4403     RS_LOGE("It is update to DrawableV2 to process node now!!");
4404 }
4405 
UpdateVirtualScreenWhiteListRootId(const RSRenderNode::SharedPtr & node)4406 void RSUniRenderVisitor::UpdateVirtualScreenWhiteListRootId(const RSRenderNode::SharedPtr& node)
4407 {
4408     if (node->GetType() == RSRenderNodeType::SURFACE_NODE && virtualScreenWhiteListRootId_ == INVALID_NODEID &&
4409         screenInfo_.whiteList.find(node->GetId()) != screenInfo_.whiteList.end()) {
4410         // limit surface node is to reduce whiteList set times
4411         // don't update if node's parent is in whiteList
4412         virtualScreenWhiteListRootId_ = node->GetId();
4413     } else if (virtualScreenWhiteListRootId_ == node->GetId()) {
4414         // restore virtualScreenWhiteListRootId_ only by itself
4415         virtualScreenWhiteListRootId_ = INVALID_NODEID;
4416     }
4417 }
4418 
ProcessDisplayRenderNode(RSDisplayRenderNode & node)4419 void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
4420 {
4421     RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
4422 }
4423 
SwitchColorFilterDrawing(int currentSaveCount)4424 void RSUniRenderVisitor::SwitchColorFilterDrawing(int currentSaveCount)
4425 {
4426     ColorFilterMode colorFilterMode = renderEngine_->GetColorFilterMode();
4427     if (colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
4428         colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE) {
4429         RS_LOGD("RsDebug RSBaseRenderEngine::SetColorFilterModeToPaint mode:%{public}d",
4430             static_cast<int32_t>(colorFilterMode));
4431         Drawing::Brush brush;
4432         RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, brush);
4433 #if defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)
4434 #ifdef NEW_RENDER_CONTEXT
4435         RSTagTracker tagTracker(
4436             renderEngine_->GetDrawingContext()->GetDrawingContext(),
4437             RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
4438 #else
4439         RSTagTracker tagTracker(
4440             renderEngine_->GetRenderContext()->GetDrGPUContext(),
4441             RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
4442 #endif
4443 #endif
4444         Drawing::SaveLayerOps slr(nullptr, &brush, Drawing::SaveLayerOps::INIT_WITH_PREVIOUS);
4445         canvas_->SaveLayer(slr);
4446         canvas_->RestoreToCount(currentSaveCount);
4447     }
4448 }
4449 
AssignGlobalZOrderAndCreateLayer(std::vector<std::shared_ptr<RSSurfaceRenderNode>> & nodesInZOrder)4450 void RSUniRenderVisitor::AssignGlobalZOrderAndCreateLayer(
4451     std::vector<std::shared_ptr<RSSurfaceRenderNode>>& nodesInZOrder)
4452 {
4453     if (!IsHardwareComposerEnabled()) {
4454         return;
4455     }
4456     if (hardwareEnabledNodes_.empty()) {
4457         return;
4458     }
4459     for (auto& appWindowNode : nodesInZOrder) {
4460         // first, sort app window node's child surfaceView by local zOrder
4461         auto& childHardwareEnabledNodes =
4462             const_cast<std::vector<std::weak_ptr<RSSurfaceRenderNode>>&>(appWindowNode->GetChildHardwareEnabledNodes());
4463         for (auto iter = childHardwareEnabledNodes.begin(); iter != childHardwareEnabledNodes.end();) {
4464             auto childNode = iter->lock();
4465             if (!childNode || !childNode->IsOnTheTree()) {
4466                 iter = childHardwareEnabledNodes.erase(iter);
4467                 continue;
4468             }
4469             auto surfaceHandler = childNode->GetMutableRSSurfaceHandler();
4470             if (surfaceHandler->GetBuffer() != nullptr &&
4471                 (!childNode->IsHardwareForcedDisabled() || childNode->GetProtectedLayer())) {
4472                 // SetGlobalZOrder here to ensure zOrder committed to composer is continuous
4473                 surfaceHandler->SetGlobalZOrder(globalZOrder_++);
4474                 RS_LOGD("createLayer: %{public}" PRIu64 "", childNode->GetId());
4475                 processor_->ProcessSurface(*childNode);
4476             }
4477             ++iter;
4478         }
4479     }
4480 }
4481 
AddOverDrawListener(std::unique_ptr<RSRenderFrame> & renderFrame,std::shared_ptr<RSCanvasListener> & overdrawListener)4482 void RSUniRenderVisitor::AddOverDrawListener(std::unique_ptr<RSRenderFrame>& renderFrame,
4483     std::shared_ptr<RSCanvasListener>& overdrawListener)
4484 {
4485     if (renderFrame == nullptr) {
4486         RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: renderFrame is nullptr");
4487         return;
4488     }
4489 #if defined(NEW_RENDER_CONTEXT)
4490     auto renderSurface = renderFrame->GetSurface();
4491     if (renderSurface == nullptr) {
4492         RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: renderSurface is nullptr");
4493         return;
4494     }
4495     RS_OPTIONAL_TRACE_BEGIN("RSUniRender::GetSurface");
4496     auto drSurface = renderSurface->GetSurface();
4497     RS_OPTIONAL_TRACE_END();
4498     if (drSurface == nullptr) {
4499         RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: drSurface is null");
4500         return;
4501     }
4502     if (drSurface->GetCanvas() == nullptr) {
4503         ROSEN_LOGE("drSurface.getCanvas is null.");
4504         return;
4505     }
4506 #else
4507     if (renderFrame->GetFrame() == nullptr) {
4508         RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: RSSurfaceFrame is nullptr");
4509         return;
4510     }
4511     RS_OPTIONAL_TRACE_BEGIN("RSUniRender::GetSurface");
4512     auto drSurface = renderFrame->GetFrame()->GetSurface();
4513     RS_OPTIONAL_TRACE_END();
4514     if (drSurface == nullptr) {
4515         RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: drSurface is null");
4516         return;
4517     }
4518     if (drSurface->GetCanvas() == nullptr) {
4519         ROSEN_LOGE("drSurface.getCanvas is null.");
4520         return;
4521     }
4522 #endif
4523     canvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
4524 }
4525 
IsNotDirtyHardwareEnabledTopSurface(std::shared_ptr<RSSurfaceRenderNode> & node) const4526 bool RSUniRenderVisitor::IsNotDirtyHardwareEnabledTopSurface(std::shared_ptr<RSSurfaceRenderNode>& node) const
4527 {
4528     if (!node->IsHardwareEnabledTopSurface()) {
4529         return false;
4530     }
4531     // If the pointer is dirty in last frame but not in current, when gpu -> hardware composer.
4532     // It should also calc global dirty in current frame.
4533     node->SetNodeDirty(isHardwareForcedDisabled_ || node->HasSubNodeShouldPaint() ||
4534         !node->IsLastFrameHardwareEnabled());
4535     return !node->IsNodeDirty();
4536 }
4537 
ClipRegion(std::shared_ptr<Drawing::Canvas> canvas,const Drawing::Region & region) const4538 void RSUniRenderVisitor::ClipRegion(std::shared_ptr<Drawing::Canvas> canvas, const Drawing::Region& region) const
4539 {
4540     if (region.IsEmpty()) {
4541         // [planning] Remove this after frame buffer can cancel
4542         canvas->ClipRect(Drawing::Rect());
4543     } else if (region.IsRect()) {
4544         canvas->ClipRegion(region);
4545     } else {
4546         RS_TRACE_NAME("RSUniRenderVisitor: clipPath");
4547 #ifdef RS_ENABLE_VK
4548         if (RSSystemProperties::IsUseVulkan()) {
4549             canvas->ClipRegion(region);
4550         } else {
4551             Drawing::Path dirtyPath;
4552             region.GetBoundaryPath(&dirtyPath);
4553             canvas->ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
4554         }
4555 #else
4556         Drawing::Path dirtyPath;
4557         region.GetBoundaryPath(&dirtyPath);
4558         canvas->ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
4559 #endif
4560     }
4561 }
4562 
CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode> & node)4563 void RSUniRenderVisitor::CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode>& node)
4564 {
4565     RS_OPTIONAL_TRACE_FUNC();
4566     auto displayDirtyManager = node->GetDirtyManager();
4567     for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
4568         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4569         if (surfaceNode == nullptr) {
4570             continue;
4571         }
4572         if (IsNotDirtyHardwareEnabledTopSurface(surfaceNode)) {
4573             continue;
4574         }
4575         auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
4576         if (isUIFirst_ && surfaceDirtyManager->IsCurrentFrameDirty()) {
4577             curDisplayNode_->GetDirtySurfaceNodeMap().emplace(
4578                 surfaceNode->GetId(), surfaceNode->ReinterpretCastTo<RSSurfaceRenderNode>());
4579         }
4580         RectI surfaceDirtyRect = surfaceDirtyManager->GetCurrentFrameDirtyRegion();
4581         if (surfaceNode->IsTransparent()) {
4582             // Handles the case of transparent surface, merge transparent dirty rect
4583             RectI transparentDirtyRect = surfaceNode->GetDstRect().IntersectRect(surfaceDirtyRect);
4584             if (!transparentDirtyRect.IsEmpty()) {
4585                 RS_OPTIONAL_TRACE_NAME_FMT("CalcDirtyDisplayRegion merge transparent dirty rect %s rect %s",
4586                     surfaceNode->GetName().c_str(), transparentDirtyRect.ToString().c_str());
4587                 displayDirtyManager->MergeDirtyRect(transparentDirtyRect);
4588             }
4589         }
4590 
4591         if (surfaceNode->GetZorderChanged()) {
4592             // Zorder changed case, merge surface dest Rect
4593             RS_LOGD("CalcDirtyDisplayRegion merge GetZorderChanged %{public}s rect %{public}s",
4594                 surfaceNode->GetName().c_str(), surfaceNode->GetDstRect().ToString().c_str());
4595             displayDirtyManager->MergeDirtyRect(surfaceNode->GetDstRect());
4596         }
4597 
4598         RectI lastFrameSurfacePos = node->GetLastFrameSurfacePos(surfaceNode->GetId());
4599         RectI currentFrameSurfacePos = node->GetCurrentFrameSurfacePos(surfaceNode->GetId());
4600         if (surfaceNode->GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
4601             RS_LOGD("CalcDirtyDisplayRegion merge surface pos changed %{public}s lastFrameRect %{public}s"
4602                 " currentFrameRect %{public}s", surfaceNode->GetName().c_str(), lastFrameSurfacePos.ToString().c_str(),
4603                 currentFrameSurfacePos.ToString().c_str());
4604             if (!lastFrameSurfacePos.IsEmpty()) {
4605                 displayDirtyManager->MergeDirtyRect(lastFrameSurfacePos);
4606             }
4607             if (!currentFrameSurfacePos.IsEmpty()) {
4608                 displayDirtyManager->MergeDirtyRect(currentFrameSurfacePos);
4609             }
4610         }
4611 
4612         bool isShadowDisappear =
4613             !surfaceNode->GetRenderProperties().IsShadowValid() && surfaceNode->IsShadowValidLastFrame();
4614         if (surfaceNode->GetRenderProperties().IsShadowValid() || isShadowDisappear) {
4615             RectI shadowDirtyRect = surfaceNode->GetOldDirtyInSurface().IntersectRect(surfaceDirtyRect);
4616             // There are two situation here:
4617             // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
4618             // surfaceDirtyRect == surfaceNode->GetOldDirtyInSurface()
4619             // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
4620             // surfaceDirtyRect > surfaceNode->GetOldDirtyInSurface()
4621             // So we should always merge surfaceDirtyRect here.
4622             if (!shadowDirtyRect.IsEmpty()) {
4623                 displayDirtyManager->MergeDirtyRect(surfaceDirtyRect);
4624                 RS_LOGD("CalcDirtyDisplayRegion merge ShadowValid %{public}s rect %{public}s",
4625                     surfaceNode->GetName().c_str(), surfaceDirtyRect.ToString().c_str());
4626             }
4627             if (isShadowDisappear) {
4628                 surfaceNode->SetShadowValidLastFrame(false);
4629             }
4630         }
4631     }
4632     std::vector<RectI> surfaceChangedRects = node->GetSurfaceChangedRects();
4633     for (auto& surfaceChangedRect : surfaceChangedRects) {
4634         RS_LOGD("CalcDirtyDisplayRegion merge Surface closed %{public}s", surfaceChangedRect.ToString().c_str());
4635         if (!surfaceChangedRect.IsEmpty()) {
4636             displayDirtyManager->MergeDirtyRect(surfaceChangedRect);
4637         }
4638     }
4639     if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
4640         RectI tempRect = {100, 100, 500, 200};   // setDirtyRegion for RealtimeRefreshRate
4641         displayDirtyManager->MergeDirtyRect(tempRect, true);  // true:debugRect for dislplayNode skip
4642     }
4643 
4644 #ifdef RS_PROFILER_ENABLED
4645     RS_LOGD("CalcDirtyRegion RSSystemProperties::GetFullDirtyScreenEnabled()");
4646     auto resolution = RSCaptureRecorder::GetInstance().GetDirtyRect(screenInfo_.width, screenInfo_.height);
4647     displayDirtyManager->MergeDirtyRect(RectI { 0, 0, resolution.first, resolution.second });
4648 #endif
4649 }
4650 
MergeDirtyRectIfNeed(std::shared_ptr<RSSurfaceRenderNode> appNode,std::shared_ptr<RSSurfaceRenderNode> hwcNode)4651 void RSUniRenderVisitor::MergeDirtyRectIfNeed(std::shared_ptr<RSSurfaceRenderNode> appNode,
4652     std::shared_ptr<RSSurfaceRenderNode> hwcNode)
4653 {
4654     if ((hwcNode->IsLastFrameHardwareEnabled() || hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) &&
4655         appNode && appNode->GetDirtyManager()) {
4656         appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
4657         curDisplayNode_->GetDirtySurfaceNodeMap().emplace(appNode->GetId(), appNode);
4658     }
4659 }
4660 
UpdateHardwareEnableList(std::vector<RectI> & filterRects,std::vector<SurfaceDirtyMgrPair> & validHwcNodes)4661 RectI RSUniRenderVisitor::UpdateHardwareEnableList(std::vector<RectI>& filterRects,
4662     std::vector<SurfaceDirtyMgrPair>& validHwcNodes)
4663 {
4664     if (validHwcNodes.empty() || filterRects.empty()) {
4665         return RectI();
4666     }
4667     // remove invisible surface since occlusion
4668     // check intersected parts
4669     RectI filterDirty;
4670     for (auto iter = validHwcNodes.begin(); iter != validHwcNodes.end(); ++iter) {
4671         auto childNode = iter->first;
4672         auto childDirtyRect = childNode->GetDstRect();
4673         bool isIntersected = false;
4674         // remove invisible surface since occlusion
4675         for (auto& filterRect : filterRects) {
4676             if (!childDirtyRect.IntersectRect(filterRect).IsEmpty()) {
4677                 filterDirty = filterDirty.JoinRect(filterRect);
4678                 isIntersected = true;
4679             }
4680         }
4681         if (isIntersected) {
4682             childNode->SetHardwareForcedDisabledStateByFilter(true);
4683             auto node = iter->second;
4684             MergeDirtyRectIfNeed(iter->second, childNode);
4685             iter = validHwcNodes.erase(iter);
4686             iter--;
4687         }
4688     }
4689     return filterDirty;
4690 }
4691 
UpdateHardwareChildNodeStatus(std::shared_ptr<RSSurfaceRenderNode> & node,std::vector<SurfaceDirtyMgrPair> & curHwcEnabledNodes)4692 void RSUniRenderVisitor::UpdateHardwareChildNodeStatus(std::shared_ptr<RSSurfaceRenderNode>& node,
4693     std::vector<SurfaceDirtyMgrPair>& curHwcEnabledNodes)
4694 {
4695     // remove invisible surface since occlusion
4696     auto visibleRegion = node->GetVisibleRegion();
4697     for (auto subNode : node->GetChildHardwareEnabledNodes()) {
4698         auto childNode = subNode.lock();
4699         if (!childNode) {
4700             continue;
4701         }
4702         // recover disabled state before update
4703         childNode->SetHardwareForcedDisabledStateByFilter(false);
4704         if (!visibleRegion.IsIntersectWith(Occlusion::Rect(childNode->GetOldDirtyInSurface()))) {
4705             continue;
4706         }
4707         bool isIntersected = false;
4708         if (!isPhone_ || childNode->GetAncoForceDoDirect()) {
4709             curHwcEnabledNodes.emplace_back(std::make_pair(subNode, node));
4710             continue;
4711         }
4712         for (auto &hwcNode: curHwcEnabledNodes) {
4713             if (childNode->GetDstRect().Intersect(hwcNode.first->GetDstRect())) {
4714                 childNode->SetHardwareForcedDisabledStateByFilter(true);
4715                 isIntersected = true;
4716                 break;
4717             }
4718         }
4719         if (!isIntersected) {
4720             curHwcEnabledNodes.emplace_back(std::make_pair(subNode, node));
4721         }
4722     }
4723 }
4724 
UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode> & node,std::vector<SurfaceDirtyMgrPair> & prevHwcEnabledNodes,std::shared_ptr<RSDirtyRegionManager> & displayDirtyManager)4725 void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode>& node,
4726     std::vector<SurfaceDirtyMgrPair>& prevHwcEnabledNodes,
4727     std::shared_ptr<RSDirtyRegionManager>& displayDirtyManager)
4728 {
4729     if (!IsHardwareComposerEnabled()) {
4730         return;
4731     }
4732     if (node == nullptr || !node->IsAppWindow() || node->GetDirtyManager() == nullptr ||
4733         displayDirtyManager == nullptr) {
4734         return;
4735     }
4736     auto dirtyManager = node->GetDirtyManager();
4737     auto filterRects = node->GetChildrenNeedFilterRectsWithoutCacheValid();
4738     // collect valid hwc surface which is not intersected with filterRects
4739     std::vector<SurfaceDirtyMgrPair> curHwcEnabledNodes;
4740     UpdateHardwareChildNodeStatus(node, curHwcEnabledNodes);
4741 
4742     // Within App: disable hwc if intersect with filterRects
4743     dirtyManager->MergeDirtyRect(UpdateHardwareEnableList(filterRects, curHwcEnabledNodes));
4744     // Among App: disable lower hwc layers if intersect with upper transparent appWindow
4745     if (node->IsTransparent()) {
4746         if (node->GetRenderProperties().NeedFilter()) {
4747             // Attention: if transparent appwindow needs filter, only need to check itself
4748             filterRects = {node->GetDstRect()};
4749         }
4750         // In case of transparent window, filterRects need hwc surface's content
4751         RectI globalTransDirty = UpdateHardwareEnableList(filterRects, prevHwcEnabledNodes);
4752         displayDirtyManager->MergeDirtyRect(globalTransDirty);
4753         dirtyManager->MergeDirtyRect(globalTransDirty);
4754     }
4755     // erase from curHwcEnabledNodes if app node has no container window and its hwc node intersects with hwc below
4756     if (!node->HasContainerWindow() && !curHwcEnabledNodes.empty() && !prevHwcEnabledNodes.empty()) {
4757         for (auto iter = curHwcEnabledNodes.begin(); iter != curHwcEnabledNodes.end(); ++iter) {
4758             for (auto& prevNode : prevHwcEnabledNodes) {
4759                 if (!iter->first->GetDstRect().IntersectRect(prevNode.first->GetDstRect()).IsEmpty()) {
4760                     iter->first->SetHardwareForcedDisabledStateByFilter(true);
4761                     MergeDirtyRectIfNeed(iter->second, iter->first);
4762                     iter = curHwcEnabledNodes.erase(iter);
4763                     iter--;
4764                     break;
4765                 }
4766             }
4767         }
4768     }
4769     if (!curHwcEnabledNodes.empty()) {
4770         prevHwcEnabledNodes.insert(prevHwcEnabledNodes.end(), curHwcEnabledNodes.begin(), curHwcEnabledNodes.end());
4771     }
4772 }
4773 
CalcDirtyRegionForFilterNode(const RectI & filterRect,std::shared_ptr<RSSurfaceRenderNode> & currentSurfaceNode,std::shared_ptr<RSDisplayRenderNode> & displayNode)4774 void RSUniRenderVisitor::CalcDirtyRegionForFilterNode(const RectI& filterRect,
4775     std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode,
4776     std::shared_ptr<RSDisplayRenderNode>& displayNode)
4777 {
4778     auto displayDirtyManager = displayNode->GetDirtyManager();
4779     auto currentSurfaceDirtyManager = currentSurfaceNode->GetDirtyManager();
4780     if (displayDirtyManager == nullptr || currentSurfaceDirtyManager == nullptr) {
4781         return;
4782     }
4783 
4784     RectI displayDirtyRect = displayDirtyManager->GetCurrentFrameDirtyRegion();
4785     RectI currentSurfaceDirtyRect = currentSurfaceDirtyManager->GetCurrentFrameDirtyRegion();
4786     bool displayDirtyIntersectRectFilter = !displayDirtyRect.IntersectRect(filterRect).IsEmpty();
4787     bool surfaceDirtyIntersectRectFilter = !currentSurfaceDirtyRect.IntersectRect(filterRect).IsEmpty();
4788     if (displayDirtyIntersectRectFilter || surfaceDirtyIntersectRectFilter) {
4789         currentSurfaceDirtyManager->MergeDirtyRect(filterRect);
4790         if (!currentSurfaceNode->IsTransparent()) {
4791             Occlusion::Region filterRegion(Occlusion::Rect(filterRect.GetLeft(), filterRect.GetTop(),
4792                 filterRect.GetRight(), filterRect.GetBottom()));
4793             if (!filterRegion.Sub(currentSurfaceNode->GetOpaqueRegion()).IsEmpty()) {
4794                 displayDirtyManager->MergeDirtyRect(filterRect);
4795                 return;
4796             }
4797         }
4798     }
4799 
4800     if (currentSurfaceNode->IsTransparent()) {
4801         if (displayDirtyIntersectRectFilter) {
4802             displayDirtyManager->MergeDirtyRect(filterRect);
4803             return;
4804         }
4805         // If currentSurfaceNode is transparent and displayDirtyRect is not intersect with filterRect,
4806         // We should check whether window below currentSurfaceNode has dirtyRect intersect with filterRect.
4807         for (auto belowSurface = displayNode->GetCurAllSurfaces().begin();
4808             belowSurface != displayNode->GetCurAllSurfaces().end(); ++belowSurface) {
4809             auto belowSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*belowSurface);
4810             if (belowSurfaceNode == currentSurfaceNode) {
4811                 break;
4812             }
4813             if (belowSurfaceNode == nullptr || !belowSurfaceNode->IsAppWindow()) {
4814                 continue;
4815             }
4816             auto belowSurfaceDirtyManager = belowSurfaceNode->GetDirtyManager();
4817             RectI belowDirtyRect =
4818                 belowSurfaceDirtyManager ? belowSurfaceDirtyManager->GetCurrentFrameDirtyRegion() : RectI{0, 0, 0, 0};
4819             if (belowDirtyRect.IsEmpty()) {
4820                 continue;
4821             }
4822             // To minimize dirtyRect, only filterRect has intersect with both visibleRegion and dirtyRect
4823             // of window below, we add filterRect to displayDirtyRect and currentSurfaceDirtyRect.
4824             if (belowSurfaceNode->GetVisibleRegion().IsIntersectWith(filterRect) &&
4825                 !belowDirtyRect.IntersectRect(filterRect).IsEmpty()) {
4826                 displayDirtyManager->MergeDirtyRect(filterRect);
4827                 currentSurfaceDirtyManager->MergeDirtyRect(filterRect);
4828                 break;
4829             }
4830         }
4831     }
4832 }
4833 
CalcChildFilterNodeDirtyRegion(std::shared_ptr<RSSurfaceRenderNode> & currentSurfaceNode,std::shared_ptr<RSDisplayRenderNode> & displayNode)4834 void RSUniRenderVisitor::CalcChildFilterNodeDirtyRegion(std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode,
4835     std::shared_ptr<RSDisplayRenderNode>& displayNode)
4836 {
4837     if (currentSurfaceNode == nullptr || displayNode == nullptr) {
4838         return;
4839     }
4840     auto filterRects = currentSurfaceNode->GetChildrenNeedFilterRects();
4841     auto filterNodes = currentSurfaceNode->GetChildrenFilterNodes();
4842     if (currentSurfaceNode->IsAppWindow() && !filterRects.empty()) {
4843         needFilter_ = needFilter_ || !currentSurfaceNode->IsStaticCached();
4844         for (size_t i = 0; i < filterNodes.size(); i++) {
4845             auto filterRectsCacheValidNow = filterNodes[i]->IsFilterCacheValid();
4846             // if child filter node has filter cache, no need to be added into dirtyregion
4847             // only support background filter cache valid and no pixelstretch node now
4848             if (isCacheBlurPartialRenderEnabled_ && filterRectsCacheValidNow &&
4849                 !filterNodes[i]->GetRenderProperties().GetPixelStretch().has_value()) {
4850                 continue;
4851             }
4852             CalcDirtyRegionForFilterNode(filterRects[i], currentSurfaceNode, displayNode);
4853         }
4854     }
4855 }
4856 
CalcSurfaceFilterNodeDirtyRegion(std::shared_ptr<RSSurfaceRenderNode> & currentSurfaceNode,std::shared_ptr<RSDisplayRenderNode> & displayNode)4857 void RSUniRenderVisitor::CalcSurfaceFilterNodeDirtyRegion(std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode,
4858     std::shared_ptr<RSDisplayRenderNode>& displayNode)
4859 {
4860     if (currentSurfaceNode == nullptr || displayNode == nullptr) {
4861         return;
4862     }
4863     if (currentSurfaceNode->GetRenderProperties().NeedFilter()) {
4864         needFilter_ = needFilter_ || !currentSurfaceNode->IsStaticCached();
4865         CalcDirtyRegionForFilterNode(
4866             currentSurfaceNode->GetOldDirtyInSurface(), currentSurfaceNode, displayNode);
4867     }
4868 }
4869 
UpdateHardwareNodeStatusBasedOnFilterRegion(RSDisplayRenderNode & displayNode)4870 void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilterRegion(RSDisplayRenderNode& displayNode)
4871 {
4872     std::vector<std::shared_ptr<RSSurfaceRenderNode>> prevHwcEnabledNodes;
4873     for (auto it = displayNode.GetCurAllSurfaces().begin(); it != displayNode.GetCurAllSurfaces().end(); ++it) {
4874         auto currentSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4875         if (currentSurfaceNode != nullptr) {
4876             UpdateHardwareNodeStatusBasedOnFilter(currentSurfaceNode, prevHwcEnabledNodes);
4877         }
4878     }
4879 }
4880 
UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode> & node,std::vector<std::shared_ptr<RSSurfaceRenderNode>> & prevHwcEnabledNodes)4881 void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode>& node,
4882     std::vector<std::shared_ptr<RSSurfaceRenderNode>>& prevHwcEnabledNodes)
4883 {
4884     if (!IsHardwareComposerEnabled()) {
4885         return;
4886     }
4887     if (node == nullptr || !node->IsAppWindow()) {
4888         return;
4889     }
4890     auto filterRects = node->GetChildrenNeedFilterRects();
4891     // collect valid hwc surface which is not intersected with filterRects
4892     std::vector<std::shared_ptr<RSSurfaceRenderNode>> curHwcEnabledNodes;
4893     for (auto subNode : node->GetChildHardwareEnabledNodes()) {
4894         auto childNode = subNode.lock();
4895         if (!childNode) {
4896             continue;
4897         }
4898         childNode->SetHardwareForcedDisabledStateByFilter(false);
4899         bool isIntersected = false;
4900         if (isPhone_) {
4901             for (auto &hwcNode: curHwcEnabledNodes) {
4902                 if (childNode->GetDstRect().Intersect(hwcNode->GetDstRect())) {
4903                     childNode->SetHardwareForcedDisabledStateByFilter(true);
4904                     isIntersected = true;
4905                     break;
4906                 }
4907             }
4908         }
4909         if (!isPhone_ || !isIntersected) {
4910             curHwcEnabledNodes.emplace_back(childNode);
4911         }
4912     }
4913     // Within App: disable hwc if intersect with filterRects
4914     UpdateHardwareEnableList(filterRects, curHwcEnabledNodes);
4915     // Among App: disable lower hwc layers if intersect with upper transparent appWindow
4916     if (node->IsTransparent()) {
4917         if (node->GetRenderProperties().NeedFilter()) {
4918             // Attention: if transparent appwindow needs filter, only need to check itself
4919             filterRects = {node->GetDstRect()};
4920         }
4921         // In case of transparent window, filterRects need hwc surface's content
4922         UpdateHardwareEnableList(filterRects, prevHwcEnabledNodes);
4923     }
4924     if (!curHwcEnabledNodes.empty()) {
4925         prevHwcEnabledNodes.insert(prevHwcEnabledNodes.end(), curHwcEnabledNodes.begin(), curHwcEnabledNodes.end());
4926     }
4927 }
4928 
UpdateHardwareEnableList(std::vector<RectI> & filterRects,std::vector<std::shared_ptr<RSSurfaceRenderNode>> & validHwcNodes)4929 void RSUniRenderVisitor::UpdateHardwareEnableList(std::vector<RectI>& filterRects,
4930     std::vector<std::shared_ptr<RSSurfaceRenderNode>>& validHwcNodes)
4931 {
4932     if (validHwcNodes.empty() || filterRects.empty()) {
4933         return;
4934     }
4935     for (auto iter = validHwcNodes.begin(); iter != validHwcNodes.end(); ++iter) {
4936         auto childDirtyRect = (*iter)->GetDstRect();
4937         bool isIntersected = false;
4938         for (auto& filterRect : filterRects) {
4939             if (!childDirtyRect.IntersectRect(filterRect).IsEmpty()) {
4940                 isIntersected = true;
4941             }
4942         }
4943         if (isIntersected) {
4944             (*iter)->SetHardwareForcedDisabledStateByFilter(true);
4945             iter = validHwcNodes.erase(iter);
4946             iter--;
4947         }
4948     }
4949 }
4950 
CalcDirtyFilterRegion(std::shared_ptr<RSDisplayRenderNode> & displayNode)4951 void RSUniRenderVisitor::CalcDirtyFilterRegion(std::shared_ptr<RSDisplayRenderNode>& displayNode)
4952 {
4953     if (displayNode == nullptr || displayNode->GetDirtyManager() == nullptr) {
4954         return;
4955     }
4956     auto displayDirtyManager = displayNode->GetDirtyManager();
4957     std::vector<SurfaceDirtyMgrPair> prevHwcEnabledNodes;
4958     for (auto it = displayNode->GetCurAllSurfaces().begin(); it != displayNode->GetCurAllSurfaces().end(); ++it) {
4959         auto currentSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4960         if (currentSurfaceNode) {
4961             // [planning] Update hwc surface dirty status at the same time
4962             UpdateHardwareNodeStatusBasedOnFilter(currentSurfaceNode, prevHwcEnabledNodes, displayDirtyManager);
4963         }
4964     }
4965 
4966     for (auto it = displayNode->GetCurAllSurfaces().begin(); it != displayNode->GetCurAllSurfaces().end();) {
4967         auto currentSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4968         if (currentSurfaceNode == nullptr) {
4969             ++it;
4970             continue;
4971         }
4972         if (currentSurfaceNode->GetVisibleRegion().IsEmpty()) {
4973             ++it;
4974             continue;
4975         }
4976         auto lastDisplayDirtyRegion = displayDirtyManager->GetCurrentFrameDirtyRegion();
4977         // child node (component) has filter
4978         CalcChildFilterNodeDirtyRegion(currentSurfaceNode, displayNode);
4979         // surfaceNode self has filter
4980         CalcSurfaceFilterNodeDirtyRegion(currentSurfaceNode, displayNode);
4981         if (lastDisplayDirtyRegion != displayDirtyManager->GetCurrentFrameDirtyRegion()) {
4982             // When DisplayDirtyRegion is changed, collect dirty filter region from begin.
4983             // After all filter region is added, the cycle will definitely stop. there is no risk of a dead cycle.
4984             it = displayNode->GetCurAllSurfaces().begin();
4985         } else {
4986             ++it;
4987         }
4988     }
4989 }
4990 
AddContainerDirtyToGlobalDirty(std::shared_ptr<RSDisplayRenderNode> & node) const4991 void RSUniRenderVisitor::AddContainerDirtyToGlobalDirty(std::shared_ptr<RSDisplayRenderNode>& node) const
4992 {
4993     RS_OPTIONAL_TRACE_FUNC();
4994     auto displayDirtyManager = node->GetDirtyManager();
4995     for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
4996         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4997         if (surfaceNode == nullptr) {
4998             continue;
4999         }
5000         if (!surfaceNode->IsNodeDirty()) {
5001             continue;
5002         }
5003         auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
5004         if (surfaceDirtyManager == nullptr) {
5005             continue;
5006         }
5007         RectI surfaceDirtyRect = surfaceDirtyManager->GetCurrentFrameDirtyRegion();
5008         auto surfaceDirtyRegion = Occlusion::Region{Occlusion::Rect{surfaceDirtyRect}};
5009         if (surfaceNode->HasContainerWindow()) {
5010             // If a surface's dirty is intersect with container region (which can be considered transparent)
5011             // should be added to display dirty region.
5012             // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
5013             auto containerRegion = surfaceNode->GetContainerRegion();
5014             auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
5015             if (!containerDirtyRegion.IsEmpty()) {
5016                 RS_LOGD("CalcDirtyDisplayRegion merge containerDirtyRegion %{public}s region %{public}s",
5017                     surfaceNode->GetName().c_str(), containerDirtyRegion.GetRegionInfo().c_str());
5018                 // plan: we can use surfacenode's absrect as containerRegion's bound
5019                 const auto& rect = containerRegion.GetBoundRef();
5020                 displayDirtyManager->MergeDirtyRect(
5021                     RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
5022                 continue;
5023             }
5024         }
5025         // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
5026         // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
5027         // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
5028         // which include transparent region but not counted in display dirtyregion)
5029         auto transparentRegion = surfaceNode->GetTransparentRegion();
5030         Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
5031         if (!transparentDirtyRegion.IsEmpty()) {
5032             RS_LOGD("CalcDirtyDisplayRegion merge TransparentDirtyRegion %{public}s region %{public}s",
5033                 surfaceNode->GetName().c_str(), transparentDirtyRegion.GetRegionInfo().c_str());
5034             const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
5035             for (const auto& rect : rects) {
5036                 displayDirtyManager->MergeDirtyRect(
5037                     RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
5038             }
5039         }
5040     }
5041 }
5042 
CheckAndSetNodeCacheType(RSRenderNode & node)5043 void RSUniRenderVisitor::CheckAndSetNodeCacheType(RSRenderNode& node)
5044 {
5045     if (node.IsStaticCached()) {
5046         if (node.GetCacheType() != CacheType::CONTENT) {
5047             node.SetCacheType(CacheType::CONTENT);
5048             RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5049         }
5050 
5051         if (!node.GetCompletedCacheSurface(threadIndex_, true) && UpdateCacheSurface(node)) {
5052             node.UpdateCompletedCacheSurface();
5053         }
5054     } else if (isDrawingCacheEnabled_ && GenerateNodeContentCache(node)) {
5055         UpdateCacheRenderNodeMapWithBlur(node);
5056     } else {
5057         if (node.GetCacheType() != CacheType::NONE) {
5058             node.SetCacheType(CacheType::NONE);
5059             if (node.GetCompletedCacheSurface(threadIndex_, false)) {
5060                 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5061             }
5062         }
5063         // label this frame not run CheckAndSetNodeCacheType, means not run drawCacheWithBlur
5064         notRunCheckAndSetNodeCacheType_ = true;
5065     }
5066 }
5067 
UpdateCacheSurface(RSRenderNode & node)5068 bool RSUniRenderVisitor::UpdateCacheSurface(RSRenderNode& node)
5069 {
5070     RS_TRACE_NAME_FMT("UpdateCacheSurface: [%llu]", node.GetId());
5071     CacheType cacheType = node.GetCacheType();
5072     if (cacheType == CacheType::NONE) {
5073         return false;
5074     }
5075 
5076     if (!node.GetCacheSurface(threadIndex_, true)) {
5077         RSRenderNode::ClearCacheSurfaceFunc func = &RSUniRenderUtil::ClearNodeCacheSurface;
5078         node.InitCacheSurface(canvas_ ? canvas_->GetGPUContext().get() : nullptr, func, threadIndex_);
5079     }
5080     auto surface = node.GetCacheSurface(threadIndex_, true);
5081     if (!surface) {
5082         RS_LOGE("Get CacheSurface failed");
5083         return false;
5084     }
5085     auto cacheCanvas = std::make_shared<RSPaintFilterCanvas>(surface.get());
5086     if (!cacheCanvas) {
5087         return false;
5088     }
5089 
5090     // copy current canvas properties into cacheCanvas
5091     if (renderEngine_) {
5092         cacheCanvas->SetHighContrast(renderEngine_->IsHighContrastEnabled());
5093     }
5094     if (canvas_) {
5095         cacheCanvas->CopyConfigurationToOffscreenCanvas(*canvas_);
5096     }
5097     // Using filter cache in multi-thread environment may cause GPU memory leak or invalid textures, so we explicitly
5098     // disable it in sub-thread.
5099     cacheCanvas->SetDisableFilterCache(isSubThread_);
5100 
5101     // When drawing CacheSurface, all child node should be drawn.
5102     // So set isOpDropped_ = false here.
5103     bool isOpDropped = isOpDropped_;
5104     isOpDropped_ = false;
5105     isUpdateCachedSurface_ = true;
5106 
5107     cacheCanvas->Clear(Drawing::Color::COLOR_TRANSPARENT);
5108 
5109     swap(cacheCanvas, canvas_);
5110     // When cacheType == CacheType::ANIMATE_PROPERTY,
5111     // we should draw AnimateProperty on cacheCanvas
5112     const auto& property = node.GetRenderProperties();
5113     if (cacheType == CacheType::ANIMATE_PROPERTY) {
5114         if (property.IsShadowValid()
5115             && !property.IsSpherizeValid()) {
5116             canvas_->Save();
5117             canvas_->Translate(node.GetShadowRectOffsetX(), node.GetShadowRectOffsetY());
5118         }
5119         node.ProcessAnimatePropertyBeforeChildren(*canvas_);
5120     }
5121     if (node.IsNodeGroupIncludeProperty()) {
5122         node.ProcessAnimatePropertyBeforeChildren(*canvas_);
5123     }
5124     if (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE) {
5125         node.SetDrawingCacheRootId(node.GetId());
5126     }
5127 
5128     node.ProcessRenderContents(*canvas_);
5129     // Set a count to label the ProcessChildren in updateCacheProcess
5130     updateCacheProcessCnt_++;
5131     ProcessChildren(node);
5132     updateCacheProcessCnt_--;
5133 
5134     if (cacheType == CacheType::ANIMATE_PROPERTY) {
5135         if (node.GetRenderProperties().IsShadowValid()
5136             && !node.GetRenderProperties().IsSpherizeValid()) {
5137             canvas_->Restore();
5138         }
5139         node.ProcessAnimatePropertyAfterChildren(*canvas_);
5140     }
5141     swap(cacheCanvas, canvas_);
5142 
5143     isUpdateCachedSurface_ = false;
5144     isOpDropped_ = isOpDropped;
5145 
5146     // To get all FreezeNode
5147     // execute: "param set rosen.dumpsurfacetype.enabled 2 && setenforce 0"
5148     // To get specific FreezeNode
5149     // execute: "param set rosen.dumpsurfacetype.enabled 1 && setenforce 0 && "
5150     // "param set rosen.dumpsurfaceid "NodeId" "
5151     // Png file could be found in /data
5152     RSBaseRenderUtil::WriteCacheRenderNodeToPng(node);
5153     return true;
5154 }
5155 
DrawSpherize(RSRenderNode & node)5156 void RSUniRenderVisitor::DrawSpherize(RSRenderNode& node)
5157 {
5158     if (node.GetCacheType() != CacheType::ANIMATE_PROPERTY) {
5159         node.SetCacheType(CacheType::ANIMATE_PROPERTY);
5160         RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5161     }
5162     if (!node.GetCompletedCacheSurface(threadIndex_, true) && UpdateCacheSurface(node)) {
5163         node.UpdateCompletedCacheSurface();
5164     }
5165     node.ProcessTransitionBeforeChildren(*canvas_);
5166     RSPropertiesPainter::DrawSpherize(
5167         node.GetRenderProperties(), *canvas_, node.GetCompletedCacheSurface(threadIndex_, true));
5168     node.ProcessTransitionAfterChildren(*canvas_);
5169 }
5170 
DrawBlurInCache(RSRenderNode & node)5171 bool RSUniRenderVisitor::DrawBlurInCache(RSRenderNode& node)
5172 {
5173     if (LIKELY(curCacheFilterRects_.empty())) {
5174         return false;
5175     }
5176     const auto& property = node.GetRenderProperties();
5177     if (curCacheFilterRects_.top().count(node.GetId())) {
5178         if (curGroupedNodes_.empty()) {
5179             // draw filter before drawing cached surface
5180             curCacheFilterRects_.top().erase(node.GetId());
5181             if (curCacheFilterRects_.empty() || !node.ChildHasVisibleFilter()) {
5182                 // no filter to draw, return
5183                 return true;
5184             }
5185         } else if (property.GetShadowColorStrategy() !=
5186             SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE) {
5187             // clear hole while generating cache surface
5188             Drawing::AutoCanvasRestore arc(*canvas_.get(), true);
5189             RectI shadowRect;
5190             auto rrect = property.GetRRect();
5191             RSPropertiesPainter::GetShadowDirtyRect(shadowRect, property, &rrect, false, false);
5192             std::shared_ptr<Drawing::CoreCanvasImpl> coreCanvas = canvas_->GetCanvasData();
5193             auto skiaCanvas = static_cast<Drawing::SkiaCanvas *>(coreCanvas.get());
5194             SkCanvasPriv::ResetClip(skiaCanvas->ExportSkCanvas());
5195             canvas_->ClipRect(Drawing::Rect(shadowRect.left_, shadowRect.top_,
5196                 shadowRect.width_ + shadowRect.left_, shadowRect.height_ + shadowRect.top_));
5197             canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
5198         } else if (property.GetBackgroundFilter() || property.GetUseEffect()) {
5199             // clear hole while generating cache surface
5200             Drawing::AutoCanvasRestore arc(*canvas_, true);
5201             if (property.GetClipBounds() != nullptr) {
5202                 canvas_->ClipRect(RSPropertiesPainter::Rect2DrawingRect(property.GetBoundsRect()),
5203                     Drawing::ClipOp::INTERSECT, false);
5204             } else {
5205                 canvas_->ClipRoundRect(RSPropertiesPainter::RRect2DrawingRRect(property.GetRRect()),
5206                     Drawing::ClipOp::INTERSECT, false);
5207             }
5208             canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
5209         }
5210     } else if (curGroupedNodes_.empty() && !node.ChildHasVisibleFilter()) {
5211         // no filter to draw, return
5212         return true;
5213     }
5214     return false;
5215 }
5216 
DrawChildCanvasRenderNode(RSRenderNode & node)5217 void RSUniRenderVisitor::DrawChildCanvasRenderNode(RSRenderNode& node)
5218 {
5219      if (node.GetCacheType() == CacheType::NONE) {
5220         if (node.IsPureContainer()) {
5221             processedPureContainerNode_++;
5222             node.ApplyBoundsGeometry(*canvas_);
5223             goto process;
5224         } else if (node.IsContentNode()) {
5225             node.ApplyBoundsGeometry(*canvas_);
5226             node.ApplyAlpha(*canvas_);
5227             node.ProcessRenderContents(*canvas_);
5228             process:
5229                 ProcessChildren(node);
5230                 node.RSRenderNode::ProcessTransitionAfterChildren(*canvas_);
5231                 return;
5232         }
5233     }
5234     DrawChildRenderNode(node);
5235 }
5236 
DrawChildRenderNode(RSRenderNode & node)5237 void RSUniRenderVisitor::DrawChildRenderNode(RSRenderNode& node)
5238 {
5239     CacheType cacheType = node.GetCacheType();
5240     node.ProcessTransitionBeforeChildren(*canvas_);
5241     switch (cacheType) {
5242         case CacheType::NONE: {
5243             auto preCache = canvas_->GetCacheType();
5244             if (node.HasCacheableAnim() && isDrawingCacheEnabled_) {
5245                 canvas_->SetCacheType(RSPaintFilterCanvas::CacheType::ENABLED);
5246             }
5247             node.ProcessAnimatePropertyBeforeChildren(*canvas_);
5248             node.ProcessRenderContents(*canvas_);
5249             ProcessChildren(node);
5250             node.ProcessAnimatePropertyAfterChildren(*canvas_);
5251             if (node.HasCacheableAnim() && isDrawingCacheEnabled_) {
5252                 canvas_->SetCacheType(preCache);
5253             }
5254             break;
5255         }
5256         case CacheType::CONTENT: {
5257             if (node.IsNodeGroupIncludeProperty()) {
5258                 node.ProcessAnimatePropertyBeforeChildren(*canvas_, false);
5259             } else {
5260                 node.ProcessAnimatePropertyBeforeChildren(*canvas_);
5261             }
5262             node.DrawCacheSurface(*canvas_, threadIndex_, false);
5263             node.ProcessAnimatePropertyAfterChildren(*canvas_);
5264             cacheRenderNodeMapRects_[node.GetId()] = node.GetOldDirtyInSurface();
5265             break;
5266         }
5267         case CacheType::ANIMATE_PROPERTY: {
5268             node.DrawCacheSurface(*canvas_, threadIndex_, false);
5269             break;
5270         }
5271         default:
5272             break;
5273     }
5274     node.ProcessTransitionAfterChildren(*canvas_);
5275 }
5276 
CheckIfSurfaceRenderNodeNeedProcess(RSSurfaceRenderNode & node,bool & keepFilterCache)5277 bool RSUniRenderVisitor::CheckIfSurfaceRenderNodeNeedProcess(RSSurfaceRenderNode& node, bool& keepFilterCache)
5278 {
5279     if (isSubThread_) {
5280         return true;
5281     }
5282     if (RSMainThread::Instance()->GetCacheCmdSkippedNodes().count(node.GetId()) != 0) {
5283         return true;
5284     }
5285     if (isSecurityDisplay_ && node.GetSkipLayer()) {
5286         RS_PROCESS_TRACE(isPhone_, node.GetName() + " SkipLayer Skip");
5287         return false;
5288     }
5289     if (!node.ShouldPaint()) {
5290         MarkSubHardwareEnableNodeState(node);
5291         RS_OPTIONAL_TRACE_NAME(node.GetName() + " Node should not paint Skip");
5292         RS_LOGD("RSUniRenderVisitor::IfSurfaceRenderNodeNeedProcess node: %{public}" PRIu64 " invisible",
5293             node.GetId());
5294         return false;
5295     }
5296     if (!node.GetOcclusionVisible() && isOcclusionEnabled_ && !isSecurityDisplay_) {
5297         MarkSubHardwareEnableNodeState(node);
5298         if (!node.GetVisibleRegionForCallBack().IsEmpty()) {
5299             keepFilterCache = true;
5300         }
5301         RS_PROCESS_TRACE(isPhone_, node.GetName() + " Occlusion Skip");
5302         return false;
5303     }
5304     if (node.IsAbilityComponent() && node.GetDstRect().IsEmpty() && curGroupedNodes_.empty()) {
5305         RS_PROCESS_TRACE(isPhone_, node.GetName() + " Empty AbilityComponent Skip");
5306         return false;
5307     }
5308     std::vector<std::shared_ptr<RSSurfaceRenderNode>> appNodes;
5309     if (node.LeashWindowRelatedAppWindowOccluded(appNodes) && !isSecurityDisplay_) {
5310         for (const auto& appNode : appNodes) {
5311             if (appNode) {
5312                 MarkSubHardwareEnableNodeState(*appNode);
5313             }
5314         }
5315         RS_PROCESS_TRACE(isPhone_, node.GetName() + " App Occluded Leashwindow Skip");
5316         return false;
5317     }
5318     if (!screenInfo_.whiteList.empty() && virtualScreenWhiteListRootId_ == INVALID_NODEID) {
5319         RS_PROCESS_TRACE(isPhone_, node.GetName() + " skip because it isn't filtered App");
5320         RS_LOGD("RSUniRenderVisitor::CheckIfSurfaceRenderNodeNeedProcess:\
5321             %{public}s skip because it isn't filtered App", node.GetName().c_str());
5322         return false;
5323     }
5324     return true;
5325 }
5326 
ForceHardwareComposer(RSSurfaceRenderNode & node) const5327 bool RSUniRenderVisitor::ForceHardwareComposer(RSSurfaceRenderNode& node) const
5328 {
5329     auto bufferPixelFormat = node.GetRSSurfaceHandler()->GetBuffer()->GetFormat();
5330     return (bufferPixelFormat == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
5331          bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCBCR_P010 ||
5332          bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCRCB_P010) && !node.IsHardwareForcedDisabledByFilter() &&
5333          !isUpdateCachedSurface_;
5334 }
5335 
UpdateSrcRectForHwcNode(RSSurfaceRenderNode & node,bool isProtected)5336 bool RSUniRenderVisitor::UpdateSrcRectForHwcNode(RSSurfaceRenderNode& node, bool isProtected)
5337 {
5338     Drawing::AutoCanvasRestore acr(*canvas_.get(), true);
5339 
5340     if (displayNodeMatrix_.has_value()) {
5341         auto& displayNodeMatrix = displayNodeMatrix_.value();
5342         auto matrix = canvas_->GetTotalMatrix();
5343         matrix.PostConcat(displayNodeMatrix);
5344         canvas_->SetMatrix(matrix);
5345     }
5346     node.SetTotalMatrix(canvas_->GetTotalMatrix());
5347 
5348     auto dstRect = node.GetDstRect();
5349     Drawing::RectI dst = { dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetRight(),
5350                            dstRect.GetBottom() };
5351     bool hasRotation = false;
5352     if (node.GetRSSurfaceHandler()->GetConsumer() != nullptr) {
5353         auto rotation = RSBaseRenderUtil::GetRotateTransform(RSBaseRenderUtil::GetSurfaceBufferTransformType(
5354             node.GetRSSurfaceHandler()->GetConsumer(), node.GetRSSurfaceHandler()->GetBuffer()));
5355         hasRotation = rotation == GRAPHIC_ROTATE_90 || rotation == GRAPHIC_ROTATE_270;
5356     }
5357     node.UpdateSrcRect(*canvas_, dst, hasRotation);
5358     return isProtected ? true : !node.IsHardwareDisabledBySrcRect();
5359 }
5360 
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)5361 void RSUniRenderVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
5362 {
5363     RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5364 }
5365 
ProcessProxyRenderNode(RSProxyRenderNode & node)5366 void RSUniRenderVisitor::ProcessProxyRenderNode(RSProxyRenderNode& node)
5367 {
5368     RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5369 }
5370 
ProcessRootRenderNode(RSRootRenderNode & node)5371 void RSUniRenderVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
5372 {
5373     RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5374 }
5375 
GenerateNodeContentCache(RSRenderNode & node)5376 bool RSUniRenderVisitor::GenerateNodeContentCache(RSRenderNode& node)
5377 {
5378     // Node cannot have cache.
5379     if (node.GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE) {
5380         if (node.cacheCnt_ > 0) {
5381             node.SetCacheType(CacheType::NONE);
5382             RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5383             node.cacheCnt_ = -1;
5384         }
5385         return false;
5386     }
5387 
5388     // The node goes down the tree to clear the cache.
5389     if (node.GetCacheType() == CacheType::NONE && node.cacheCnt_ > 0) {
5390         node.cacheCnt_ = -1;
5391     }
5392     return true;
5393 }
5394 
ClearRenderGroupCache()5395 void RSUniRenderVisitor::ClearRenderGroupCache()
5396 {
5397     std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
5398     cacheRenderNodeMap.clear();
5399 }
5400 
InitNodeCache(RSRenderNode & node)5401 bool RSUniRenderVisitor::InitNodeCache(RSRenderNode& node)
5402 {
5403     if (node.GetDrawingCacheType() == RSDrawingCacheType::FORCED_CACHE ||
5404         node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
5405         if (node.cacheCnt_ == -1 || (!node.IsStaticCached() && node.NeedInitCacheCompletedSurface())) {
5406             RenderParam val { node.shared_from_this(), canvas_->GetCanvasStatus() };
5407             curGroupedNodes_.push(val);
5408             node.SetCacheType(CacheType::CONTENT);
5409             RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5410             if (UpdateCacheSurface(node)) {
5411                 node.UpdateCompletedCacheSurface();
5412                 node.cacheCnt_++;
5413                 cacheReuseTimes = 0;
5414                 node.ResetDrawingCacheNeedUpdate();
5415             }
5416             curGroupedNodes_.pop();
5417             return true;
5418         }
5419     }
5420     return false;
5421 }
5422 
ChangeCacheRenderNodeMap(RSRenderNode & node,const uint32_t count)5423 void RSUniRenderVisitor::ChangeCacheRenderNodeMap(RSRenderNode& node, const uint32_t count)
5424 {
5425     std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
5426     cacheRenderNodeMap[node.GetId()] = count;
5427 }
5428 
UpdateCacheRenderNodeMapWithBlur(RSRenderNode & node)5429 void RSUniRenderVisitor::UpdateCacheRenderNodeMapWithBlur(RSRenderNode& node)
5430 {
5431     curCacheFilterRects_.push(allCacheFilterRects_[node.GetId()]);
5432     auto canvasType = canvas_->GetCacheType();
5433     canvas_->SetCacheType(RSPaintFilterCanvas::CacheType::OFFSCREEN);
5434     UpdateCacheRenderNodeMap(node);
5435     canvas_->SetCacheType(canvasType);
5436     RS_TRACE_NAME_FMT("Draw cache with blur [%llu]", node.GetId());
5437     Drawing::AutoCanvasRestore arc(*canvas_, true);
5438     auto nodeType = node.GetCacheType();
5439     node.SetCacheType(CacheType::NONE);
5440     bool isOpDropped = isOpDropped_;
5441     isOpDropped_ = false;
5442     // Label the ProcessChildren in drawCacheWithBlur
5443     drawCacheWithBlur_ = true;
5444     DrawChildRenderNode(node);
5445     isOpDropped_ = isOpDropped;
5446     drawCacheWithBlur_ = false;
5447     node.SetCacheType(nodeType);
5448     curCacheFilterRects_.pop();
5449 }
5450 
UpdateCacheRenderNodeMap(RSRenderNode & node)5451 void RSUniRenderVisitor::UpdateCacheRenderNodeMap(RSRenderNode& node)
5452 {
5453     if (InitNodeCache(node)) {
5454         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateCacheRenderNodeMap, generate the node cache for the first"
5455             "time, NodeId: %" PRIu64 " ", node.GetId());
5456         return;
5457     }
5458     cacheRenderNodeIsUpdateMap_[node.GetId()] = node.GetDrawingCacheChanged();
5459     if (node.GetDrawingCacheType() == RSDrawingCacheType::FORCED_CACHE) {
5460         // Regardless of the number of consecutive refreshes, the current cache is forced to be updated.
5461         if (node.GetDrawingCacheChanged()) {
5462             RenderParam val { node.shared_from_this(), canvas_->GetCanvasStatus() };
5463             curGroupedNodes_.push(val);
5464             node.SetCacheType(CacheType::CONTENT);
5465             if (UpdateCacheSurface(node)) {
5466                 node.UpdateCompletedCacheSurface();
5467                 node.cacheCnt_++;
5468                 cacheReuseTimes = 0;
5469                 node.ResetDrawingCacheNeedUpdate();
5470             }
5471             curGroupedNodes_.pop();
5472             return;
5473         }
5474     }
5475     if (node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
5476         // If the number of consecutive refreshes exceeds CACHE_MAX_UPDATE_TIME times, the cache is cleaned,
5477         // otherwise the cache is updated.
5478         if (node.GetDrawingCacheChanged()) {
5479             node.cacheCnt_++;
5480             if (node.cacheCnt_ >= CACHE_MAX_UPDATE_TIME) {
5481                 node.SetCacheType(CacheType::NONE);
5482                 node.MarkNodeGroup(RSRenderNode::GROUPED_BY_UI, false, false);
5483                 node.MarkNodeGroup(RSRenderNode::GROUPED_BY_ANIM, false, false);
5484                 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5485                 node.cacheCnt_ = -1;
5486                 cacheReuseTimes = 0;
5487                 return;
5488             }
5489             node.SetCacheType(CacheType::CONTENT);
5490             if (UpdateCacheSurface(node)) {
5491                 node.UpdateCompletedCacheSurface();
5492                 cacheReuseTimes = 0;
5493                 node.ResetDrawingCacheNeedUpdate();
5494             }
5495             curGroupedNodes_.pop();
5496             return;
5497         }
5498     }
5499     // The cache is not refreshed continuously.
5500     node.cacheCnt_ = 0;
5501     cacheReuseTimes++;
5502     RS_OPTIONAL_TRACE_NAME("RSUniRenderVisitor::UpdateCacheRenderNodeMap ,NodeId: " + std::to_string(node.GetId()) +
5503         " ,CacheRenderNodeMapCnt: " + std::to_string(cacheReuseTimes));
5504 }
5505 
ProcessCanvasRenderNode(RSCanvasRenderNode & node)5506 void RSUniRenderVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
5507 {
5508     RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5509 }
5510 
ProcessEffectRenderNode(RSEffectRenderNode & node)5511 void RSUniRenderVisitor::ProcessEffectRenderNode(RSEffectRenderNode& node)
5512 {
5513     RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5514 }
5515 
ClosePartialRenderWhenAnimatingWindows(std::shared_ptr<RSDisplayRenderNode> & node)5516 void RSUniRenderVisitor::ClosePartialRenderWhenAnimatingWindows(std::shared_ptr<RSDisplayRenderNode>& node)
5517 {
5518     if (!doAnimate_) {
5519         return;
5520     }
5521     if (appWindowNum_ > PHONE_MAX_APP_WINDOW_NUM) {
5522         node->GetDirtyManager()->MergeSurfaceRect();
5523     } else {
5524         isPartialRenderEnabled_ = false;
5525         isOpDropped_ = false;
5526         RS_TRACE_NAME("ClosePartialRender 0 Window Animation");
5527     }
5528 }
5529 
SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams> & renderThreadParams)5530 void RSUniRenderVisitor::SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams>& renderThreadParams)
5531 {
5532     if (!renderThreadParams) {
5533         RS_LOGE("RSUniRenderVisitor::SetUniRenderThreadParam renderThreadParams is nullptr");
5534         return;
5535     }
5536     renderThreadParams->isPartialRenderEnabled_ = isPartialRenderEnabled_;
5537     renderThreadParams->isRegionDebugEnabled_ = isRegionDebugEnabled_;
5538     renderThreadParams->isDirtyRegionDfxEnabled_ = isDirtyRegionDfxEnabled_;
5539     renderThreadParams->isDisplayDirtyDfxEnabled_ = isDisplayDirtyDfxEnabled_;
5540     renderThreadParams->isOpaqueRegionDfxEnabled_ = isOpaqueRegionDfxEnabled_;
5541     renderThreadParams->isVisibleRegionDfxEnabled_ = isVisibleRegionDfxEnabled_;
5542     renderThreadParams->isAllSurfaceVisibleDebugEnabled_ = isAllSurfaceVisibleDebugEnabled_;
5543     renderThreadParams->isTargetDirtyRegionDfxEnabled_ = isTargetDirtyRegionDfxEnabled_;
5544     renderThreadParams->dirtyRegionDebugType_ = dirtyRegionDebugType_;
5545     renderThreadParams->isOpDropped_ = isOpDropped_;
5546     renderThreadParams->isUIFirstDebugEnable_ = isUIFirstDebugEnable_;
5547     renderThreadParams->dfxTargetSurfaceNames_ = std::move(dfxTargetSurfaceNames_);
5548     renderThreadParams->isVirtualDirtyEnabled_ = isVirtualDirtyEnabled_;
5549     renderThreadParams->isVirtualDirtyDfxEnabled_ = isVirtualDirtyDfxEnabled_;
5550     renderThreadParams->isExpandScreenDirtyEnabled_ = isExpandScreenDirtyEnabled_;
5551     renderThreadParams->hasMirrorDisplay_ = hasMirrorDisplay_;
5552 }
5553 
SetHardwareEnabledNodes(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & hardwareEnabledNodes)5554 void RSUniRenderVisitor::SetHardwareEnabledNodes(
5555     const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& hardwareEnabledNodes)
5556 {
5557     hardwareEnabledNodes_ = hardwareEnabledNodes;
5558 }
5559 
DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode)5560 bool RSUniRenderVisitor::DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
5561 {
5562     auto children = rootNode->GetChildren();
5563     if (!IsHardwareComposerEnabled() || children->empty()) {
5564         RS_LOGD("RSUniRenderVisitor::DoDirectComposition HardwareComposer disabled");
5565         return false;
5566     }
5567     RS_TRACE_NAME("DoDirectComposition");
5568     auto& child = children->front();
5569     if (child == nullptr || !child->IsInstanceOf<RSDisplayRenderNode>()) {
5570         RS_LOGE("RSUniRenderVisitor::DoDirectComposition child type not match");
5571         return false;
5572     }
5573     auto displayNode = child->ReinterpretCastTo<RSDisplayRenderNode>();
5574     if (!displayNode ||
5575         displayNode->GetCompositeType() != RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE) {
5576         RS_LOGE("RSUniRenderVisitor::DoDirectComposition displayNode state error");
5577         return false;
5578     }
5579     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
5580     screenInfo_ = screenManager->QueryScreenInfo(displayNode->GetScreenId());
5581     if (screenInfo_.state != ScreenState::HDI_OUTPUT_ENABLE) {
5582         RS_LOGE("RSUniRenderVisitor::DoDirectComposition: ScreenState error!");
5583         return false;
5584     }
5585     processor_ = RSProcessorFactory::CreateProcessor(displayNode->GetCompositeType());
5586     if (processor_ == nullptr || renderEngine_ == nullptr) {
5587         RS_LOGE("RSUniRenderVisitor::DoDirectComposition: RSProcessor or renderEngine is null!");
5588         return false;
5589     }
5590 
5591     if (!processor_->Init(*displayNode, displayNode->GetDisplayOffsetX(), displayNode->GetDisplayOffsetY(),
5592         INVALID_SCREEN_ID, renderEngine_)) {
5593         RS_LOGE("RSUniRenderVisitor::DoDirectComposition: processor init failed!");
5594         return false;
5595     }
5596 
5597     if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
5598         RS_LOGW("RSUniRenderVisitor::DoDirectComposition: hardwareThread task has too many to Execute");
5599     }
5600     if (!RSMainThread::Instance()->CheckIsHardwareEnabledBufferUpdated()) {
5601         for (auto& surfaceNode: hardwareEnabledNodes_) {
5602             if (!surfaceNode->IsHardwareForcedDisabled()) {
5603                 surfaceNode->MarkCurrentFrameHardwareEnabled();
5604             }
5605         }
5606         RS_TRACE_NAME("DoDirectComposition skip commit");
5607         return true;
5608     }
5609     processor_->ProcessDisplaySurface(*displayNode);
5610     for (auto& node: hardwareEnabledNodes_) {
5611         if (!node->IsHardwareForcedDisabled()) {
5612             processor_->ProcessSurface(*node);
5613         }
5614     }
5615     DoScreenRcdTask(processor_, rcdInfo_, screenInfo_);
5616     processor_->PostProcess();
5617     RS_LOGD("RSUniRenderVisitor::DoDirectComposition end");
5618     return true;
5619 }
5620 
DrawWatermarkIfNeed(RSDisplayRenderNode & node,bool isMirror)5621 void RSUniRenderVisitor::DrawWatermarkIfNeed(RSDisplayRenderNode& node, bool isMirror)
5622 {
5623     if (RSMainThread::Instance()->GetWatermarkFlag()) {
5624         auto screenManager = CreateOrGetScreenManager();
5625         auto mainScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
5626         auto mainWidth = static_cast<float>(mainScreenInfo.width);
5627         auto mainHeight = static_cast<float>(mainScreenInfo.height);
5628         if (RSSystemProperties::IsFoldScreenFlag() && node.GetScreenId() == 0 && isMirror) {
5629             std::swap(mainWidth, mainHeight);
5630         }
5631         std::shared_ptr<Drawing::Image> drImage = RSMainThread::Instance()->GetWatermarkImg();
5632         if (drImage == nullptr) {
5633             return;
5634         }
5635 
5636         Drawing::SaveLayerOps slr(nullptr, nullptr, Drawing::SaveLayerOps::INIT_WITH_PREVIOUS);
5637         canvas_->SaveLayer(slr); // avoid abnormal dsicard
5638         Drawing::Brush rectPaint;
5639         canvas_->AttachBrush(rectPaint);
5640         auto srcRect = Drawing::Rect(0, 0, drImage->GetWidth(), drImage->GetHeight());
5641         auto dstRect = Drawing::Rect(0, 0, mainWidth, mainHeight);
5642         canvas_->DrawImageRect(*drImage, srcRect, dstRect, Drawing::SamplingOptions(),
5643             Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
5644         canvas_->DetachBrush();
5645         canvas_->Restore();
5646     }
5647 }
5648 
SetAppWindowNum(uint32_t num)5649 void RSUniRenderVisitor::SetAppWindowNum(uint32_t num)
5650 {
5651     appWindowNum_ = num;
5652 }
5653 
5654 #ifdef ENABLE_RECORDING_DCL
tryCapture(float width,float height)5655 void RSUniRenderVisitor::tryCapture(float width, float height)
5656 {
5657     if (!RSSystemProperties::GetRecordingEnabled()) {
5658 #ifdef RS_PROFILER_ENABLED
5659         if (auto canvas = RSCaptureRecorder::GetInstance().TryInstantCapture(width, height)) {
5660             canvas_->AddCanvas(canvas);
5661         }
5662 #endif
5663         return;
5664     }
5665     recordingCanvas_ = std::make_unique<ExtendRecordingCanvas>(width, height);
5666     RS_TRACE_NAME("RSUniRender:Recording begin");
5667 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
5668     auto renderContext = RSMainThread::Instance()->GetRenderEngine()->GetRenderContext();
5669     recordingCanvas_->SetGrRecordingContext(renderContext->GetSharedDrGPUContext());
5670 #endif
5671     canvas_->AddCanvas(recordingCanvas_.get());
5672     RSRecordingThread::Instance(renderEngine_->GetRenderContext().get()).CheckAndRecording();
5673 }
5674 
endCapture() const5675 void RSUniRenderVisitor::endCapture() const
5676 {
5677     if (!RSRecordingThread::Instance(renderEngine_->GetRenderContext().get()).GetRecordingEnabled()) {
5678 #ifdef RS_PROFILER_ENABLED
5679         RSCaptureRecorder::GetInstance().EndInstantCapture();
5680 #endif
5681         return;
5682     }
5683     auto drawCmdList = recordingCanvas_->GetDrawCmdList();
5684     RS_TRACE_NAME("RSUniRender:RecordingToFile curFrameNum = " +
5685         std::to_string(RSRecordingThread::Instance(renderEngine_->GetRenderContext().get()).GetCurDumpFrame()));
5686     RSRecordingThread::Instance(renderEngine_->GetRenderContext().get()).RecordingToFile(drawCmdList);
5687 }
5688 #endif
5689 
RotateMirrorCanvasIfNeed(RSDisplayRenderNode & node,bool canvasRotation)5690 void RSUniRenderVisitor::RotateMirrorCanvasIfNeed(RSDisplayRenderNode& node, bool canvasRotation)
5691 {
5692     auto mirrorNode = node.GetMirrorSource().lock();
5693     if ((canvasRotation && (RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0)) ||
5694         (!canvasRotation && !(RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0))) {
5695         return;
5696     }
5697     auto screenManager = CreateOrGetScreenManager();
5698     auto mainScreenInfo = screenManager->QueryScreenInfo(mirrorNode->GetScreenId());
5699     auto mainWidth = static_cast<float>(mainScreenInfo.width);
5700     auto mainHeight = static_cast<float>(mainScreenInfo.height);
5701     auto rotation = mirrorNode->GetScreenRotation();
5702     if (RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) {
5703         if (rotation == ScreenRotation::ROTATION_0 || rotation == ScreenRotation::ROTATION_180) {
5704             std::swap(mainWidth, mainHeight);
5705         }
5706         auto oriRotation = node.GetOriginScreenRotation();
5707         rotation = static_cast<ScreenRotation>((static_cast<int>(oriRotation) -
5708             static_cast<int>(rotation) + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
5709     }
5710     if (rotation != ScreenRotation::ROTATION_0) {
5711         if (rotation == ScreenRotation::ROTATION_90) {
5712             canvas_->Rotate(90, 0, 0);
5713             canvas_->Translate(0, -mainHeight);
5714         } else if (rotation == ScreenRotation::ROTATION_180) {
5715             canvas_->Rotate(180, mainWidth / 2, mainHeight / 2);
5716         } else if (rotation == ScreenRotation::ROTATION_270) {
5717             canvas_->Rotate(270, 0, 0);
5718             canvas_->Translate(-mainWidth, 0);
5719         }
5720     }
5721 }
5722 
ScaleMirrorIfNeed(RSDisplayRenderNode & node,bool canvasRotation)5723 void RSUniRenderVisitor::ScaleMirrorIfNeed(RSDisplayRenderNode& node, bool canvasRotation)
5724 {
5725     auto screenManager = CreateOrGetScreenManager();
5726     auto mirrorNode = node.GetMirrorSource().lock();
5727     if (!screenManager || !mirrorNode) {
5728         RS_LOGE("RSUniRenderVisitor::ScaleMirrorIfNeed screenManager or mirrorNode is nullptr");
5729         return;
5730     }
5731     auto mainScreenInfo = screenManager->QueryScreenInfo(mirrorNode->GetScreenId());
5732     auto mainWidth = static_cast<float>(mainScreenInfo.width);
5733     auto mainHeight = static_cast<float>(mainScreenInfo.height);
5734     auto mirrorWidth = node.GetRenderProperties().GetBoundsWidth();
5735     auto mirrorHeight = node.GetRenderProperties().GetBoundsHeight();
5736     auto scaleMode = screenManager->GetScaleMode(node.GetScreenId());
5737     if (canvasRotation) {
5738         if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) ||
5739             mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_90 ||
5740             mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_270) {
5741             std::swap(mainWidth, mainHeight);
5742         }
5743     } else {
5744         if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0)) {
5745             auto oriRotation = node.GetOriginScreenRotation();
5746             auto curRotation = node.GetScreenRotation();
5747             auto rotation = static_cast<ScreenRotation>((static_cast<int>(oriRotation) -
5748                 static_cast<int>(curRotation) + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
5749             if (rotation == ScreenRotation::ROTATION_0 ||
5750                 rotation == ScreenRotation::ROTATION_180) {
5751                 std::swap(mainWidth, mainHeight);
5752             }
5753         } else {
5754             if ((node.GetOriginScreenRotation() == ScreenRotation::ROTATION_90 ||
5755                 node.GetOriginScreenRotation() == ScreenRotation::ROTATION_270)) {
5756                 std::swap(mirrorWidth, mirrorHeight);
5757             }
5758         }
5759     }
5760     // If the width and height not match the main screen, calculate the dstRect.
5761     if (mainWidth != mirrorWidth || mainHeight != mirrorHeight) {
5762         canvas_->Clear(SK_ColorBLACK);
5763         auto processor = std::static_pointer_cast<RSUniRenderVirtualProcessor>(processor_);
5764         if (!processor) {
5765             RS_LOGE("RSUniRenderVisitor::ScaleMirrorIfNeed processor is nullptr!");
5766             return;
5767         }
5768         if (scaleMode == ScreenScaleMode::FILL_MODE) {
5769             processor->Fill(*canvas_, mainWidth, mainHeight, mirrorWidth, mirrorHeight);
5770         } else if (scaleMode == ScreenScaleMode::UNISCALE_MODE) {
5771             processor->UniScale(*canvas_, mainWidth, mainHeight, mirrorWidth, mirrorHeight);
5772         }
5773     }
5774 }
5775 
SendRcdMessage(RSDisplayRenderNode & node)5776 void RSUniRenderVisitor::SendRcdMessage(RSDisplayRenderNode& node)
5777 {
5778     if ((screenInfo_.state == ScreenState::HDI_OUTPUT_ENABLE) &&
5779         RSSingleton<RoundCornerDisplay>::GetInstance().GetRcdEnable()) {
5780         using rcd_msg = RSSingleton<RsMessageBus>;
5781         rcd_msg::GetInstance().SendMsg<uint32_t, uint32_t>(TOPIC_RCD_DISPLAY_SIZE,
5782             screenInfo_.width, screenInfo_.height);
5783         rcd_msg::GetInstance().SendMsg<ScreenRotation>(TOPIC_RCD_DISPLAY_ROTATION,
5784             node.GetScreenRotation());
5785         rcd_msg::GetInstance().SendMsg<int>(TOPIC_RCD_DISPLAY_NOTCH,
5786             RSSystemParameters::GetHideNotchStatus());
5787     }
5788 }
5789 
RotateMirrorCanvasIfNeedForWiredScreen(RSDisplayRenderNode & node)5790 void RSUniRenderVisitor::RotateMirrorCanvasIfNeedForWiredScreen(RSDisplayRenderNode& node)
5791 {
5792     auto mirrorNode = node.GetMirrorSource().lock();
5793     auto rotation = mirrorNode->GetScreenRotation();
5794     if (RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) {
5795         if (rotation == ScreenRotation::ROTATION_270) {
5796             rotation = ScreenRotation::ROTATION_0;
5797         } else {
5798             rotation = static_cast<ScreenRotation>(static_cast<int>(rotation) + 1);
5799         }
5800     }
5801     if (rotation != ScreenRotation::ROTATION_0) {
5802         auto screenManager = CreateOrGetScreenManager();
5803         auto mainScreenInfo = screenManager->QueryScreenInfo(mirrorNode->GetScreenId());
5804         if (rotation == ScreenRotation::ROTATION_90) {
5805             canvas_->Rotate(RS_ROTATION_90, 0, 0);
5806             canvas_->Translate(0, -(static_cast<float>(mainScreenInfo.height)));
5807         } else if (rotation == ScreenRotation::ROTATION_180) {
5808             float ratio = 0.5f;
5809             canvas_->Rotate(RS_ROTATION_180, static_cast<float>(mainScreenInfo.width) * ratio,
5810                 static_cast<float>(mainScreenInfo.height) * ratio);
5811         } else if (rotation == ScreenRotation::ROTATION_270) {
5812             canvas_->Rotate(RS_ROTATION_270, 0, 0);
5813             canvas_->Translate(-(static_cast<float>(mainScreenInfo.width)), 0);
5814         }
5815     }
5816 }
5817 
ScaleMirrorIfNeedForWiredScreen(RSDisplayRenderNode & node,bool canvasRotation)5818 void RSUniRenderVisitor::ScaleMirrorIfNeedForWiredScreen(RSDisplayRenderNode& node, bool canvasRotation)
5819 {
5820     auto screenManager = CreateOrGetScreenManager();
5821     auto mirrorNode = node.GetMirrorSource().lock();
5822     auto mainScreenInfo = screenManager->QueryScreenInfo(mirrorNode->GetScreenId());
5823     float mainWidth = static_cast<float>(mainScreenInfo.width);
5824     float mainHeight = static_cast<float>(mainScreenInfo.height);
5825     if (canvasRotation) {
5826         if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) ||
5827             mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_90 ||
5828             mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_270) {
5829             std::swap(mainWidth, mainHeight);
5830         }
5831     } else {
5832         if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) ||
5833             node.GetOriginScreenRotation() == ScreenRotation::ROTATION_90 ||
5834             node.GetOriginScreenRotation() == ScreenRotation::ROTATION_270) {
5835             std::swap(mainWidth, mainHeight);
5836         }
5837         if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0 &&
5838             (mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_90 ||
5839             mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_270)) || mirrorAutoRotate_) {
5840             std::swap(mainWidth, mainHeight);
5841         }
5842     }
5843     float boundsWidth = node.GetRenderProperties().GetBoundsWidth();
5844     float boundsHeight = node.GetRenderProperties().GetBoundsHeight();
5845     // If the width and height not match the main screen, calculate the dstRect.
5846     if ((mainWidth != boundsWidth || mainHeight != boundsHeight) &&
5847         (mainWidth > 0 && mainHeight > 0)) {
5848         canvas_->Clear(SK_ColorBLACK);
5849         float mirrorScale = 1.0f; // 1 for init scale
5850         float startX = 0.0f;
5851         float startY = 0.0f;
5852         float mirrorScaleX = boundsWidth / mainWidth;
5853         float mirrorScaleY = boundsHeight / mainHeight;
5854         float ratio = 0.5f;
5855         if (mirrorScaleY < mirrorScaleX) {
5856             mirrorScale = mirrorScaleY;
5857             startX = (boundsWidth - (mirrorScale * mainWidth)) * ratio;
5858         } else {
5859             mirrorScale = mirrorScaleX;
5860             startY = (boundsHeight - (mirrorScale * mainHeight)) * ratio;
5861         }
5862         canvas_->Translate(startX, startY);
5863         canvas_->Scale(mirrorScale, mirrorScale);
5864     }
5865 }
5866 
SetHasSharedTransitionNode(RSSurfaceRenderNode & surfaceNode,bool hasSharedTransitionNode)5867 void RSUniRenderVisitor::SetHasSharedTransitionNode(RSSurfaceRenderNode& surfaceNode, bool hasSharedTransitionNode)
5868 {
5869     // only allow change hasSharedTransitionNode in leash window's child
5870     if (surfaceNode.GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
5871         return;
5872     }
5873     surfaceNode.SetHasSharedTransitionNode(hasSharedTransitionNode);
5874     // sync the change to parent leash window
5875     auto leashNode =
5876         RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surfaceNode.GetParent().lock());
5877     if (leashNode && leashNode->GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
5878         leashNode->SetHasSharedTransitionNode(hasSharedTransitionNode);
5879     }
5880 }
5881 
ProcessUnpairedSharedTransitionNode()5882 void RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode()
5883 {
5884     static auto unpairNode = [](const std::weak_ptr<RSRenderNode>& wptr) {
5885         auto sptr = wptr.lock();
5886         if (sptr == nullptr) {
5887             return;
5888         }
5889         // make sure parent regenerates ChildrenDrawable
5890         auto parent = sptr->GetParent().lock();
5891         if (parent == nullptr) {
5892             return;
5893         }
5894         parent->AddDirtyType(RSModifierType::CHILDREN);
5895         parent->ApplyModifiers();
5896         // avoid changing the paired status or unpairedShareTransitions_
5897         auto param = sptr->GetSharedTransitionParam();
5898         if (param == nullptr) {
5899             ROSEN_LOGE("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: param is null");
5900             return;
5901         }
5902         param->paired_ = false;
5903         SharedTransitionParam::unpairedShareTransitions_.clear();
5904     };
5905     auto unpairedShareTransitions = std::move(SharedTransitionParam::unpairedShareTransitions_);
5906     for (auto& [id, wptr] : unpairedShareTransitions) {
5907         auto sharedTransitionParam = wptr.lock();
5908         // If the unpaired share transition is already deal with, do nothing
5909         if (!sharedTransitionParam) {
5910             continue;
5911         }
5912         if (!sharedTransitionParam->paired_) {
5913             sharedTransitionParam->ResetRelation();
5914             continue;
5915         }
5916         ROSEN_LOGD("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: mark %s as unpaired",
5917             sharedTransitionParam->Dump().c_str());
5918         sharedTransitionParam->paired_ = false;
5919         unpairNode(sharedTransitionParam->inNode_);
5920         unpairNode(sharedTransitionParam->outNode_);
5921         sharedTransitionParam->ResetRelation();
5922     }
5923 }
5924 
FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)5925 NodeId RSUniRenderVisitor::FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)
5926 {
5927     if (node == nullptr) {
5928         return INVALID_NODEID;
5929     }
5930     auto nodeParent = node->GetParent().lock();
5931     if (nodeParent == nullptr) {
5932         return INVALID_NODEID;
5933     }
5934     if (nodeParent->GetType() == RSRenderNodeType::DISPLAY_NODE) {
5935         return node->GetId();
5936     } else {
5937         return FindInstanceChildOfDisplay(nodeParent);
5938     }
5939 }
5940 
CheckIfNeedResetRotate()5941 bool RSUniRenderVisitor::CheckIfNeedResetRotate()
5942 {
5943     if (canvas_ == nullptr) {
5944         return true;
5945     }
5946     auto matrix = canvas_->GetTotalMatrix();
5947     if (displayNodeMatrix_.has_value()) {
5948         matrix.PreConcat(displayNodeMatrix_.value());
5949     }
5950     int angle = RSUniRenderUtil::GetRotationFromMatrix(matrix);
5951     return angle != 0 && angle % RS_ROTATION_90 == 0;
5952 }
5953 
IsOutOfScreenRegion(RectI rect)5954 bool RSUniRenderVisitor::IsOutOfScreenRegion(RectI rect)
5955 {
5956     if (!canvas_) {
5957         return false;
5958     }
5959 
5960     auto deviceClipBounds = canvas_->GetDeviceClipBounds();
5961 
5962     if (rect.GetRight() <= deviceClipBounds.GetLeft() ||
5963         rect.GetLeft() >= deviceClipBounds.GetRight() ||
5964         rect.GetBottom() <= deviceClipBounds.GetTop() ||
5965         rect.GetTop() >= deviceClipBounds.GetBottom()) {
5966         return true;
5967     }
5968 
5969     return false;
5970 }
5971 
DrawCurtainScreen()5972 void RSUniRenderVisitor::DrawCurtainScreen()
5973 {
5974     if (!isCurtainScreenOn_ || !canvas_) {
5975         return;
5976     }
5977     float screenWidth = static_cast<float>(screenInfo_.width);
5978     float screenHeight = static_cast<float>(screenInfo_.height);
5979     Drawing::Brush brush;
5980     brush.SetARGB(MAX_ALPHA, 0, 0, 0); // not transparent black
5981     canvas_->AttachBrush(brush);
5982     canvas_->DrawRect(Drawing::Rect(0, 0, screenWidth, screenHeight));
5983     canvas_->DetachBrush();
5984 }
5985 
CheckColorFilterChange() const5986 bool RSUniRenderVisitor::CheckColorFilterChange() const
5987 {
5988     if (!RSMainThread::Instance()->IsAccessibilityConfigChanged()) {
5989         return false;
5990     }
5991     RS_LOGD("RSUniRenderVisitor::CheckColorFilterChange changed");
5992     return true;
5993 }
5994 
CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr> & surfaces)5995 void RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr>& surfaces)
5996 {
5997     // Debug dirtyregion of show current refreshRation
5998     if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
5999         RectI tempRect = {100, 100, 500, 200};   // setDirtyRegion for RealtimeRefreshRate
6000         bool surfaceNodeSet = false;
6001         for (auto surface : surfaces) {
6002             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
6003             if (surfaceNode == nullptr) {
6004                 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate surfaceNode is nullptr");
6005                 continue;
6006             }
6007             if (surfaceNode->GetName().find(RELIABLE_GESTURE_BACK_SURFACE_NAME) != std::string::npos) {
6008                 // refresh rate rect for mainwindow
6009                 auto& geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
6010                 if (!geoPtr) {
6011                     break;
6012                 }
6013                 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
6014                 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
6015                 surfaceNodeSet = true;
6016                 break;
6017             }
6018         }
6019         if (!surfaceNodeSet) {
6020             auto &geoPtr = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
6021             if (!geoPtr) {
6022                 return;
6023             }
6024             tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
6025             curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
6026         }
6027     }
6028 }
6029 
CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode & node)6030 void RSUniRenderVisitor::CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode& node)
6031 {
6032     bool hasAnim = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
6033     if (!node.IsScale() || hasAnim || curCornerRadius_.IsZero() || curAlpha_ < 1) {
6034         node.SetGpuOverDrawBufferOptimizeNode(false);
6035         return;
6036     }
6037 
6038     for (auto& child : *(node.GetChildren())) {
6039         if (!child || !(child->IsInstanceOf<RSSurfaceRenderNode>() &&
6040             RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashOrMainWindow())) {
6041             continue;
6042         }
6043         auto rootNode = child->GetFirstChild();
6044         if (!rootNode) {
6045             break;
6046         }
6047         auto canvasNode = rootNode->GetFirstChild();
6048         if (!canvasNode) {
6049             break;
6050         }
6051         const auto& surfaceProperties = node.GetRenderProperties();
6052         const auto& canvasProperties = canvasNode->GetRenderProperties();
6053         if (canvasProperties.GetAlpha() >= 1
6054             && canvasProperties.GetBackgroundColor().GetAlpha() >= MAX_ALPHA
6055             && canvasProperties.GetFrameWidth() == surfaceProperties.GetFrameWidth()
6056             && canvasProperties.GetFrameHeight() == surfaceProperties.GetFrameHeight()) {
6057             node.SetGpuOverDrawBufferOptimizeNode(true);
6058             node.SetOverDrawBufferNodeCornerRadius(curCornerRadius_);
6059             return;
6060         }
6061     }
6062 
6063     node.SetGpuOverDrawBufferOptimizeNode(false);
6064 }
6065 
6066 } // namespace Rosen
6067 } // namespace OHOS
6068