• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_render_node.h"
17 
18 #include <algorithm>
19 #include <cstdint>
20 #include <memory>
21 #include <mutex>
22 #include <set>
23 #include <utility>
24 
25 #include "offscreen_render/rs_offscreen_render_thread.h"
26 #include "rs_trace.h"
27 #include "sandbox_utils.h"
28 
29 #include "animation/rs_render_animation.h"
30 #include "common/rs_common_def.h"
31 #include "common/rs_obj_abs_geometry.h"
32 #include "common/rs_optional_trace.h"
33 #include "dirty_region/rs_gpu_dirty_collector.h"
34 #include "dirty_region/rs_optimize_canvas_dirty_collector.h"
35 #include "drawable/rs_misc_drawable.h"
36 #include "drawable/rs_property_drawable_foreground.h"
37 #include "drawable/rs_render_node_drawable_adapter.h"
38 #ifdef RS_MEMORY_INFO_MANAGER
39 #include "feature/memory_info_manager/rs_memory_info_manager.h"
40 #endif
41 #include "modifier_ng/geometry/rs_transform_render_modifier.h"
42 #include "modifier_ng/rs_render_modifier_ng.h"
43 #include "params/rs_render_params.h"
44 #include "pipeline/rs_canvas_drawing_render_node.h"
45 #include "pipeline/rs_context.h"
46 #include "pipeline/rs_screen_render_node.h"
47 #include "pipeline/rs_effect_render_node.h"
48 #include "pipeline/rs_logical_display_render_node.h"
49 #include "pipeline/rs_paint_filter_canvas.h"
50 #include "pipeline/rs_recording_canvas.h"
51 #include "pipeline/rs_render_node_gc.h"
52 #include "pipeline/rs_root_render_node.h"
53 #include "pipeline/rs_surface_render_node.h"
54 #include "pipeline/sk_resource_manager.h"
55 #include "platform/common/rs_log.h"
56 #include "platform/common/rs_system_properties.h"
57 #include "property/rs_point_light_manager.h"
58 #include "property/rs_properties_painter.h"
59 #include "property/rs_property_trace.h"
60 #include "render/rs_foreground_effect_filter.h"
61 #include "transaction/rs_transaction_proxy.h"
62 #include "visitor/rs_node_visitor.h"
63 #include "rs_profiler.h"
64 
65 #ifdef RS_ENABLE_VK
66 #ifdef USE_M133_SKIA
67 #include "include/gpu/ganesh/GrBackendSurface.h"
68 #else
69 #include "include/gpu/GrBackendSurface.h"
70 #endif
71 #include "platform/ohos/backend/native_buffer_utils.h"
72 #include "platform/ohos/backend/rs_vulkan_context.h"
73 #endif
74 
75 namespace OHOS {
76 namespace Rosen {
77 
78 namespace {
79 const std::unordered_set<RSDrawableSlot> edrDrawableSlots = {
80     RSDrawableSlot::FOREGROUND_FILTER,
81     RSDrawableSlot::BACKGROUND_FILTER,
82     RSDrawableSlot::BACKGROUND_NG_SHADER,
83     RSDrawableSlot::COMPOSITING_FILTER,
84     RSDrawableSlot::BLENDER
85 };
86 } // namespace
87 
88 std::unordered_map<pid_t, size_t> RSRenderNode::blurEffectCounter_ = {};
UpdateBlurEffectCounter(int deltaCount)89 void RSRenderNode::UpdateBlurEffectCounter(int deltaCount)
90 {
91     if (LIKELY(deltaCount == 0)) {
92         return;
93     }
94 
95     auto pid = ExtractPid(GetId());
96     // Try to insert pid with value 0 and we got an iterator to the inserted element or to the existing element.
97     auto it = blurEffectCounter_.emplace(std::make_pair(pid, 0)).first;
98     if (deltaCount > 0 || (static_cast<int>(it->second) > -deltaCount)) {
99         it->second += deltaCount;
100     } else {
101         blurEffectCounter_.erase(it);
102     }
103 }
104 
OnRegister(const std::weak_ptr<RSContext> & context)105 void RSRenderNode::OnRegister(const std::weak_ptr<RSContext>& context)
106 {
107     context_ = context;
108     renderProperties_.backref_ = weak_from_this();
109     SetDirty(true);
110     InitRenderParams();
111 }
112 
IsPureContainer() const113 bool RSRenderNode::IsPureContainer() const
114 {
115     return (!GetRenderProperties().isDrawn_ && !GetRenderProperties().alphaNeedApply_ && !HasDrawCmdModifiers());
116 }
117 
IsPureBackgroundColor() const118 bool RSRenderNode::IsPureBackgroundColor() const
119 {
120     static const std::unordered_set<RSDrawableSlot> pureBackgroundColorSlots = {
121         RSDrawableSlot::BG_SAVE_BOUNDS,
122         RSDrawableSlot::CLIP_TO_BOUNDS,
123         RSDrawableSlot::BACKGROUND_COLOR,
124         RSDrawableSlot::BG_RESTORE_BOUNDS,
125         RSDrawableSlot::SAVE_FRAME,
126         RSDrawableSlot::FRAME_OFFSET,
127         RSDrawableSlot::CLIP_TO_FRAME,
128         RSDrawableSlot::CHILDREN,
129         RSDrawableSlot::RESTORE_FRAME
130     };
131     for (int8_t i = 0; i < static_cast<int8_t>(RSDrawableSlot::MAX); ++i) {
132         if (drawableVec_[i] &&
133             !pureBackgroundColorSlots.count(static_cast<RSDrawableSlot>(i))) {
134             return false;
135         }
136     }
137     return true;
138 }
139 
SetDrawNodeType(DrawNodeType nodeType)140 void RSRenderNode::SetDrawNodeType(DrawNodeType nodeType)
141 {
142     drawNodeType_ = nodeType;
143 }
144 
GetDrawNodeType() const145 DrawNodeType RSRenderNode::GetDrawNodeType() const
146 {
147     return drawNodeType_;
148 }
149 
DrawNodeTypeToString(DrawNodeType nodeType)150 std::string DrawNodeTypeToString(DrawNodeType nodeType)
151 {
152     // Corresponding to DrawNodeType
153     const std::string typeMap[] = {
154         "PureContainerType",
155         "MergeableType",
156         "DrawPropertyType",
157         "GeometryPropertyType"
158     };
159     return typeMap[nodeType];
160 }
161 
IsContentNode() const162 bool RSRenderNode::IsContentNode() const
163 {
164     return !GetRenderProperties().isDrawn_ &&
165         ((HasContentStyleModifierOnly() && !GetModifiersNG(ModifierNG::RSModifierType::CONTENT_STYLE).empty()) ||
166         !HasDrawCmdModifiers());
167 }
168 
IsPurgeAble()169 static inline bool IsPurgeAble()
170 {
171     return RSSystemProperties::GetRenderNodePurgeEnabled() && RSUniRenderJudgement::IsUniRender();
172 }
173 
RSRenderNode(NodeId id,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)174 RSRenderNode::RSRenderNode(NodeId id, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
175     : isTextureExportNode_(isTextureExportNode), isPurgeable_(IsPurgeAble()), id_(id), context_(context)
176 {
177     RS_PROFILER_RENDERNODE_INC(isOnTheTree_);
178 }
179 
RSRenderNode(NodeId id,bool isOnTheTree,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)180 RSRenderNode::RSRenderNode(
181     NodeId id, bool isOnTheTree, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
182     : isOnTheTree_(isOnTheTree), isTextureExportNode_(isTextureExportNode), isPurgeable_(IsPurgeAble()), id_(id),
183       context_(context)
184 {
185     RS_PROFILER_RENDERNODE_INC(isOnTheTree_);
186 }
187 
AddUIExtensionChild(SharedPtr child)188 void RSRenderNode::AddUIExtensionChild(SharedPtr child)
189 {
190     auto realParent = shared_from_this();
191     while (realParent) {
192         auto surfaceNode = realParent->ReinterpretCastTo<RSSurfaceRenderNode>();
193         if (surfaceNode && surfaceNode->IsAppWindow()) {
194             break;
195         }
196         realParent = realParent->GetParent().lock();
197     }
198     if (!realParent) {
199         return;
200     }
201     realParent->AddChild(child, -1);
202     RS_LOGI("RSRenderNode::AddUIExtensionChild parent:%{public}" PRIu64 ",child:%{public}" PRIu64 ".",
203         realParent->GetId(), child->GetId());
204     AddToPendingSyncList();
205 }
206 
207 // when child is UnobscuredUIExtension and parent is not main window, Mark Need, Rout to main window.
NeedRoutedBasedOnUIExtension(SharedPtr child)208 bool RSRenderNode::NeedRoutedBasedOnUIExtension(SharedPtr child)
209 {
210     if (!child) {
211         return false;
212     }
213     auto surfaceNode = child->ReinterpretCastTo<RSSurfaceRenderNode>();
214     bool isUnobscuredUIExtension = surfaceNode && surfaceNode->IsUnobscuredUIExtensionNode();
215     auto parent = ReinterpretCastTo<RSSurfaceRenderNode>();
216     return isUnobscuredUIExtension && !(parent && parent->IsMainWindowType());
217 }
218 
AddChild(SharedPtr child,int index)219 void RSRenderNode::AddChild(SharedPtr child, int index)
220 {
221     if (NeedRoutedBasedOnUIExtension(child)) {
222         stagingUECChildren_->insert(child);
223         unobscuredUECChildrenNeedSync_ = true;
224         return AddUIExtensionChild(child);
225     }
226     // sanity check, avoid loop
227     if (child == nullptr || child->GetId() == GetId()) {
228         return;
229     }
230 
231     if (RS_PROFILER_PROCESS_ADD_CHILD(this, child, index)) {
232         RS_LOGI("Add child: blocked during replay");
233         return;
234     }
235 
236     // if child already has a parent, remove it from its previous parent
237     if (auto prevParent = child->GetParent().lock()) {
238         prevParent->RemoveChild(child, true);
239         child->InternalRemoveSelfFromDisappearingChildren();
240     }
241 
242     // Set parent-child relationship
243     child->SetParent(weak_from_this());
244     if (index < 0 || index >= static_cast<int>(children_.size())) {
245         children_.emplace_back(child);
246     } else {
247         children_.emplace(std::next(children_.begin(), index), child);
248     }
249     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
250 
251     // A child is not on the tree until its parent is on the tree
252     if (isOnTheTree_) {
253         child->SetIsOnTheTree(true, instanceRootNodeId_, firstLevelNodeId_, drawingCacheRootId_,
254             uifirstRootNodeId_, screenNodeId_, logicalDisplayNodeId_);
255     } else {
256         if (child->GetType() == RSRenderNodeType::SURFACE_NODE) {
257             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
258             ROSEN_LOGI("RSRenderNode:: add child surfaceNode[id:%{public}" PRIu64 " name:%{public}s]"
259             " parent'S isOnTheTree_:%{public}d", surfaceNode->GetId(), surfaceNode->GetNodeName().c_str(),
260             isOnTheTree_);
261         }
262     }
263     ((RSSystemProperties::GetOptimizeParentNodeRegionEnabled() && child->GetType() == RSRenderNodeType::SURFACE_NODE) ||
264         child->GetNeedUseCmdlistDrawRegion())
265         ? child->SetParentSubTreeDirty()
266         : SetContentDirty();
267     isFullChildrenListValid_ = false;
268 }
269 
SetContainBootAnimation(bool isContainBootAnimation)270 void RSRenderNode::SetContainBootAnimation(bool isContainBootAnimation)
271 {
272     isContainBootAnimation_ = isContainBootAnimation;
273     isFullChildrenListValid_ = false;
274     if (GetType() == RSRenderNodeType::SCREEN_NODE) {
275         if (auto parentPtr = GetParent().lock()) {
276             parentPtr->SetContainBootAnimation(isContainBootAnimation);
277         }
278     }
279 }
280 
MoveUIExtensionChild(SharedPtr child)281 void RSRenderNode::MoveUIExtensionChild(SharedPtr child)
282 {
283     if (!child) {
284         return;
285     }
286     auto parent = child->GetParent().lock();
287     if (!parent) {
288         return;
289     }
290     parent->MoveChild(child, -1);
291 }
292 
MoveChild(SharedPtr child,int index)293 void RSRenderNode::MoveChild(SharedPtr child, int index)
294 {
295     if (NeedRoutedBasedOnUIExtension(child)) {
296         return MoveUIExtensionChild(child);
297     }
298     if (child == nullptr || child->GetParent().lock().get() != this) {
299         return;
300     }
301     auto it = std::find_if(children_.begin(), children_.end(),
302         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
303     if (it == children_.end()) {
304         return;
305     }
306 
307     // Reset parent-child relationship
308     if (index < 0 || index >= static_cast<int>(children_.size())) {
309         children_.emplace_back(child);
310     } else {
311         children_.emplace(std::next(children_.begin(), index), child);
312     }
313     children_.erase(it);
314     SetContentDirty();
315     isFullChildrenListValid_ = false;
316 }
317 
RemoveUIExtensionChild(SharedPtr child)318 void RSRenderNode::RemoveUIExtensionChild(SharedPtr child)
319 {
320     if (!child) {
321         return;
322     }
323     auto parent = child->GetParent().lock();
324     if (!parent) {
325         return;
326     }
327     parent->RemoveChild(child);
328     RS_LOGI("RSRenderNode::RemoveUIExtensionChild parent:%{public}" PRIu64 ",child:%{public}" PRIu64 ".",
329         parent->GetId(), child->GetId());
330     AddToPendingSyncList();
331 }
332 
RemoveChild(SharedPtr child,bool skipTransition)333 void RSRenderNode::RemoveChild(SharedPtr child, bool skipTransition)
334 {
335     if (NeedRoutedBasedOnUIExtension(child)) {
336         stagingUECChildren_->erase(child);
337         unobscuredUECChildrenNeedSync_ = true;
338         return RemoveUIExtensionChild(child);
339     }
340     if (child == nullptr) {
341         return;
342     }
343     // break parent-child relationship
344     auto it = std::find_if(children_.begin(), children_.end(),
345         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
346     if (it == children_.end()) {
347         return;
348     }
349     // avoid duplicate entry in disappearingChildren_ (this should not happen)
350     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
351     // if child has disappearing transition, add it to disappearingChildren_
352     if (skipTransition == false && child->HasDisappearingTransition(true)) {
353         ROSEN_LOGD("RSRenderNode::RemoveChild %{public}" PRIu64 " move child(id %{public}" PRIu64 ") into"
354             " disappearingChildren", GetId(), child->GetId());
355         // keep shared_ptr alive for transition
356         uint32_t origPos = static_cast<uint32_t>(std::distance(children_.begin(), it));
357         disappearingChildren_.emplace_back(child, origPos);
358     } else {
359         child->ResetParent();
360     }
361     children_.erase(it);
362     if (child->GetBootAnimation()) {
363         SetContainBootAnimation(false);
364     }
365     ((RSSystemProperties::GetOptimizeParentNodeRegionEnabled() && child->GetType() == RSRenderNodeType::SURFACE_NODE) ||
366         child->GetNeedUseCmdlistDrawRegion())
367         ? child->SetParentSubTreeDirty()
368         : SetContentDirty();
369     isFullChildrenListValid_ = false;
370 }
371 
HasUnobscuredUEC() const372 bool RSRenderNode::HasUnobscuredUEC() const
373 {
374     return stagingRenderParams_->HasUnobscuredUEC();
375 }
376 
SetHasUnobscuredUEC()377 void RSRenderNode::SetHasUnobscuredUEC()
378 {
379     bool hasUnobscuredUEC = stagingUECChildren_ && !stagingUECChildren_->empty();
380     if (hasUnobscuredUEC) {
381         return stagingRenderParams_->SetHasUnobscuredUEC(hasUnobscuredUEC);
382     }
383     std::lock_guard<std::mutex> lock(childrenMutex_);
384     for (auto childWeakPtr : children_) {
385         if (auto child = childWeakPtr.lock()) {
386             hasUnobscuredUEC |= child->HasUnobscuredUEC();
387             if (hasUnobscuredUEC) {
388                 break;
389             }
390         }
391     }
392     stagingRenderParams_->SetHasUnobscuredUEC(hasUnobscuredUEC);
393 }
394 
395 #ifdef SUBTREE_PARALLEL_ENABLE
ClearSubtreeParallelNodes()396 void RSRenderNode::ClearSubtreeParallelNodes()
397 {
398     subtreeParallelNodes_.clear();
399 }
400 
ResetRepaintBoundaryInfo()401 void RSRenderNode::ResetRepaintBoundaryInfo()
402 {
403     isAllChildRepaintBoundary_ = true;
404     hasForceSubmit_ = false;
405     repaintBoundaryWeight_ = 0;
406 }
407 
UpdateRepaintBoundaryInfo(RSRenderNode & node)408 void RSRenderNode::UpdateRepaintBoundaryInfo(RSRenderNode& node)
409 {
410     isAllChildRepaintBoundary_ = isAllChildRepaintBoundary_ && node.IsRepaintBoundary();
411     hasForceSubmit_ = hasForceSubmit_ || node.HasForceSubmit() || node.GetRenderProperties().GetNeedForceSubmit();
412     repaintBoundaryWeight_ += node.GetRepaintBoundaryWeight() + 1;
413 }
414 
GetRepaintBoundaryWeight()415 uint32_t RSRenderNode::GetRepaintBoundaryWeight()
416 {
417     return repaintBoundaryWeight_;
418 }
419 
UpdateSubTreeParallelNodes()420 void RSRenderNode::UpdateSubTreeParallelNodes()
421 {
422     // static constexpr size_t RB_POLICY_CHILDREN_NUMBER = SubtreeParallelParam::GetRBChildrenWeight();
423     static constexpr size_t RB_POLICY_CHILDREN_NUMBER = 4;
424     if (!isRepaintBoundary_ || GetChildrenCount() <= RB_POLICY_CHILDREN_NUMBER || !isAllChildRepaintBoundary_
425         || ChildHasVisibleEffect() || GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE) {
426         return;
427     }
428     subtreeParallelNodes_.emplace(id_);
429 }
430 
MergeSubtreeParallelNodes(RSRenderNode & childNode)431 void RSRenderNode::MergeSubtreeParallelNodes(RSRenderNode& childNode)
432 {
433     auto& childSubtreeParallelNodes = childNode.GetSubtreeParallelNodes();
434     subtreeParallelNodes_.insert(childSubtreeParallelNodes.begin(), childSubtreeParallelNodes.end());
435 }
436 
GetSubtreeParallelNodes()437 std::unordered_set<NodeId>& RSRenderNode::GetSubtreeParallelNodes()
438 {
439     return subtreeParallelNodes_;
440 }
441 #endif
442 
SetHdrNum(bool flag,NodeId instanceRootNodeId,HDRComponentType hdrType)443 void RSRenderNode::SetHdrNum(bool flag, NodeId instanceRootNodeId, HDRComponentType hdrType)
444 {
445     auto context = GetContext().lock();
446     if (!context) {
447         ROSEN_LOGE("RSRenderNode::SetHdrNum: Invalid context");
448         return;
449     }
450     auto parentInstance = context->GetNodeMap().GetRenderNode(instanceRootNodeId);
451     if (!parentInstance) {
452         ROSEN_LOGE("RSRenderNode::SetHdrNum get parent instance root node info failed.");
453         return;
454     }
455     if (auto parentSurface = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>()) {
456         if (flag) {
457             parentSurface->IncreaseHDRNum(hdrType);
458         } else {
459             parentSurface->ReduceHDRNum(hdrType);
460         }
461     }
462 }
463 
SetEnableHdrEffect(bool enableHdrEffect)464 void RSRenderNode::SetEnableHdrEffect(bool enableHdrEffect)
465 {
466     if (enableHdrEffect_ == enableHdrEffect) {
467         return;
468     }
469     if (IsOnTheTree()) {
470         SetHdrNum(enableHdrEffect, GetInstanceRootNodeId(), HDRComponentType::EFFECT);
471     }
472     enableHdrEffect_ = enableHdrEffect;
473 }
474 
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId,NodeId firstLevelNodeId,NodeId cacheNodeId,NodeId uifirstRootNodeId,NodeId screenNodeId,NodeId logicalDisplayNodeId)475 void RSRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId, NodeId firstLevelNodeId,
476     NodeId cacheNodeId, NodeId uifirstRootNodeId, NodeId screenNodeId, NodeId logicalDisplayNodeId)
477 {
478 #ifdef RS_ENABLE_GPU
479     // We do not need to label a child when the child is removed from a parent that is not on the tree
480     if (flag == isOnTheTree_) {
481         return;
482     }
483 
484 #ifdef RS_MEMORY_INFO_MANAGER
485     RSMemoryInfoManager::RecordNodeOnTreeStatus(flag, GetId(), instanceRootNodeId);
486 #endif
487 
488     if (autoClearCloneNode_ && !flag) {
489         ClearCloneCrossNode();
490     }
491 
492     // Need to count upeer or lower trees of HDR nodes
493     if (GetType() == RSRenderNodeType::CANVAS_NODE) {
494         auto canvasNode = RSBaseRenderNode::ReinterpretCast<RSCanvasRenderNode>(shared_from_this());
495         if (canvasNode != nullptr &&
496             (canvasNode->GetHDRPresent() || canvasNode->GetRenderProperties().IsHDRUIBrightnessValid())) {
497             NodeId parentNodeId = flag ? instanceRootNodeId : instanceRootNodeId_;
498             ROSEN_LOGD("RSRenderNode::SetIsOnTheTree HDRClient canvasNode[id:%{public}" PRIu64 " name:%{public}s]"
499                        " parent'S id:%{public}" PRIu64 " ",
500                 canvasNode->GetId(), canvasNode->GetNodeName().c_str(), parentNodeId);
501             if (canvasNode->GetHDRPresent()) {
502                 SetHdrNum(flag, parentNodeId, HDRComponentType::IMAGE);
503                 canvasNode->UpdateScreenHDRNodeList(flag, screenNodeId);
504             }
505             if (canvasNode->GetRenderProperties().IsHDRUIBrightnessValid()) {
506                 SetHdrNum(flag, parentNodeId, HDRComponentType::UICOMPONENT);
507             }
508         }
509     }
510 
511     if (enableHdrEffect_) {
512         NodeId parentNodeId = flag ? instanceRootNodeId : instanceRootNodeId_;
513         ROSEN_LOGD("RSRenderNode::SetIsOnTheTree HDREffect Node[id:%{public}" PRIu64 " name:%{public}s]"
514                    " parent's id:%{public}" PRIu64 " ",
515             GetId(), GetNodeName().c_str(), parentNodeId);
516         SetHdrNum(flag, parentNodeId, HDRComponentType::EFFECT);
517     }
518 
519     if (isOnTheTree_ != flag) {
520         RS_PROFILER_RENDERNODE_CHANGE(flag);
521     }
522 
523     isNewOnTree_ = flag && !isOnTheTree_;
524     isOnTheTree_ = flag;
525     screenNodeId_ = screenNodeId;
526     logicalDisplayNodeId_ = logicalDisplayNodeId;
527     if (isOnTheTree_) {
528         instanceRootNodeId_ = instanceRootNodeId;
529         firstLevelNodeId_ = firstLevelNodeId;
530         OnTreeStateChanged();
531     } else {
532         OnTreeStateChanged();
533         instanceRootNodeId_ = instanceRootNodeId;
534         if (firstLevelNodeId_ != INVALID_NODEID) {
535             preFirstLevelNodeIdSet_.insert(firstLevelNodeId_);
536         }
537         firstLevelNodeId_ = firstLevelNodeId;
538     }
539     // if node is marked as cacheRoot, update subtree status when update surface
540     // in case prepare stage upper cacheRoot cannot specify dirty subnode
541     if (cacheNodeId != INVALID_NODEID) {
542         drawingCacheRootId_ = cacheNodeId;
543     }
544     if (uifirstRootNodeId != INVALID_NODEID) {
545         uifirstRootNodeId_ = uifirstRootNodeId;
546     }
547 
548     if (stagingRenderParams_) {
549         bool ret = stagingRenderParams_->SetFirstLevelNode(firstLevelNodeId_);
550         ret |= stagingRenderParams_->SetUiFirstRootNode(uifirstRootNodeId_);
551         if (ret) {
552             AddToPendingSyncList();
553         }
554         stagingRenderParams_->SetIsOnTheTree(isOnTheTree_);
555     }
556 
557     for (auto& weakChild : children_) {
558         auto child = weakChild.lock();
559         if (child == nullptr) {
560             continue;
561         }
562         if (isOnTheTree_) {
563             AddPreFirstLevelNodeIdSet(child->GetPreFirstLevelNodeIdSet());
564         }
565         child->SetIsOnTheTree(flag, instanceRootNodeId, firstLevelNodeId, cacheNodeId, uifirstRootNodeId, screenNodeId,
566             logicalDisplayNodeId);
567     }
568 
569     for (auto& [child, _] : disappearingChildren_) {
570         child->SetIsOnTheTree(flag, instanceRootNodeId, firstLevelNodeId, cacheNodeId, uifirstRootNodeId, screenNodeId,
571             logicalDisplayNodeId);
572     }
573 
574 #ifdef RS_MEMORY_INFO_MANAGER
575     RSMemoryInfoManager::ResetRootNodeStatusChangeFlag(GetId(), instanceRootNodeId);
576 #endif
577 #endif
578 }
579 
ResetChildRelevantFlags()580 void RSRenderNode::ResetChildRelevantFlags()
581 {
582     childHasVisibleFilter_ = false;
583     childHasVisibleEffect_ = false;
584     childHasSharedTransition_ = false;
585     visibleFilterChild_.clear();
586     visibleEffectChild_.clear();
587     childrenRect_.Clear();
588     hasChildrenOutOfRect_ = false;
589 }
590 
ResetPixelStretchSlot()591 void RSRenderNode::ResetPixelStretchSlot()
592 {
593     RSDrawable::ResetPixelStretchSlot(*this, drawableVec_);
594 }
595 
CanFuzePixelStretch()596 bool RSRenderNode::CanFuzePixelStretch()
597 {
598     return RSDrawable::CanFusePixelStretch(drawableVec_);
599 }
600 
UpdateChildrenRect(const RectI & subRect)601 void RSRenderNode::UpdateChildrenRect(const RectI& subRect)
602 {
603     if (!subRect.IsEmpty()) {
604         if (childrenRect_.IsEmpty()) {
605             // init as not empty subRect in case join RectI enlarging area
606             childrenRect_ = subRect;
607         } else {
608             childrenRect_ = childrenRect_.JoinRect(subRect);
609         }
610     }
611 }
612 
ClearCloneCrossNode()613 void RSRenderNode::ClearCloneCrossNode()
614 {
615     if (cloneCrossNodeVec_.size() == 0) {
616         return;
617     }
618 
619     for (auto it = cloneCrossNodeVec_.begin(); it != cloneCrossNodeVec_.end(); ++it) {
620         if (auto parent = (*it)->GetParent().lock()) {
621             parent->RemoveChild(*it, true);
622         }
623     }
624     cloneCrossNodeVec_.clear();
625 }
626 
SetIsCrossNode(bool isCrossNode)627 void RSRenderNode::SetIsCrossNode(bool isCrossNode)
628 {
629     if (!isCrossNode) {
630         ClearCloneCrossNode();
631     }
632     isCrossNode_ = isCrossNode;
633 }
634 
IsCrossNode() const635 bool RSRenderNode::IsCrossNode() const
636 {
637     return isCrossNode_ || isCloneCrossNode_;
638 }
639 
HasVisitedCrossNode() const640 bool RSRenderNode::HasVisitedCrossNode() const
641 {
642     return hasVisitedCrossNode_;
643 }
644 
SetCrossNodeVisitedStatus(bool hasVisited)645 void RSRenderNode::SetCrossNodeVisitedStatus(bool hasVisited)
646 {
647     if (isCrossNode_) {
648         hasVisitedCrossNode_ = hasVisited;
649         RS_LOGD("%{public}s NodeId[%{public}" PRIu64 "] hasVisited:%{public}d", __func__, GetId(), hasVisited);
650         for (auto cloneNode : cloneCrossNodeVec_) {
651             if (!cloneNode) {
652                 RS_LOGE("%{public}s cloneNode is nullptr sourceNodeId[%{public}" PRIu64 "] hasVisited:%{public}d",
653                         __func__, GetId(), hasVisited);
654                 continue;
655             }
656             cloneNode->hasVisitedCrossNode_ = hasVisited;
657             RS_LOGD("%{public}s cloneNodeId[%{public}" PRIu64 "] hasVisited:%{public}d",
658                     __func__, cloneNode->GetId(), hasVisited);
659         }
660     } else if (isCloneCrossNode_) {
661         auto sourceNode = GetSourceCrossNode().lock();
662         if (!sourceNode) {
663             RS_LOGE("%{public}s sourceNode is nullptr cloneNodeId[%{public}" PRIu64 "] hasVisited:%{public}d",
664                     __func__, GetId(), hasVisited);
665             return;
666         }
667         sourceNode->SetCrossNodeVisitedStatus(hasVisited);
668     }
669 }
670 
AddCrossParentChild(const SharedPtr & child,int32_t index)671 void RSRenderNode::AddCrossParentChild(const SharedPtr& child, int32_t index)
672 {
673     // AddCrossParentChild only used as: the child is under multiple parents(e.g. a window cross multi-screens),
674     // so this child will not remove from the old parent.
675     if (child == nullptr) {
676         return;
677     }
678     // Set parent-child relationship
679     child->SetParent(weak_from_this());
680     if (index < 0 || index >= static_cast<int32_t>(children_.size())) {
681         children_.emplace_back(child);
682     } else {
683         children_.emplace(std::next(children_.begin(), index), child);
684     }
685 
686     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
687     // A child is not on the tree until its parent is on the tree
688     if (isOnTheTree_) {
689         child->SetIsOnTheTree(true, instanceRootNodeId_, firstLevelNodeId_, drawingCacheRootId_, uifirstRootNodeId_,
690             screenNodeId_, logicalDisplayNodeId_);
691     }
692     if (child->IsCrossNode()) {
693         child->SetDirty();
694     }
695     SetContentDirty();
696     isFullChildrenListValid_ = false;
697 }
698 
RemoveCrossParentChild(const SharedPtr & child,const WeakPtr & newParent)699 void RSRenderNode::RemoveCrossParentChild(const SharedPtr& child, const WeakPtr& newParent)
700 {
701     // RemoveCrossParentChild only used as: the child is under multiple parents(e.g. a window cross multi-screens),
702     // set the newParentId to rebuild the parent-child relationship.
703     if (child == nullptr) {
704         return;
705     }
706     // break parent-child relationship
707     auto it = std::find_if(children_.begin(), children_.end(),
708         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
709     if (it == children_.end()) {
710         return;
711     }
712     // avoid duplicate entry in disappearingChildren_ (this should not happen)
713     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
714     // if child has disappearing transition, add it to disappearingChildren_
715     if (child->HasDisappearingTransition(true)) {
716         ROSEN_LOGD("RSRenderNode::RemoveChild %{public}" PRIu64 " move child(id %{public}" PRIu64 ")"
717             " into disappearingChildren", GetId(), child->GetId());
718         // keep shared_ptr alive for transition
719         uint32_t origPos = static_cast<uint32_t>(std::distance(children_.begin(), it));
720         disappearingChildren_.emplace_back(child, origPos);
721     } else {
722         child->SetParent(newParent);
723         // attention: set new parent means 'old' parent has removed this child
724         hasRemovedChild_ = true;
725     }
726     children_.erase(it);
727     SetContentDirty();
728     isFullChildrenListValid_ = false;
729 }
730 
AddCrossScreenChild(const SharedPtr & child,NodeId cloneNodeId,int32_t index,bool autoClearCloneNode)731 void RSRenderNode::AddCrossScreenChild(const SharedPtr& child, NodeId cloneNodeId, int32_t index,
732     bool autoClearCloneNode)
733 {
734     auto context = GetContext().lock();
735     if (child == nullptr || context == nullptr) {
736         ROSEN_LOGE("RSRenderNode::AddCrossScreenChild child is null? %{public}d context is null? %{public}d",
737             child == nullptr, context == nullptr);
738         return;
739     }
740 
741     child->autoClearCloneNode_ = autoClearCloneNode;
742 
743     RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode::AddCrossScreenChild cloneNodeId=%" PRIu64 "", cloneNodeId);
744     RSSurfaceRenderNodeConfig config = {
745         .id = cloneNodeId,
746         .name = child->GetNodeName() + "_cloneNode",
747         .nodeType = RSSurfaceNodeType::LEASH_WINDOW_NODE,
748         .surfaceWindowType = SurfaceWindowType::DEFAULT_WINDOW
749     };
750     auto cloneNode = std::shared_ptr<RSSurfaceRenderNode>(new RSSurfaceRenderNode(config,
751         context->weak_from_this()), RSRenderNodeGC::NodeDestructor);
752     auto res = context->GetMutableNodeMap().RegisterRenderNode(cloneNode);
753     if (!res) {
754         ROSEN_LOGE("RSRenderNode::AddCrossScreenChild register clone node failed! id=%{public}"
755             "" PRIu64 "", cloneNode->GetId());
756         return;
757     }
758     auto& cloneNodeParams = cloneNode->GetStagingRenderParams();
759     if (cloneNodeParams == nullptr) {
760         ROSEN_LOGE("RSRenderNode::AddCrossScreenChild failed! clone node params is null. id=%{public}"
761             "" PRIu64 "", GetId());
762         return;
763     }
764     child->ApplyPositionZModifier();
765     cloneNode->GetMutableRenderProperties().SetPositionZ(child->GetRenderProperties().GetPositionZ());
766     cloneNode->isCloneCrossNode_ = true;
767     cloneNode->sourceCrossNode_ = child;
768 
769     cloneNodeParams->SetCloneSourceDrawable(child->GetRenderDrawable());
770     cloneNodeParams->SetShouldPaint(true);
771     cloneNodeParams->SetNeedSync(true);
772     cloneNode->AddToPendingSyncList();
773 
774     child->RecordCloneCrossNode(cloneNode);
775     AddChild(cloneNode, index);
776 }
777 
RecordCloneCrossNode(SharedPtr node)778 void RSRenderNode::RecordCloneCrossNode(SharedPtr node)
779 {
780     cloneCrossNodeVec_.emplace_back(node);
781 }
782 
RemoveCrossScreenChild(const SharedPtr & child)783 void RSRenderNode::RemoveCrossScreenChild(const SharedPtr& child)
784 {
785     if (child == nullptr) {
786         ROSEN_LOGE("RSRenderNode::RemoveCrossScreenChild child is null");
787         return;
788     }
789 
790     auto cloneIt = std::find_if(child->cloneCrossNodeVec_.begin(), child->cloneCrossNodeVec_.end(),
791         [this](auto cloneNode) -> bool {
792             if (cloneNode) {
793                 auto parent = cloneNode->GetParent().lock();
794                 return parent && parent->GetId() == id_;
795             } else {
796                 return false;
797             }
798         });
799     if (cloneIt == child->cloneCrossNodeVec_.end()) {
800         ROSEN_LOGE("RSRenderNode::RemoveCrossScreenChild can not find clone node %{public}" PRIu64 " in source node"
801             "(id %{public}" PRIu64 ")", GetId(), child->GetId());
802         return;
803     }
804     RemoveChild(*cloneIt, true);
805     child->cloneCrossNodeVec_.erase(cloneIt);
806 }
807 
RemoveFromTree(bool skipTransition)808 void RSRenderNode::RemoveFromTree(bool skipTransition)
809 {
810     auto parentPtr = parent_.lock();
811     if (parentPtr == nullptr) {
812         return;
813     }
814     auto child = shared_from_this();
815     parentPtr->RemoveChild(child, skipTransition);
816     if (skipTransition == false) {
817         return;
818     }
819     // force remove child from disappearingChildren_ and clean sortChildren_ cache
820     parentPtr->disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
821     parentPtr->isFullChildrenListValid_ = false;
822     child->ResetParent();
823 }
824 
ClearChildren()825 void RSRenderNode::ClearChildren()
826 {
827     if (children_.empty()) {
828         return;
829     }
830     // Cache the parent's transition state to avoid redundant recursively check
831     bool parentHasDisappearingTransition = HasDisappearingTransition(true);
832     uint32_t pos = 0;
833     for (auto& childWeakPtr : children_) {
834         auto child = childWeakPtr.lock();
835         if (child == nullptr) {
836             ++pos;
837             continue;
838         }
839         // avoid duplicate entry in disappearingChildren_ (this should not happen)
840         disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
841         if (parentHasDisappearingTransition || child->HasDisappearingTransition(false)) {
842             // keep shared_ptr alive for transition
843             disappearingChildren_.emplace_back(child, pos);
844         } else {
845             child->ResetParent();
846         }
847         ++pos;
848     }
849     children_.clear();
850     SetContentDirty();
851     isFullChildrenListValid_ = false;
852 }
853 
SetParent(WeakPtr parent)854 void RSRenderNode::SetParent(WeakPtr parent)
855 {
856     AddSubSurfaceUpdateInfo(parent.lock(), parent_.lock());
857     parent_ = parent;
858 }
859 
ResetParent()860 void RSRenderNode::ResetParent()
861 {
862     if (auto parentNode = parent_.lock()) {
863         parentNode->hasRemovedChild_ = true;
864         auto geoPtr = GetRenderProperties().GetBoundsGeometry();
865         if (geoPtr != nullptr) {
866             parentNode->removedChildrenRect_ = parentNode->removedChildrenRect_.JoinRect(
867                 geoPtr->MapRect(selfDrawRect_.JoinRect(childrenRect_.ConvertTo<float>()), geoPtr->GetMatrix()));
868         }
869         ((RSSystemProperties::GetOptimizeParentNodeRegionEnabled() && GetType() == RSRenderNodeType::SURFACE_NODE) ||
870             GetNeedUseCmdlistDrawRegion())
871             ? SetParentSubTreeDirty()
872             : parentNode->SetContentDirty();
873         AddSubSurfaceUpdateInfo(nullptr, parentNode);
874     }
875     SetIsOnTheTree(false);
876     parent_.reset();
877     OnResetParent();
878 }
879 
DumpTree(int32_t depth,std::string & out) const880 void RSRenderNode::DumpTree(int32_t depth, std::string& out) const
881 {
882     // Exceed max depth for dumping render node tree, refuse to continue and add a warning.
883     // Possible reason: loop in the render node tree
884     constexpr int32_t MAX_DUMP_DEPTH = 256;
885     if (depth >= MAX_DUMP_DEPTH) {
886         ROSEN_LOGW("RSRenderNode::DumpTree depth exceed max depth, stop dumping. current depth = %d, "
887             "nodeId = %" PRIu64, depth, id_);
888         out += "===== WARNING: exceed max depth for dumping render node tree =====\n";
889         return;
890     }
891 
892     for (int32_t i = 0; i < depth; ++i) {
893         out += "  ";
894     }
895     out += "| ";
896     DumpNodeType(GetType(), out);
897     out += "[" + std::to_string(GetId()) + "], instanceRootNodeId" + "[" +
898         std::to_string(GetInstanceRootNodeId()) + "]";
899     if (auto displayNode = ReinterpretCastTo<RSScreenRenderNode>()) {
900         out += ", screenId[" + std::to_string(displayNode->GetScreenId()) + "]";
901     }
902     if (auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>()) {
903 #if defined(ROSEN_OHOS)
904         if (surfaceNode->GetRSSurfaceHandler() && surfaceNode->GetRSSurfaceHandler()->GetConsumer()) {
905             out +=
906                 ", uniqueId[" + std::to_string(surfaceNode->GetRSSurfaceHandler()->GetConsumer()->GetUniqueId()) + "]";
907         }
908 #endif
909         if (surfaceNode->HasSubSurfaceNodes()) {
910             out += surfaceNode->SubSurfaceNodesDump();
911         }
912         out += ", abilityState: " +
913             std::string(surfaceNode->GetAbilityState() == RSSurfaceNodeAbilityState::FOREGROUND ?
914             "foreground" : "background");
915 
916 #if defined(ROSEN_OHOS)
917         out += ", FrameGravity: " + std::to_string((static_cast<int>(
918             surfaceNode->GetRenderProperties().GetFrameGravity())));
919         if (surfaceNode->GetRSSurfaceHandler() && surfaceNode->GetRSSurfaceHandler()->GetBuffer()) {
920             out += ", ScalingMode: " + std::to_string(
921                 surfaceNode->GetRSSurfaceHandler()->GetBuffer()->GetSurfaceBufferScalingMode());
922             if (surfaceNode->GetRSSurfaceHandler()->GetConsumer()) {
923                 auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
924                 surfaceNode->GetRSSurfaceHandler()->GetConsumer()->GetSurfaceBufferTransformType(
925                     surfaceNode->GetRSSurfaceHandler()->GetBuffer(), &transformType);
926                 out += ", TransformType: " + std::to_string(transformType);
927             }
928         }
929         out += ", AbsRotation: " + std::to_string(surfaceNode->GetAbsRotation());
930 #endif
931     }
932     if (sharedTransitionParam_) {
933         out += sharedTransitionParam_->Dump();
934     }
935     if (IsSuggestedDrawInGroup()) {
936         out += ", [nodeGroup" + std::to_string(nodeGroupType_) + "]"; // adapt for SmartPerf Editor tree tool
937     }
938     if (HasChildrenOutOfRect()) {
939         out += ", [ChildrenOutOfParent: true]";
940     }
941     if (uifirstRootNodeId_ != INVALID_NODEID) {
942         out += ", uifirstRootNodeId_: " + std::to_string(uifirstRootNodeId_);
943     }
944     if (HasSubSurface()) {
945         out += ", subSurfaceCnt: " + std::to_string(subSurfaceCnt_);
946     }
947 
948 #if defined(ROSEN_OHOS)
949     if (RSSystemProperties::GetDumpRsTreeDetailEnabled()) {
950         out += ", PrepareSeq: " + std::to_string(curFrameInfoDetail_.curFramePrepareSeqNum);
951         out += ", PostPrepareSeq: " + std::to_string(curFrameInfoDetail_.curFramePostPrepareSeqNum);
952         out += ", VsyncId: " + std::to_string(curFrameInfoDetail_.curFrameVsyncId);
953         out += ", IsSubTreeSkipped: " + std::to_string(curFrameInfoDetail_.curFrameSubTreeSkipped);
954         out += ", ReverseChildren: " + std::to_string(curFrameInfoDetail_.curFrameReverseChildren);
955         out += ", zOrder: " + std::to_string(hwcRecorder_.GetZOrderForHwcEnableByFilter());
956     }
957 #endif
958 
959     DumpSubClassNode(out);
960     out += ", Properties: " + GetRenderProperties().Dump();
961     if (!uiContextTokenList_.empty()) {
962         out += ", RSUIContextToken: [";
963         for (const auto& token : uiContextTokenList_) {
964             out += " " + std::to_string(token);
965         }
966         out += " ]";
967     } else {
968         out += ", RSUIContextToken: NO_RSUIContext";
969     }
970     if (GetBootAnimation()) {
971         out += ", GetBootAnimation: true";
972     }
973     if (isContainBootAnimation_) {
974         out += ", isContainBootAnimation: true";
975     }
976     if (dirtyStatus_ != NodeDirty::CLEAN) {
977         out += ", isNodeDirty: " + std::to_string(static_cast<int>(dirtyStatus_));
978     }
979     if (GetRenderProperties().IsDirty()) {
980         out += ", isPropertyDirty: true";
981     }
982     if (isSubTreeDirty_) {
983         out += ", isSubTreeDirty: true";
984     }
985     if (IsPureContainer()) {
986         out += ", IsPureContainer: true";
987     }
988     if (RSSystemProperties::ViewDrawNodeType() && GetType() == RSRenderNodeType::CANVAS_NODE) {
989         out += "DrawNodeType: " + DrawNodeTypeToString(GetDrawNodeType());
990     }
991     if (!oldDirty_.IsEmpty()) {
992         out += ", oldDirty: " + oldDirty_.ToString();
993     }
994     if (!innerAbsDrawRect_.IsEmpty()) {
995         out += ", innerAbsDrawRect: " + innerAbsDrawRect_.ToString();
996     }
997     if (!localShadowRect_.IsEmpty()) {
998         out += ", localShadowRect: " + localShadowRect_.ToString();
999     }
1000     if (!localOutlineRect_.IsEmpty()) {
1001         out += ", localOutlineRect: " + localOutlineRect_.ToString();
1002     }
1003     if (!localPixelStretchRect_.IsEmpty()) {
1004         out += ", localPixelStretchRect: " + localPixelStretchRect_.ToString();
1005     }
1006     if (!localForegroundEffectRect_.IsEmpty()) {
1007         out += ", localForegroundEffectRect: " + localForegroundEffectRect_.ToString();
1008     }
1009     if (auto drawRegion = GetRenderProperties().GetDrawRegion()) {
1010         if (!drawRegion->IsEmpty()) {
1011             out += ", drawRegion: " + drawRegion->ToString();
1012         }
1013     }
1014     if (drawableVecStatus_ != 0) {
1015         out += ", drawableVecStatus: " + std::to_string(drawableVecStatus_);
1016     }
1017 #ifdef SUBTREE_PARALLEL_ENABLE
1018     if (isRepaintBoundary_) {
1019         out += ", RB: true";
1020     }
1021 #endif
1022     DumpDrawCmdModifiers(out);
1023     DumpModifiers(out);
1024     animationManager_.DumpAnimations(out);
1025     ChildrenListDump(out);
1026 
1027     for (auto& child : children_) {
1028         if (auto c = child.lock()) {
1029             c->DumpTree(depth + 1, out);
1030         }
1031     }
1032     for (auto& [child, pos] : disappearingChildren_) {
1033         child->DumpTree(depth + 1, out);
1034     }
1035 }
1036 
ChildrenListDump(std::string & out) const1037 void RSRenderNode::ChildrenListDump(std::string& out) const
1038 {
1039     auto sortedChildren = GetSortedChildren();
1040     const int childrenCntLimit = 10;
1041     if (!isFullChildrenListValid_) {
1042         out += ", Children list needs update, current count: " + std::to_string(fullChildrenList_->size());
1043         if (!fullChildrenList_->empty()) {
1044             int cnt = 0;
1045             out += "(";
1046             for (auto child = fullChildrenList_->begin(); child != fullChildrenList_->end(); child++) {
1047                 if (cnt > childrenCntLimit) {
1048                     break;
1049                 }
1050                 if ((*child) == nullptr) {
1051                     continue;
1052                 }
1053                 out += std::to_string((*child)->GetId()) + " ";
1054                 cnt++;
1055             }
1056             out += ")";
1057         }
1058         out +=" expected count: " + std::to_string(sortedChildren->size());
1059         if (!sortedChildren->empty()) {
1060             int cnt = 0;
1061             out += "(";
1062             for (auto child = sortedChildren->begin(); child != sortedChildren->end(); child++) {
1063                 if (cnt > childrenCntLimit) {
1064                     break;
1065                 }
1066                 if ((*child) == nullptr) {
1067                     continue;
1068                 }
1069                 out += std::to_string((*child)->GetId()) + " ";
1070                 cnt++;
1071             }
1072             out += ")";
1073         }
1074     } else if (!sortedChildren->empty()) {
1075         out += ", sortedChildren: " + std::to_string(sortedChildren->size());
1076         int cnt = 0;
1077         out += "(";
1078         for (auto child = sortedChildren->begin(); child != sortedChildren->end(); child++) {
1079             if (cnt > childrenCntLimit) {
1080                 break;
1081             }
1082             if ((*child) == nullptr) {
1083                 continue;
1084             }
1085             out += std::to_string((*child)->GetId()) + " ";
1086             cnt++;
1087         }
1088         out += ")";
1089     }
1090     if (!disappearingChildren_.empty()) {
1091         out += ", disappearingChildren: " + std::to_string(disappearingChildren_.size());
1092         int cnt = 0;
1093         out += "(";
1094         for (auto& [child, _] : disappearingChildren_) {
1095             if (cnt > childrenCntLimit) {
1096                 break;
1097             }
1098             if (child == nullptr) {
1099                 continue;
1100             }
1101             out += std::to_string(child->GetId()) + " ";
1102             cnt++;
1103         }
1104         out += ")";
1105     }
1106     out += "\n";
1107 }
1108 
DumpNodeType(RSRenderNodeType nodeType,std::string & out)1109 void RSRenderNode::DumpNodeType(RSRenderNodeType nodeType, std::string& out)
1110 {
1111     switch (nodeType) {
1112         case RSRenderNodeType::SCREEN_NODE: {
1113             out += "SCREEN_NODE";
1114             break;
1115         }
1116         case RSRenderNodeType::RS_NODE: {
1117             out += "RS_NODE";
1118             break;
1119         }
1120         case RSRenderNodeType::SURFACE_NODE: {
1121             out += "SURFACE_NODE";
1122             break;
1123         }
1124         case RSRenderNodeType::CANVAS_NODE: {
1125             out += "CANVAS_NODE";
1126             break;
1127         }
1128         case RSRenderNodeType::ROOT_NODE: {
1129             out += "ROOT_NODE";
1130             break;
1131         }
1132         case RSRenderNodeType::PROXY_NODE: {
1133             out += "PROXY_NODE";
1134             break;
1135         }
1136         case RSRenderNodeType::CANVAS_DRAWING_NODE: {
1137             out += "CANVAS_DRAWING_NODE";
1138             break;
1139         }
1140         case RSRenderNodeType::EFFECT_NODE: {
1141             out += "EFFECT_NODE";
1142             break;
1143         }
1144         case RSRenderNodeType::LOGICAL_DISPLAY_NODE: {
1145             out += "LOGICAL_DISPLAY_NODE";
1146             break;
1147         }
1148         default: {
1149             out += "UNKNOWN_NODE";
1150             break;
1151         }
1152     }
1153 }
1154 
DumpSubClassNode(std::string & out) const1155 void RSRenderNode::DumpSubClassNode(std::string& out) const
1156 {
1157     if (GetType() == RSRenderNodeType::SURFACE_NODE) {
1158         auto surfaceNode = (static_cast<const RSSurfaceRenderNode*>(this));
1159         auto p = parent_.lock();
1160         out += ", Parent [" + (p != nullptr ? std::to_string(p->GetId()) : "null") + "]";
1161         out += ", Name [" + surfaceNode->GetName() + "]";
1162         out += ", hasConsumer: " + std::to_string(surfaceNode->GetRSSurfaceHandler()->HasConsumer());
1163         std::string propertyAlpha = std::to_string(surfaceNode->GetRenderProperties().GetAlpha());
1164         out += ", Alpha: " + propertyAlpha;
1165         if (surfaceNode->contextAlpha_ < 1.0f) {
1166             std::string contextAlpha = std::to_string(surfaceNode->contextAlpha_);
1167             out += " (ContextAlpha: " + contextAlpha + ")";
1168         }
1169         out += ", Visible: " + std::to_string(surfaceNode->GetRenderProperties().GetVisible());
1170         out += ", Visible" + surfaceNode->GetVisibleRegion().GetRegionInfo();
1171         out += ", Opaque" + surfaceNode->GetOpaqueRegion().GetRegionInfo();
1172         out += ", OcclusionBg: " + std::to_string(surfaceNode->GetAbilityBgAlpha());
1173         const auto specialLayerManager = surfaceNode->GetSpecialLayerMgr();
1174         out += ", SpecialLayer: " + std::to_string(specialLayerManager.Get());
1175         out += ", surfaceType: " + std::to_string((int)surfaceNode->GetSurfaceNodeType());
1176         out += ", ContainerConfig: " + surfaceNode->GetContainerConfigDump();
1177         out += ", colorSpace: " + std::to_string(surfaceNode->GetColorSpace());
1178         out += ", uifirstColorGamut: " + std::to_string(surfaceNode->GetFirstLevelNodeColorGamut());
1179     } else if (GetType() == RSRenderNodeType::ROOT_NODE) {
1180         auto rootNode = static_cast<const RSRootRenderNode*>(this);
1181         out += ", Visible: " + std::to_string(rootNode->GetRenderProperties().GetVisible());
1182         out += ", Size: [" + std::to_string(rootNode->GetRenderProperties().GetFrameWidth()) + ", " +
1183             std::to_string(rootNode->GetRenderProperties().GetFrameHeight()) + "]";
1184         out += ", EnableRender: " + std::to_string(rootNode->GetEnableRender());
1185     } else if (GetType() == RSRenderNodeType::LOGICAL_DISPLAY_NODE) {
1186         auto displayNode = static_cast<const RSLogicalDisplayRenderNode*>(this);
1187         out += ", skipLayer: " + std::to_string(displayNode->GetSecurityDisplay());
1188         out += ", securityExemption: " + std::to_string(displayNode->GetSecurityExemption());
1189         out += ", virtualScreenMuteStatus: " + std::to_string(displayNode->GetVirtualScreenMuteStatus());
1190     } else if (GetType() == RSRenderNodeType::CANVAS_NODE) {
1191         auto canvasNode = static_cast<const RSCanvasRenderNode*>(this);
1192         NodeId linkedRootNodeId = canvasNode->GetLinkedRootNodeId();
1193         if (linkedRootNodeId != INVALID_NODEID) {
1194             out += ", linkedRootNodeId: " + std::to_string(linkedRootNodeId);
1195         }
1196     }
1197 }
1198 
DumpDrawCmdModifiers(std::string & out) const1199 void RSRenderNode::DumpDrawCmdModifiers(std::string& out) const
1200 {
1201     const std::string splitStr = ", ";
1202     std::string modifierDesc = "";
1203     for (auto& slot : modifiersNG_) {
1204         for (auto& modifier : slot) {
1205             if (!modifier->IsCustom()) {
1206                 continue;
1207             }
1208             modifier->Dump(modifierDesc, splitStr);
1209         }
1210     }
1211     if (modifierDesc.empty()) {
1212         return;
1213     }
1214     modifierDesc = ", DrawCmdModifiers2:[" + modifierDesc;
1215     out += modifierDesc.substr(0, modifierDesc.length() - splitStr.length()) + "]";
1216 }
1217 
DumpModifiers(std::string & out) const1218 void RSRenderNode::DumpModifiers(std::string& out) const
1219 {
1220     const std::string splitStr = ", ";
1221     std::string propertyDesc = "";
1222     for (auto& slot : modifiersNG_) {
1223         for (auto& modifier : slot) {
1224             if (modifier->IsCustom()) {
1225                 continue;
1226             }
1227             propertyDesc = propertyDesc + "pid:" + std::to_string(ExtractPid(modifier->GetId())) + "->";
1228             modifier->Dump(propertyDesc, splitStr);
1229         }
1230     }
1231     if (propertyDesc.empty()) {
1232         return;
1233     }
1234     out += ", OtherModifiers:[" + propertyDesc.substr(0, propertyDesc.length() - splitStr.length()) + "]";
1235 }
1236 
IsOnlyBasicGeoTransform() const1237 bool RSRenderNode::IsOnlyBasicGeoTransform() const
1238 {
1239     return isOnlyBasicGeoTransform_;
1240 }
1241 
ForceMergeSubTreeDirtyRegion(RSDirtyRegionManager & dirtyManager,const RectI & clipRect)1242 void RSRenderNode::ForceMergeSubTreeDirtyRegion(RSDirtyRegionManager& dirtyManager, const RectI& clipRect)
1243 {
1244     // prepare skip -> quick prepare, old dirty do not update
1245     if (geoUpdateDelay_) {
1246         if (auto& geoPtr = GetRenderProperties().GetBoundsGeometry()) {
1247             auto absChildrenRect = geoPtr->MapRect(oldChildrenRect_.ConvertTo<float>(), oldAbsMatrix_);
1248             subTreeDirtyRegion_ = absChildrenRect.IntersectRect(oldClipRect_);
1249             dirtyManager.MergeDirtyRect(subTreeDirtyRegion_);
1250         }
1251     }
1252     lastFrameSubTreeSkipped_ = false;
1253 }
1254 
1255 // attention: current all base node's dirty ops causing content dirty
SetContentDirty()1256 void RSRenderNode::SetContentDirty()
1257 {
1258     isContentDirty_ = true;
1259     isOnlyBasicGeoTransform_ = false;
1260     SetDirty();
1261 }
1262 
SetDirty(bool forceAddToActiveList)1263 void RSRenderNode::SetDirty(bool forceAddToActiveList)
1264 {
1265     // TO avoid redundant add, only add if both: 1. on-tree node 2. newly dirty node (or forceAddToActiveList = true)
1266     if (dirtyStatus_ == NodeDirty::CLEAN || dirtyTypesNG_.none() || forceAddToActiveList) {
1267         if (auto context = GetContext().lock()) {
1268             context->AddActiveNode(shared_from_this());
1269         }
1270     }
1271     SetParentSubTreeDirty();
1272     dirtyStatus_ = NodeDirty::DIRTY;
1273 }
1274 
CollectSurface(const std::shared_ptr<RSRenderNode> & node,std::vector<RSRenderNode::SharedPtr> & vec,bool isUniRender,bool onlyFirstLevel)1275 void RSRenderNode::CollectSurface(
1276     const std::shared_ptr<RSRenderNode>& node, std::vector<RSRenderNode::SharedPtr>& vec, bool isUniRender,
1277     bool onlyFirstLevel)
1278 {
1279     if (node == nullptr) {
1280         return;
1281     }
1282 
1283     for (auto& child : *node->GetSortedChildren()) {
1284         child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
1285     }
1286 }
1287 
CollectSelfDrawingChild(const std::shared_ptr<RSRenderNode> & node,std::vector<NodeId> & vec)1288 void RSRenderNode::CollectSelfDrawingChild(const std::shared_ptr<RSRenderNode>& node, std::vector<NodeId>& vec)
1289 {
1290     if (node == nullptr) {
1291         return;
1292     }
1293 
1294     for (auto& child : *node->GetSortedChildren()) {
1295         child->CollectSelfDrawingChild(child, vec);
1296     }
1297 }
1298 
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)1299 void RSRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
1300 {
1301     if (!visitor) {
1302         return;
1303     }
1304     ApplyModifiers();
1305     visitor->PrepareChildren(*this);
1306 }
1307 
QuickPrepare(const std::shared_ptr<RSNodeVisitor> & visitor)1308 void RSRenderNode::QuickPrepare(const std::shared_ptr<RSNodeVisitor>& visitor)
1309 {
1310     if (!visitor) {
1311         return;
1312     }
1313     ApplyModifiers();
1314     visitor->QuickPrepareChildren(*this);
1315 
1316     // fallback for global root node
1317     UpdateRenderParams();
1318     AddToPendingSyncList();
1319 }
1320 
IsSubTreeNeedPrepare(bool filterInGlobal,bool isOccluded)1321 bool RSRenderNode::IsSubTreeNeedPrepare(bool filterInGlobal, bool isOccluded)
1322 {
1323     auto checkType = RSSystemProperties::GetSubTreePrepareCheckType();
1324     if (checkType == SubTreePrepareCheckType::DISABLED) {
1325         return true;
1326     }
1327     // stop visit invisible or clean without filter subtree
1328     // Exception: If cross-display node is fully invisible under current visited display, its subtree can't be skipped,
1329     // since it may be visible on other displays, and it is only prepared once.
1330     if (!shouldPaint_ || (isOccluded && !IsFirstLevelCrossNode() && !IsTreeStateChangeDirty())) {
1331         // when subTreeOccluded, need to applyModifiers to node's children
1332         RS_OPTIONAL_TRACE_NAME_FMT("IsSubTreeNeedPrepare node[%llu] skip subtree ShouldPaint [%d], isOccluded [%d], "
1333             "CrossDisplay: %d", GetId(), shouldPaint_, isOccluded, IsFirstLevelCrossNode());
1334         return false;
1335     }
1336     if (checkType == SubTreePrepareCheckType::DISABLE_SUBTREE_DIRTY_CHECK) {
1337         return true;
1338     }
1339     if (IsSubTreeDirty()) {
1340         // reset iff traverses dirty subtree
1341         SetSubTreeDirty(false);
1342         SetTreeStateChangeDirty(false);
1343         UpdateChildrenOutOfRectFlag(false); // collect again
1344         return true;
1345     }
1346     if (childHasSharedTransition_ || isAccumulatedClipFlagChanged_ || subSurfaceCnt_ > 0) {
1347         return true;
1348     }
1349     if (ChildHasVisibleFilter()) {
1350         RS_OPTIONAL_TRACE_NAME_FMT("IsSubTreeNeedPrepare node[%d] filterInGlobal_[%d]",
1351             GetId(), filterInGlobal);
1352     }
1353     // if clean without filter skip subtree
1354     return ChildHasVisibleFilter() ? filterInGlobal : false;
1355 }
1356 
PrepareChildrenForApplyModifiers()1357 void RSRenderNode::PrepareChildrenForApplyModifiers()
1358 {
1359     auto children = GetSortedChildren();
1360     std::for_each((*children).begin(), (*children).end(),
1361         [this](const std::shared_ptr<RSRenderNode>& node) {
1362         node->PrepareSelfNodeForApplyModifiers();
1363     });
1364 }
1365 
PrepareSelfNodeForApplyModifiers()1366 void RSRenderNode::PrepareSelfNodeForApplyModifiers()
1367 {
1368 #ifdef RS_ENABLE_GPU
1369     ApplyModifiers();
1370     PrepareChildrenForApplyModifiers();
1371 
1372     stagingRenderParams_->SetAlpha(GetRenderProperties().GetAlpha());
1373 
1374     UpdateRenderParams();
1375     AddToPendingSyncList();
1376 #endif
1377 }
1378 
UpdateDrawingCacheInfoBeforeChildren(bool isScreenRotation)1379 void RSRenderNode::UpdateDrawingCacheInfoBeforeChildren(bool isScreenRotation)
1380 {
1381     auto foregroundFilterCache = GetRenderProperties().GetForegroundFilterCache();
1382     bool rotateOptimize  = RSSystemProperties::GetCacheOptimizeRotateEnable() ? false : isScreenRotation;
1383     if (!ShouldPaint() || (rotateOptimize && !foregroundFilterCache)) {
1384         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
1385         return;
1386     }
1387     CheckDrawingCacheType();
1388     if (GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE) {
1389         RS_LOGD("RSRenderNode::UpdateDrawingCacheInfoBC drawingCacheType is %{public}d", GetDrawingCacheType());
1390         return;
1391     }
1392     SetDrawingCacheChanged((IsContentDirty() || IsSubTreeDirty() || IsAccessibilityConfigChanged()));
1393     RS_OPTIONAL_TRACE_NAME_FMT(
1394         "SetDrawingCacheChanged id:%llu nodeGroupType:%d contentDirty:%d propertyDirty:%d subTreeDirty:%d "
1395         "AccessibilityConfigChanged:%d",
1396         GetId(), nodeGroupType_, isContentDirty_, GetRenderProperties().IsContentDirty(), IsSubTreeDirty(),
1397         IsAccessibilityConfigChanged());
1398 #ifdef RS_ENABLE_GPU
1399     stagingRenderParams_->SetDrawingCacheIncludeProperty(nodeGroupIncludeProperty_);
1400 #endif
1401 }
1402 
Process(const std::shared_ptr<RSNodeVisitor> & visitor)1403 void RSRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
1404 {
1405     if (!visitor) {
1406         return;
1407     }
1408     visitor->ProcessChildren(*this);
1409 }
1410 
SendCommandFromRT(std::unique_ptr<RSCommand> & command,NodeId nodeId)1411 void RSRenderNode::SendCommandFromRT(std::unique_ptr<RSCommand>& command, NodeId nodeId)
1412 {
1413     auto transactionProxy = RSTransactionProxy::GetInstance(); // planing
1414     if (transactionProxy != nullptr) {
1415         transactionProxy->AddCommandFromRT(command, nodeId);
1416     }
1417 }
1418 
InternalRemoveSelfFromDisappearingChildren()1419 void RSRenderNode::InternalRemoveSelfFromDisappearingChildren()
1420 {
1421     // internal use only, force remove self from parent's disappearingChildren_
1422     auto parent = parent_.lock();
1423     if (parent == nullptr) {
1424         return;
1425     }
1426     auto it = std::find_if(parent->disappearingChildren_.begin(), parent->disappearingChildren_.end(),
1427         [childPtr = shared_from_this()](const auto& pair) -> bool { return pair.first == childPtr; });
1428     if (it == parent->disappearingChildren_.end()) {
1429         return;
1430     }
1431     parent->disappearingChildren_.erase(it);
1432     parent->isFullChildrenListValid_ = false;
1433     ResetParent();
1434 }
1435 
~RSRenderNode()1436 RSRenderNode::~RSRenderNode()
1437 {
1438     RS_PROFILER_RENDERNODE_DEC(isOnTheTree_);
1439     if (appPid_ != 0) {
1440         RSSingleFrameComposer::AddOrRemoveAppPidToMap(false, appPid_);
1441     }
1442     FallbackAnimationsToRoot();
1443     if (clearCacheSurfaceFunc_ && (cacheSurface_ || cacheCompletedSurface_)) {
1444         clearCacheSurfaceFunc_(std::move(cacheSurface_), std::move(cacheCompletedSurface_), cacheSurfaceThreadIndex_,
1445             completedSurfaceThreadIndex_);
1446     }
1447     ClearCacheSurface();
1448     auto context = GetContext().lock();
1449     if (!context) {
1450         ROSEN_LOGD("RSRenderNode::~RSRenderNode: Invalid context");
1451         return;
1452     }
1453 }
1454 
FallbackAnimationsToRoot()1455 void RSRenderNode::FallbackAnimationsToRoot()
1456 {
1457     if (animationManager_.animations_.empty()) {
1458         return;
1459     }
1460 
1461     auto context = GetContext().lock();
1462     if (!context) {
1463         ROSEN_LOGE("RSRenderNode::FallbackAnimationsToRoot: Invalid context");
1464         return;
1465     }
1466     auto target = context->GetNodeMap().GetAnimationFallbackNode();
1467     if (!target) {
1468         ROSEN_LOGE("Failed to move animation to root, root render node is null!");
1469         return;
1470     }
1471     context->RegisterAnimatingRenderNode(target);
1472 
1473     for (auto& [unused, animation] : animationManager_.animations_) {
1474         if (animation->IsPaused()) {
1475             animation->Resume();
1476         }
1477 
1478         animation->Detach(true);
1479         // avoid infinite loop for fallback animation
1480         animation->SetRepeatCount(1);
1481         target->animationManager_.AddAnimation(std::move(animation));
1482     }
1483     animationManager_.animations_.clear();
1484     // Check the next frame's VSync has been requested. If there is no request, add another VSync request
1485     if (!context->IsRequestedNextVsyncAnimate()) {
1486         context->RequestVsync();
1487         context->SetRequestedNextVsyncAnimate(true);
1488     }
1489 }
1490 
ActivateDisplaySync()1491 void RSRenderNode::ActivateDisplaySync()
1492 {
1493     if (!displaySync_) {
1494         displaySync_ = std::make_shared<RSRenderDisplaySync>(GetId());
1495     }
1496 }
1497 
UpdateDisplaySyncRange()1498 void RSRenderNode::UpdateDisplaySyncRange()
1499 {
1500     if (!displaySync_) {
1501         return;
1502     }
1503     auto animationRange = animationManager_.GetFrameRateRange();
1504     if (animationRange.IsValid()) {
1505         displaySync_->SetExpectedFrameRateRange(animationRange);
1506     }
1507 }
1508 
Animate(int64_t timestamp,int64_t & minLeftDelayTime,int64_t period,bool isDisplaySyncEnabled)1509 std::tuple<bool, bool, bool> RSRenderNode::Animate(
1510     int64_t timestamp, int64_t& minLeftDelayTime, int64_t period, bool isDisplaySyncEnabled)
1511 {
1512     RS_PROFILER_ANIMATION_NODE(GetType(), selfDrawRect_.GetWidth() * selfDrawRect_.GetWidth());
1513     if (displaySync_ && displaySync_->OnFrameSkip(timestamp, period, isDisplaySyncEnabled)) {
1514         minLeftDelayTime = 0;
1515         return displaySync_->GetAnimateResult();
1516     }
1517     RSSurfaceNodeAbilityState abilityState = RSSurfaceNodeAbilityState::FOREGROUND;
1518 
1519     // Animation on surfaceNode is always on foreground ability state.
1520     // If instanceRootNode is surfaceNode, get its ability state. If not, regard it as foreground ability state.
1521     if (GetType() != RSRenderNodeType::SURFACE_NODE) {
1522         if (auto instanceRootNode = GetInstanceRootNode()) {
1523             abilityState = instanceRootNode->GetAbilityState();
1524         }
1525     }
1526 
1527     auto animateResult = animationManager_.Animate(timestamp, minLeftDelayTime, IsOnTheTree(), abilityState);
1528     if (displaySync_) {
1529         displaySync_->SetAnimateResult(animateResult);
1530     }
1531     return animateResult;
1532 }
1533 
IsClipBound() const1534 bool RSRenderNode::IsClipBound() const
1535 {
1536     return GetRenderProperties().GetClipToBounds() || GetRenderProperties().GetClipToFrame();
1537 }
1538 
SetAccumulatedClipFlag(bool clipChange)1539 bool RSRenderNode::SetAccumulatedClipFlag(bool clipChange)
1540 {
1541     isAccumulatedClipFlagChanged_ = (hasAccumulatedClipFlag_ != IsClipBound()) || clipChange;
1542     if (isAccumulatedClipFlagChanged_) {
1543         hasAccumulatedClipFlag_ = IsClipBound();
1544     }
1545     return isAccumulatedClipFlagChanged_;
1546 }
1547 
1548 #ifdef RS_ENABLE_GPU
1549 // Deprecated! Do not use this interface.
1550 // This interface has crash risks and will be deleted in later versions.
GetRenderParams() const1551 const std::unique_ptr<RSRenderParams>& RSRenderNode::GetRenderParams() const
1552 {
1553     if (renderDrawable_ == nullptr) {
1554         DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(shared_from_this());
1555     }
1556     return renderDrawable_->renderParams_;
1557 }
1558 #endif
CollectAndUpdateLocalShadowRect()1559 void RSRenderNode::CollectAndUpdateLocalShadowRect()
1560 {
1561     // update shadow if shadow changes
1562     if (dirtySlots_.find(RSDrawableSlot::SHADOW) != dirtySlots_.end()) {
1563         auto& properties = GetRenderProperties();
1564         if (properties.IsShadowValid()) {
1565             SetShadowValidLastFrame(true);
1566             if (IsInstanceOf<RSSurfaceRenderNode>()) {
1567                 RRect absClipRRect = RRect(properties.GetBoundsRect(), properties.GetCornerRadius());
1568                 RSPropertiesPainter::GetShadowDirtyRect(localShadowRect_, properties, &absClipRRect, false, true);
1569             } else {
1570                 RSPropertiesPainter::GetShadowDirtyRect(localShadowRect_, properties, nullptr, false, true);
1571             }
1572         }
1573     }
1574     selfDrawRect_ = selfDrawRect_.JoinRect(localShadowRect_.ConvertTo<float>());
1575 }
1576 
CollectAndUpdateLocalOutlineRect()1577 void RSRenderNode::CollectAndUpdateLocalOutlineRect()
1578 {
1579     // update outline if oueline changes
1580     if (dirtySlots_.find(RSDrawableSlot::OUTLINE) != dirtySlots_.end()) {
1581         RSPropertiesPainter::GetOutlineDirtyRect(localOutlineRect_, GetRenderProperties(), false);
1582     }
1583     selfDrawRect_ = selfDrawRect_.JoinRect(localOutlineRect_.ConvertTo<float>());
1584 }
1585 
CollectAndUpdateLocalPixelStretchRect()1586 void RSRenderNode::CollectAndUpdateLocalPixelStretchRect()
1587 {
1588     // update outline if oueline changes
1589     if (dirtySlots_.find(RSDrawableSlot::PIXEL_STRETCH) != dirtySlots_.end()) {
1590         RSPropertiesPainter::GetPixelStretchDirtyRect(localPixelStretchRect_, GetRenderProperties(), false);
1591     }
1592     selfDrawRect_ = selfDrawRect_.JoinRect(localPixelStretchRect_.ConvertTo<float>());
1593 }
1594 
CollectAndUpdateLocalForegroundEffectRect()1595 void RSRenderNode::CollectAndUpdateLocalForegroundEffectRect()
1596 {
1597     // update foreground effect's dirty region if it changes
1598     if (GetRenderProperties().GetForegroundEffectDirty()) {
1599         RSPropertiesPainter::GetForegroundEffectDirtyRect(localForegroundEffectRect_, GetRenderProperties(), false);
1600         GetMutableRenderProperties().SetForegroundEffectDirty(false);
1601     }
1602     selfDrawRect_ = selfDrawRect_.JoinRect(localForegroundEffectRect_.ConvertTo<float>());
1603 }
1604 
CollectAndUpdateLocalDistortionEffectRect()1605 void RSRenderNode::CollectAndUpdateLocalDistortionEffectRect()
1606 {
1607     // update distortion effect's dirty region if it changes
1608     if (GetRenderProperties().GetDistortionDirty()) {
1609         RSPropertiesPainter::GetDistortionEffectDirtyRect(localDistortionEffectRect_, GetRenderProperties());
1610         GetMutableRenderProperties().SetDistortionDirty(false);
1611     }
1612     selfDrawRect_ = selfDrawRect_.JoinRect(localDistortionEffectRect_.ConvertTo<float>());
1613 }
1614 
UpdateBufferDirtyRegion()1615 void RSRenderNode::UpdateBufferDirtyRegion()
1616 {
1617 #ifndef ROSEN_CROSS_PLATFORM
1618     isSelfDrawingNode_ = false;
1619     if (GetType() != RSRenderNodeType::SURFACE_NODE) {
1620         return;
1621     }
1622     auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
1623     if (surfaceNode == nullptr) {
1624         return;
1625     }
1626     auto buffer = surfaceNode->GetRSSurfaceHandler()->GetBuffer();
1627     if (buffer != nullptr) {
1628         isSelfDrawingNode_ = true;
1629         // Use the matrix from buffer to relative coordinate and the absolute matrix
1630         // to calculate the buffer damageRegion's absolute rect
1631         auto rect = surfaceNode->GetRSSurfaceHandler()->GetDamageRegion();
1632         bool isUseSelfDrawingDirtyRegion = buffer->GetSurfaceBufferWidth() == rect.w &&
1633             buffer->GetSurfaceBufferHeight() == rect.h && rect.x == 0 && rect.y == 0;
1634         if (isUseSelfDrawingDirtyRegion) {
1635             Rect selfDrawingDirtyRect;
1636             bool isDirtyRectValid = RSGpuDirtyCollector::DirtyRegionCompute(buffer, selfDrawingDirtyRect);
1637             if (isDirtyRectValid) {
1638                 rect = { selfDrawingDirtyRect.x, selfDrawingDirtyRect.y,
1639                     selfDrawingDirtyRect.w, selfDrawingDirtyRect.h };
1640                 RS_OPTIONAL_TRACE_NAME_FMT("selfDrawingDirtyRect:[%d, %d, %d, %d]", rect.x, rect.y, rect.w, rect.h);
1641             }
1642         }
1643         auto matrix = surfaceNode->GetBufferRelMatrix();
1644         auto bufferDirtyRect = GetRenderProperties().GetBoundsGeometry()->MapRect(
1645             RectF(rect.x, rect.y, rect.w, rect.h), matrix).ConvertTo<float>();
1646         // The buffer's dirtyRect should not be out of the scope of the node's dirtyRect
1647         selfDrawingNodeDirtyRect_ = bufferDirtyRect.IntersectRect(selfDrawRect_);
1648         RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode id: %" PRIu64 ", buffer size [%d,%d], "
1649             "buffer damageRegion [%d,%d,%d,%d], dirtyRect %s", GetId(),
1650             buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(),
1651             rect.x, rect.y, rect.w, rect.h, selfDrawingNodeDirtyRect_.ToString().c_str());
1652     }
1653 #endif
1654 }
1655 
UpdateSelfDrawRect()1656 bool RSRenderNode::UpdateSelfDrawRect()
1657 {
1658     auto prevSelfDrawRect = selfDrawRect_;
1659     // empty rect would not join and doesn't need to check
1660     auto& properties = GetRenderProperties();
1661     selfDrawRect_ = properties.GetLocalBoundsAndFramesRect();
1662     UpdateBufferDirtyRegion();
1663     if (auto drawRegion = properties.GetDrawRegion()) {
1664         selfDrawRect_ = selfDrawRect_.JoinRect(*drawRegion);
1665     }
1666     CollectAndUpdateLocalShadowRect();
1667     CollectAndUpdateLocalOutlineRect();
1668     CollectAndUpdateLocalPixelStretchRect();
1669     CollectAndUpdateLocalDistortionEffectRect();
1670     return !selfDrawRect_.IsNearEqual(prevSelfDrawRect);
1671 }
1672 
UpdateAbsDirtyRegion(RSDirtyRegionManager & dirtyManager,const RectI & clipRect)1673 void RSRenderNode::UpdateAbsDirtyRegion(RSDirtyRegionManager& dirtyManager, const RectI& clipRect)
1674 {
1675     // merge old children draw rect if node's sub tree is all dirty
1676     const auto& renderProperties = GetRenderProperties();
1677     if (renderProperties.IsSubTreeAllDirty()) {
1678         auto oldChildrenDirtyRect = renderProperties.GetBoundsGeometry()->MapRect(
1679             oldChildrenRect_.ConvertTo<float>(), oldAbsMatrix_);
1680         dirtyManager.MergeDirtyRect(IsFirstLevelCrossNode() ? oldChildrenDirtyRect :
1681             oldChildrenDirtyRect.IntersectRect(oldClipRect_));
1682     }
1683     // it is necessary to ensure that last frame dirty rect is merged
1684     auto oldDirtyRect = oldDirty_;
1685     if (absDrawRect_ != oldAbsDrawRect_) {
1686         if (isSelfDrawingNode_) {
1687             // merge self drawing node last frame size and join current frame size to absDrawRect_ when changed
1688             dirtyManager.MergeDirtyRect(oldAbsDrawRect_.IntersectRect(clipRect));
1689             selfDrawingNodeAbsDirtyRect_.JoinRect(absDrawRect_);
1690         }
1691         oldAbsDrawRect_ = absDrawRect_;
1692     }
1693     // easily merge oldDirty if switch to invisible
1694     if (!shouldPaint_ && isLastVisible_) {
1695         dirtyManager.MergeDirtyRect(oldDirtyRect);
1696         return;
1697     }
1698     auto dirtyRect = isSelfDrawingNode_ ? selfDrawingNodeAbsDirtyRect_ :
1699         (!absCmdlistDrawRect_.IsEmpty() ? absCmdlistDrawRect_ : absDrawRect_);
1700     dirtyRect = IsFirstLevelCrossNode() ? dirtyRect : dirtyRect.IntersectRect(clipRect);
1701     oldDirty_ = dirtyRect;
1702     oldDirtyInSurface_ = oldDirty_.IntersectRect(dirtyManager.GetSurfaceRect());
1703     dirtyManager.MergeDirtyRect(dirtyRect.JoinRect(oldDirtyRect));
1704 }
1705 
UpdateDrawRectAndDirtyRegion(RSDirtyRegionManager & dirtyManager,bool accumGeoDirty,const RectI & clipRect,const Drawing::Matrix & parentSurfaceMatrix)1706 bool RSRenderNode::UpdateDrawRectAndDirtyRegion(RSDirtyRegionManager& dirtyManager, bool accumGeoDirty,
1707     const RectI& clipRect, const Drawing::Matrix& parentSurfaceMatrix)
1708 {
1709     auto& properties = GetMutableRenderProperties();
1710 #ifdef RS_ENABLE_PREFETCH
1711     // The 2 is the cache level.
1712     __builtin_prefetch(&(properties.boundsGeo_), 0, 2);
1713     __builtin_prefetch(&(properties.frameGeo_), 0, 2);
1714 #endif
1715     // 1. update self drawrect if dirty
1716     bool selfDrawRectChanged = IsDirty() ? UpdateSelfDrawRect() : false;
1717     if (selfDrawRectChanged) {
1718         UpdateChildrenOutOfRectFlag(!childrenRect_.ConvertTo<float>().IsInsideOf(selfDrawRect_));
1719     }
1720     // 2. update geoMatrix by parent for dirty collection
1721     // update geoMatrix and accumGeoDirty if needed
1722     auto parent = curCloneNodeParent_.lock();
1723     if (parent == nullptr) {
1724         parent = GetParent().lock();
1725     }
1726     if (parent && parent->GetGeoUpdateDelay()) {
1727         accumGeoDirty = true;
1728         // Set geometry update delay flag recursively to update node's old dirty in subTree
1729         SetGeoUpdateDelay(true);
1730         oldAbsMatrix_ = parent->oldAbsMatrix_;
1731         oldAbsMatrix_.PostConcat(oldMatrix_);
1732     }
1733     if (accumGeoDirty || properties.NeedClip() || properties.geoDirty_ || (dirtyStatus_ != NodeDirty::CLEAN)) {
1734         UpdateDrawRect(accumGeoDirty, clipRect, parentSurfaceMatrix);
1735         // planning: double check if it would be covered by updateself without geo update
1736         auto& geoPtr = properties.boundsGeo_;
1737         // selfdrawing node's geo may not dirty when its dirty region changes
1738         // updateDrawRect info when this node need to use cmdlistDrawRegion
1739         if (geoPtr && (accumGeoDirty || properties.geoDirty_ ||
1740             isSelfDrawingNode_ || selfDrawRectChanged || GetNeedUseCmdlistDrawRegion())) {
1741             absDrawRectF_ = geoPtr->MapRectWithoutRounding(selfDrawRect_, geoPtr->GetAbsMatrix());
1742             absDrawRect_ = geoPtr->InflateToRectI(absDrawRectF_);
1743             innerAbsDrawRect_ = geoPtr->DeflateToRectI(absDrawRectF_);
1744             absCmdlistDrawRect_ = GetNeedUseCmdlistDrawRegion() ?
1745                 geoPtr->MapRect(cmdlistDrawRegion_, geoPtr->GetAbsMatrix()) : RectI(0, 0, 0, 0);
1746             if (isSelfDrawingNode_) {
1747                 selfDrawingNodeAbsDirtyRectF_ = geoPtr->MapRectWithoutRounding(
1748                     selfDrawingNodeDirtyRect_, geoPtr->GetAbsMatrix());
1749                 selfDrawingNodeAbsDirtyRect_ = geoPtr->InflateToRectI(selfDrawingNodeAbsDirtyRectF_);
1750             }
1751             UpdateSrcOrClipedAbsDrawRectChangeState(clipRect);
1752         }
1753     }
1754     // 3. update dirtyRegion if needed
1755     if (properties.GetBackgroundFilter()) {
1756         UpdateFilterCacheWithBelowDirty(Occlusion::Rect(dirtyManager.GetCurrentFrameDirtyRegion()));
1757     }
1758     ValidateLightResources();
1759     isDirtyRegionUpdated_ = false;
1760     // Only when satisfy following conditions, absDirtyRegion should update:
1761     // 1.The node is dirty; 2.The clip absDrawRect change; 3.Parent clip property change or has GeoUpdateDelay dirty;
1762     // When the subtree is all dirty and the node should not paint, it also needs to add dirty region
1763     if ((IsDirty() || srcOrClipedAbsDrawRectChangeFlag_ || (parent && (parent->GetAccumulatedClipFlagChange() ||
1764         parent->GetGeoUpdateDelay()))) && (shouldPaint_ || isLastVisible_ || properties.IsSubTreeAllDirty())) {
1765         // update ForegroundFilterCache
1766         UpdateAbsDirtyRegion(dirtyManager, clipRect);
1767         UpdateDirtyRegionInfoForDFX(dirtyManager);
1768     }
1769     // 4. reset dirty status
1770     ResetDirtyStatus();
1771     return accumGeoDirty;
1772 }
1773 
UpdateDrawRect(bool & accumGeoDirty,const RectI & clipRect,const Drawing::Matrix & parentSurfaceMatrix)1774 void RSRenderNode::UpdateDrawRect(
1775     bool& accumGeoDirty, const RectI& clipRect, const Drawing::Matrix& parentSurfaceMatrix)
1776 {
1777     auto parent = curCloneNodeParent_.lock();
1778     if (parent == nullptr) {
1779         parent = GetParent().lock();
1780     }
1781     auto& properties = GetMutableRenderProperties();
1782     if (auto sandbox = properties.GetSandBox(); sandbox.has_value() && sharedTransitionParam_) {
1783         // case a. use parent sur_face matrix with sandbox
1784         auto translateMatrix = Drawing::Matrix();
1785         translateMatrix.Translate(sandbox->x_, sandbox->y_);
1786         properties.GetBoundsGeometry()->SetContextMatrix(translateMatrix);
1787         accumGeoDirty = properties.UpdateGeometryByParent(&parentSurfaceMatrix, std::nullopt) || accumGeoDirty;
1788         properties.GetBoundsGeometry()->SetContextMatrix(std::nullopt);
1789     } else if (parent != nullptr) {
1790         // case b. use parent matrix
1791         auto parentMatrix = &(parent->GetRenderProperties().GetBoundsGeometry()->GetAbsMatrix());
1792         bool isSurfaceRenderNode = IsInstanceOf<RSSurfaceRenderNode>();
1793         auto offset = !isSurfaceRenderNode
1794                           ? std::make_optional<Drawing::Point>(parent->GetRenderProperties().GetFrameOffsetX(),
1795                                 parent->GetRenderProperties().GetFrameOffsetY())
1796                           : std::nullopt;
1797         if (isSurfaceRenderNode && GetGlobalPositionEnabled()) {
1798             offset = std::make_optional<Drawing::Point>(-GetPreparedDisplayOffsetX(), -GetPreparedDisplayOffsetY());
1799         }
1800         accumGeoDirty = properties.UpdateGeometryByParent(parentMatrix, offset) || accumGeoDirty;
1801     } else {
1802         // case c. no parent
1803         accumGeoDirty = properties.UpdateGeometryByParent(nullptr, std::nullopt) || accumGeoDirty;
1804     }
1805 }
1806 
UpdateDirtyRegionInfoForDFX(RSDirtyRegionManager & dirtyManager)1807 void RSRenderNode::UpdateDirtyRegionInfoForDFX(RSDirtyRegionManager& dirtyManager)
1808 {
1809     if (RSSystemProperties::GetDirtyRegionDebugType() == DirtyRegionDebugType::DISABLED) {
1810         return;
1811     }
1812     // update dirty region information that depends on geoPtr.
1813     auto& properties = GetRenderProperties();
1814     if (auto& geoPtr = properties.GetBoundsGeometry()) {
1815         // drawRegion can be nullptr if not set.
1816         if (auto drawRegion = properties.GetDrawRegion()) {
1817             dirtyManager.UpdateDirtyRegionInfoForDfx(
1818                 GetId(), GetType(), DirtyRegionType::OVERLAY_RECT, geoPtr->MapAbsRect(*drawRegion));
1819         }
1820         dirtyManager.UpdateDirtyRegionInfoForDfx(
1821             GetId(), GetType(), DirtyRegionType::SHADOW_RECT, geoPtr->MapAbsRect(localShadowRect_.ConvertTo<float>()));
1822         dirtyManager.UpdateDirtyRegionInfoForDfx(GetId(),
1823             GetType(), DirtyRegionType::OUTLINE_RECT, geoPtr->MapAbsRect(localOutlineRect_.ConvertTo<float>()));
1824     }
1825 
1826     // update dirty region information in abs Coords.
1827     dirtyManager.UpdateDirtyRegionInfoForDfx(
1828         GetId(), GetType(), DirtyRegionType::UPDATE_DIRTY_REGION, oldDirtyInSurface_);
1829     dirtyManager.UpdateDirtyRegionInfoForDfx(
1830         GetId(), GetType(), DirtyRegionType::FILTER_RECT, filterRegion_);
1831     if (LastFrameSubTreeSkipped()) {
1832         dirtyManager.UpdateDirtyRegionInfoForDfx(
1833             GetId(), GetType(), DirtyRegionType::SUBTREE_SKIP_RECT, subTreeDirtyRegion_);
1834     }
1835     if (properties.GetClipToBounds() || properties.GetClipToFrame()) {
1836         dirtyManager.UpdateDirtyRegionInfoForDfx(
1837             GetId(), GetType(), DirtyRegionType::PREPARE_CLIP_RECT, GetAbsDrawRect());
1838     }
1839 }
1840 
UpdateSubTreeSkipDirtyForDFX(RSDirtyRegionManager & dirtyManager,const RectI & rect)1841 void RSRenderNode::UpdateSubTreeSkipDirtyForDFX(RSDirtyRegionManager& dirtyManager, const RectI& rect)
1842 {
1843     if (RSSystemProperties::GetDirtyRegionDebugType() == DirtyRegionDebugType::DISABLED) {
1844         return;
1845     }
1846     dirtyManager.UpdateDirtyRegionInfoForDfx(
1847         GetId(), GetType(), DirtyRegionType::SUBTREE_SKIP_OUT_OF_PARENT_RECT, rect);
1848 }
1849 
Update(RSDirtyRegionManager & dirtyManager,const std::shared_ptr<RSRenderNode> & parent,bool parentDirty,std::optional<RectI> clipRect)1850 bool RSRenderNode::Update(RSDirtyRegionManager& dirtyManager, const std::shared_ptr<RSRenderNode>& parent,
1851     bool parentDirty, std::optional<RectI> clipRect)
1852 {
1853     // no need to update invisible nodes
1854     if (!ShouldPaint() && !isLastVisible_) {
1855         SetClean();
1856         GetMutableRenderProperties().ResetDirty();
1857         return false;
1858     }
1859     // [planning] surfaceNode use frame instead
1860     std::optional<Drawing::Point> offset;
1861     if (parent != nullptr && !IsInstanceOf<RSSurfaceRenderNode>()) {
1862         auto& properties = parent->GetRenderProperties();
1863         offset = Drawing::Point { properties.GetFrameOffsetX(), properties.GetFrameOffsetY() };
1864     }
1865     // in some case geodirty_ is not marked in drawCmdModifiers_, we should update node geometry
1866     // [planing] using drawcmdModifierDirty from dirtyType_
1867     parentDirty = parentDirty || (dirtyStatus_ != NodeDirty::CLEAN);
1868     auto parentProperties = parent ? &parent->GetRenderProperties() : nullptr;
1869     bool dirty = GetMutableRenderProperties().UpdateGeometry(parentProperties, parentDirty, offset);
1870     isDirtyRegionUpdated_ = false;
1871     isLastVisible_ = ShouldPaint();
1872     GetMutableRenderProperties().ResetDirty();
1873 
1874     // Note:
1875     // 1. cache manager will use dirty region to update cache validity, background filter cache manager should use
1876     // 'dirty region of all the nodes drawn before this node', and foreground filter cache manager should use 'dirty
1877     // region of all the nodes drawn before this node, this node, and the children of this node'
1878     // 2. Filter must be valid when filter cache manager is valid, we make sure that in RSRenderNode::ApplyModifiers().
1879     if (GetRenderProperties().GetBackgroundFilter()) {
1880         UpdateFilterCacheWithBelowDirty(Occlusion::Rect(dirtyManager.GetCurrentFrameDirtyRegion()));
1881     }
1882     UpdateDirtyRegion(dirtyManager, dirty, clipRect);
1883     return dirty;
1884 }
1885 
UpdateBufferDirtyRegion(RectI & dirtyRect,const RectI & drawRegion)1886 bool RSRenderNode::UpdateBufferDirtyRegion(RectI& dirtyRect, const RectI& drawRegion)
1887 {
1888 #ifndef ROSEN_CROSS_PLATFORM
1889     if (GetType() != RSRenderNodeType::SURFACE_NODE) {
1890         return false;
1891     }
1892     auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
1893     if (surfaceNode == nullptr) {
1894         return false;
1895     }
1896     auto surfaceHandler = surfaceNode->GetRSSurfaceHandler();
1897     auto buffer = surfaceHandler->GetBuffer();
1898     if (buffer != nullptr) {
1899         // Use the matrix from buffer to relative coordinate and the absolute matrix
1900         // to calculate the buffer damageRegion's absolute rect
1901         auto rect = surfaceHandler->GetDamageRegion();
1902         auto matrix = surfaceNode->GetBufferRelMatrix();
1903         matrix.PostConcat(GetRenderProperties().GetBoundsGeometry()->GetAbsMatrix());
1904         auto bufferDirtyRect = GetRenderProperties().GetBoundsGeometry()->MapRect(
1905             RectF(rect.x, rect.y, rect.w, rect.h), matrix);
1906         bufferDirtyRect.JoinRect(drawRegion);
1907         // The buffer's dirtyRect should not be out of the scope of the node's dirtyRect
1908         dirtyRect = bufferDirtyRect.IntersectRect(dirtyRect);
1909         RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode id: %" PRIu64 ", buffer size [%d,%d], "
1910             "buffer damageRegion [%d,%d,%d,%d], dirtyRect %s", GetId(),
1911             buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(),
1912             rect.x, rect.y, rect.w, rect.h, dirtyRect.ToString().c_str());
1913         return true;
1914     }
1915 #endif
1916     return false;
1917 }
1918 
UpdateDirtyRegion(RSDirtyRegionManager & dirtyManager,bool geoDirty,const std::optional<RectI> & clipRect)1919 void RSRenderNode::UpdateDirtyRegion(
1920     RSDirtyRegionManager& dirtyManager, bool geoDirty, const std::optional<RectI>& clipRect)
1921 {
1922     if (!IsDirty() && !geoDirty) {
1923         return;
1924     }
1925     if (RSSystemProperties::GetSkipGeometryNotChangeEnabled()) {
1926         // while node absRect not change and other content not change, return directly for not generate dirty region
1927         if (!IsSelfDrawingNode() && !geometryChangeNotPerceived_ && !geoDirty) {
1928             return;
1929         }
1930         geometryChangeNotPerceived_ = false;
1931     }
1932     if (!oldDirty_.IsEmpty()) {
1933         dirtyManager.MergeDirtyRect(oldDirty_);
1934     }
1935     // merge old dirty if switch to invisible
1936     if (!ShouldPaint() && isLastVisible_) {
1937         ROSEN_LOGD("RSRenderNode:: id %{public}" PRIu64 " UpdateDirtyRegion visible->invisible", GetId());
1938     } else {
1939         RectI drawRegion;
1940         RectI shadowRect;
1941         auto& properties = GetRenderProperties();
1942         auto dirtyRect = properties.GetDirtyRect(drawRegion);
1943         auto rectFromRenderProperties = dirtyRect;
1944         // When surface node with buffer has damageRegion, use this instead of the node size
1945         if (UpdateBufferDirtyRegion(dirtyRect, drawRegion)) {
1946             // Add node's last and current frame absRect when the node size change
1947             if (rectFromRenderProperties != oldRectFromRenderProperties_) {
1948                 dirtyManager.MergeDirtyRect(oldRectFromRenderProperties_);
1949                 dirtyRect.JoinRect(rectFromRenderProperties);
1950                 oldRectFromRenderProperties_ = rectFromRenderProperties;
1951             }
1952         }
1953 
1954         // Add node's shadow region to dirtyRect
1955         if (properties.IsShadowValid()) {
1956             SetShadowValidLastFrame(true);
1957             if (IsInstanceOf<RSSurfaceRenderNode>()) {
1958                 const RectF absBounds = {0, 0, properties.GetBoundsWidth(),
1959                     properties.GetBoundsHeight()};
1960                 RRect absClipRRect = RRect(absBounds, properties.GetCornerRadius());
1961                 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, properties, &absClipRRect);
1962             } else {
1963                 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, properties);
1964             }
1965             if (!shadowRect.IsEmpty()) {
1966                 // Avoid deviation caused by converting float to int
1967                 shadowRect = shadowRect.MakeOutset({1, 1, 1, 1});
1968                 dirtyRect = dirtyRect.JoinRect(shadowRect);
1969             }
1970         }
1971 
1972         // Add node's outline region to dirtyRect
1973         auto& outline = properties.GetOutline();
1974         RectI outlineRect;
1975         if (outline && outline->HasBorder()) {
1976             RSPropertiesPainter::GetOutlineDirtyRect(outlineRect, properties);
1977             if (!outlineRect.IsEmpty()) {
1978                 dirtyRect = dirtyRect.JoinRect(outlineRect);
1979             }
1980         }
1981 
1982         // Add node's pixelStretch region to dirtyRect
1983         if (properties.pixelStretch_) {
1984             auto stretchDirtyRect = properties.GetPixelStretchDirtyRect();
1985             dirtyRect = dirtyRect.JoinRect(stretchDirtyRect);
1986         }
1987 
1988         // Add node's foregroundEffect region to dirtyRect
1989         std::shared_ptr<RSFilter> foregroundFilter = nullptr;
1990         if (RSProperties::IS_UNI_RENDER) {
1991             foregroundFilter = properties.GetForegroundFilterCache();
1992         } else {
1993             foregroundFilter = properties.GetForegroundFilter();
1994         }
1995         if (foregroundFilter && foregroundFilter->GetFilterType() == RSFilter::FOREGROUND_EFFECT) {
1996             float dirtyExtension =
1997                 std::static_pointer_cast<RSForegroundEffectFilter>(foregroundFilter)->GetDirtyExtension();
1998             dirtyRect = dirtyRect.MakeOutset(Vector4<int>(dirtyExtension));
1999         }
2000 
2001         if (clipRect.has_value()) {
2002             dirtyRect = dirtyRect.IntersectRect(*clipRect);
2003         }
2004         oldDirty_ = dirtyRect;
2005         oldDirtyInSurface_ = oldDirty_.IntersectRect(dirtyManager.GetSurfaceRect());
2006         // filter invalid dirtyrect
2007         if (!dirtyRect.IsEmpty()) {
2008             dirtyManager.MergeDirtyRect(dirtyRect);
2009             isDirtyRegionUpdated_ = true;
2010             // save types of dirty region of target dirty manager for dfx
2011             if (dirtyManager.IsTargetForDfx() &&
2012                 (GetType() == RSRenderNodeType::CANVAS_NODE || GetType() == RSRenderNodeType::SURFACE_NODE)) {
2013                 dirtyManager.UpdateDirtyRegionInfoForDfx(
2014                     GetId(), GetType(), DirtyRegionType::UPDATE_DIRTY_REGION, oldDirtyInSurface_);
2015                 dirtyManager.UpdateDirtyRegionInfoForDfx(
2016                     GetId(), GetType(), DirtyRegionType::OVERLAY_RECT, drawRegion);
2017                 dirtyManager.UpdateDirtyRegionInfoForDfx(
2018                     GetId(), GetType(), DirtyRegionType::SHADOW_RECT, shadowRect);
2019                 dirtyManager.UpdateDirtyRegionInfoForDfx(
2020                     GetId(), GetType(), DirtyRegionType::PREPARE_CLIP_RECT, clipRect.value_or(RectI()));
2021                 dirtyManager.UpdateDirtyRegionInfoForDfx(
2022                     GetId(), GetType(), DirtyRegionType::RENDER_PROPERTIES_RECT, rectFromRenderProperties);
2023                 dirtyManager.UpdateDirtyRegionInfoForDfx(
2024                     GetId(), GetType(), DirtyRegionType::OUTLINE_RECT, outlineRect);
2025             }
2026         }
2027     }
2028 
2029     SetClean();
2030 }
2031 
IsSelfDrawingNode() const2032 bool RSRenderNode::IsSelfDrawingNode() const
2033 {
2034     return GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE || GetType() == RSRenderNodeType::SURFACE_NODE;
2035 }
2036 
IsDirty() const2037 bool RSRenderNode::IsDirty() const
2038 {
2039     return dirtyStatus_ != NodeDirty::CLEAN || GetRenderProperties().IsDirty();
2040 }
2041 
SetParentSubTreeDirty()2042 void RSRenderNode::SetParentSubTreeDirty()
2043 {
2044     auto parentNode = parent_.lock();
2045     if (parentNode && !parentNode->IsSubTreeDirty()) {
2046         parentNode->SetSubTreeDirty(true);
2047         parentNode->SetParentSubTreeDirty();
2048     }
2049 }
2050 
IsTreeStateChangeDirty() const2051 bool RSRenderNode::IsTreeStateChangeDirty() const
2052 {
2053     return isTreeStateChangeDirty_;
2054 }
2055 
SetTreeStateChangeDirty(bool val)2056 void RSRenderNode::SetTreeStateChangeDirty(bool val)
2057 {
2058     isTreeStateChangeDirty_ = val;
2059 }
2060 
SetParentTreeStateChangeDirty()2061 void RSRenderNode::SetParentTreeStateChangeDirty()
2062 {
2063     auto parentNode = parent_.lock();
2064     if (parentNode && !parentNode->IsTreeStateChangeDirty()) {
2065         parentNode->SetTreeStateChangeDirty(true);
2066         parentNode->SetParentTreeStateChangeDirty();
2067     }
2068 }
2069 
IsContentDirty() const2070 bool RSRenderNode::IsContentDirty() const
2071 {
2072     // Considering renderNode, it should consider both basenode's case and its properties
2073     return isContentDirty_ || GetRenderProperties().IsContentDirty();
2074 }
2075 
UpdateRenderStatus(RectI & dirtyRegion,bool isPartialRenderEnabled)2076 void RSRenderNode::UpdateRenderStatus(RectI& dirtyRegion, bool isPartialRenderEnabled)
2077 {
2078     auto dirtyRect = GetRenderProperties().GetDirtyRect();
2079     // should judge if there's any child out of parent
2080     if (!isPartialRenderEnabled || HasChildrenOutOfRect()) {
2081         isRenderUpdateIgnored_ = false;
2082     } else if (dirtyRegion.IsEmpty() || dirtyRect.IsEmpty()) {
2083         isRenderUpdateIgnored_ = true;
2084     } else {
2085         RectI intersectRect = dirtyRegion.IntersectRect(dirtyRect);
2086         isRenderUpdateIgnored_ = intersectRect.IsEmpty();
2087     }
2088 }
2089 
2090 
UpdateParentChildrenRect(std::shared_ptr<RSRenderNode> parentNode) const2091 void RSRenderNode::UpdateParentChildrenRect(std::shared_ptr<RSRenderNode> parentNode) const
2092 {
2093     if (!shouldPaint_ || (oldDirty_.IsEmpty() && GetChildrenRect().IsEmpty())) {
2094         return;
2095     }
2096     if (parentNode) {
2097         // accumulate current node's all children region(including itself)
2098         // apply oldDirty_ as node's real region(including overlay and shadow)
2099         RectI accumulatedRect = GetChildrenRect().JoinRect(oldDirty_);
2100         parentNode->UpdateChildrenRect(accumulatedRect);
2101         // check each child is inside of parent
2102         if (!accumulatedRect.IsInsideOf(parentNode->GetOldDirty())) {
2103             parentNode->UpdateChildrenOutOfRectFlag(true);
2104         }
2105     }
2106 }
2107 
IsFilterCacheValid() const2108 bool RSRenderNode::IsFilterCacheValid() const
2109 {
2110 #ifdef RS_ENABLE_GPU
2111     if (!RSSystemProperties::GetBlurEnabled() || !RSProperties::filterCacheEnabled_) {
2112         ROSEN_LOGD("IsBackgroundFilterCacheValid::blur is disabled or filter cache is disabled.");
2113         return false;
2114     }
2115     auto filterDrawable = GetRenderProperties().GetFilter() != nullptr ?
2116         GetFilterDrawable(true) : GetFilterDrawable(false);
2117     if (filterDrawable == nullptr) {
2118         return false;
2119     }
2120     return filterDrawable->IsFilterCacheValid();
2121 #endif
2122     return false;
2123 }
2124 
IsAIBarFilter() const2125 bool RSRenderNode::IsAIBarFilter() const
2126 {
2127     if (!RSSystemProperties::GetBlurEnabled() || !RSProperties::filterCacheEnabled_) {
2128         ROSEN_LOGD("blur is disabled or filter cache is disabled.");
2129         return false;
2130     }
2131     auto filterDrawable = GetRenderProperties().GetFilter() != nullptr ?
2132         GetFilterDrawable(true) : GetFilterDrawable(false);
2133     if (filterDrawable == nullptr) {
2134         return false;
2135     }
2136     return filterDrawable->IsAIBarFilter();
2137 }
2138 
CheckAndUpdateAIBarCacheStatus(bool intersectHwcDamage) const2139 bool RSRenderNode::CheckAndUpdateAIBarCacheStatus(bool intersectHwcDamage) const
2140 {
2141 #ifdef RS_ENABLE_GPU
2142     if (!RSSystemProperties::GetBlurEnabled() || !RSProperties::filterCacheEnabled_) {
2143         ROSEN_LOGD("IsBackgroundFilterCacheValid::blur is disabled or filter cache is disabled.");
2144         return false;
2145     }
2146     auto filterDrawable = GetRenderProperties().GetFilter() != nullptr ?
2147         GetFilterDrawable(true) : GetFilterDrawable(false);
2148     if (filterDrawable == nullptr) {
2149         return false;
2150     }
2151     return filterDrawable->CheckAndUpdateAIBarCacheStatus(intersectHwcDamage);
2152 #endif
2153 return false;
2154 }
2155 
GetFilterCachedRegion() const2156 const RectI RSRenderNode::GetFilterCachedRegion() const
2157 {
2158     return lastFilterRegion_;
2159 }
2160 
HasBlurFilter() const2161 bool RSRenderNode::HasBlurFilter() const
2162 {
2163     return GetRenderProperties().GetBackgroundFilter() || GetRenderProperties().GetFilter();
2164 }
2165 
UpdateLastFilterCacheRegion()2166 void RSRenderNode::UpdateLastFilterCacheRegion()
2167 {
2168     lastFilterRegion_ = filterRegion_;
2169 }
2170 
GetAbsMatrixReverse(const RSRenderNode & rootNode,Drawing::Matrix & absMatrix)2171 bool RSRenderNode::GetAbsMatrixReverse(const RSRenderNode& rootNode, Drawing::Matrix& absMatrix)
2172 {
2173     auto& rootProperties = rootNode.GetRenderProperties();
2174     auto rootGeo = rootProperties.GetBoundsGeometry();
2175     auto selfGeo = GetRenderProperties().GetBoundsGeometry();
2176     if (!rootGeo || !selfGeo) {
2177         return false;
2178     }
2179     Drawing::Matrix selfMatrix = selfGeo->GetMatrix();
2180     auto directParent = GetParent().lock();
2181     while (directParent && directParent->GetId() != rootNode.GetId()) {
2182         if (auto parentGeo = directParent->GetRenderProperties().GetBoundsGeometry()) {
2183             selfMatrix.PostConcat(parentGeo->GetMatrix());
2184         }
2185         directParent = directParent->GetParent().lock();
2186     }
2187     if (!directParent) {
2188         return false;
2189     }
2190     selfMatrix.PostConcat(rootGeo->GetAbsMatrix());
2191     absMatrix = selfMatrix;
2192     return true;
2193 }
2194 
UpdateFilterRegionInSkippedSubTree(RSDirtyRegionManager & dirtyManager,const RSRenderNode & subTreeRoot,RectI & filterRect,const RectI & clipRect)2195 void RSRenderNode::UpdateFilterRegionInSkippedSubTree(RSDirtyRegionManager& dirtyManager,
2196     const RSRenderNode& subTreeRoot, RectI& filterRect, const RectI& clipRect)
2197 {
2198     Drawing::Matrix absMatrix;
2199     if (!GetAbsMatrixReverse(subTreeRoot, absMatrix)) {
2200         return;
2201     }
2202     absDrawRect_ = RSObjAbsGeometry::MapRect(selfDrawRect_, absMatrix);
2203     oldDirtyInSurface_ = absDrawRect_.IntersectRect(clipRect);
2204     filterRect = RSObjAbsGeometry::MapRect(GetRenderProperties().GetBoundsRect(), absMatrix);
2205     filterRect = filterRect.IntersectRect(clipRect);
2206     filterRegion_ = filterRect;
2207     if (filterRect == lastFilterRegion_) {
2208         return;
2209     }
2210     dirtyManager.MergeDirtyRect(filterRect);
2211     isDirtyRegionUpdated_ = true;
2212 }
2213 
CheckBlurFilterCacheNeedForceClearOrSave(bool rotationChanged,bool rotationStatusChanged)2214 void RSRenderNode::CheckBlurFilterCacheNeedForceClearOrSave(bool rotationChanged, bool rotationStatusChanged)
2215 {
2216 #ifdef RS_ENABLE_GPU
2217     bool rotationClear = false;
2218     if (!IsInstanceOf<RSEffectRenderNode>() && rotationChanged) {
2219         rotationClear = true;
2220     }
2221     const auto& properties = GetRenderProperties();
2222     if (properties.GetBackgroundFilter()) {
2223         auto filterDrawable = GetFilterDrawable(false);
2224         if (filterDrawable != nullptr) {
2225             auto bgDirty = dirtySlots_.count(RSDrawableSlot::BACKGROUND_COLOR) ||
2226                 dirtySlots_.count(RSDrawableSlot::BACKGROUND_SHADER) ||
2227                 dirtySlots_.count(RSDrawableSlot::BACKGROUND_IMAGE);
2228             if (!(filterDrawable->IsForceClearFilterCache()) && (rotationClear || bgDirty)) {
2229                 RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode[%llu] background color or shader or image is dirty", GetId());
2230                 filterDrawable->MarkFilterForceClearCache();
2231             }
2232         }
2233     }
2234     if (IsInstanceOf<RSEffectRenderNode>()) {
2235         rotationStatusChanged = false;
2236     }
2237     if (properties.GetFilter()) {
2238         auto filterDrawable = GetFilterDrawable(true);
2239         if (filterDrawable != nullptr) {
2240             if (!(filterDrawable->IsForceClearFilterCache()) && (rotationStatusChanged || !dirtySlots_.empty())) {
2241                 RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode[%llu] foreground is dirty", GetId());
2242                 filterDrawable->MarkFilterForceClearCache();
2243             }
2244         }
2245     }
2246 #endif
2247 }
2248 
MarkFilterInForegroundFilterAndCheckNeedForceClearCache(NodeId offscreenCanvasNodeId)2249 void RSRenderNode::MarkFilterInForegroundFilterAndCheckNeedForceClearCache(NodeId offscreenCanvasNodeId)
2250 {
2251 #ifdef RS_ENABLE_GPU
2252     const auto& properties = GetRenderProperties();
2253     if (properties.GetBackgroundFilter()) {
2254         auto filterDrawable = GetFilterDrawable(false);
2255         if (filterDrawable != nullptr) {
2256             filterDrawable->MarkInForegroundFilterAndCheckNeedForceClearCache(offscreenCanvasNodeId);
2257         }
2258     }
2259 
2260     if (properties.GetFilter()) {
2261         auto filterDrawable = GetFilterDrawable(true);
2262         if (filterDrawable != nullptr) {
2263             filterDrawable->MarkInForegroundFilterAndCheckNeedForceClearCache(offscreenCanvasNodeId);
2264         }
2265     }
2266 #endif
2267 }
2268 
2269 #ifdef RS_ENABLE_GPU
IsForceClearOrUseFilterCache(std::shared_ptr<DrawableV2::RSFilterDrawable> & filterDrawable)2270 bool RSRenderNode::IsForceClearOrUseFilterCache(std::shared_ptr<DrawableV2::RSFilterDrawable>& filterDrawable)
2271 {
2272     return filterDrawable->IsForceUseFilterCache() || filterDrawable->IsForceClearFilterCache();
2273 }
2274 #endif
MarkFilterStatusChanged(bool isForeground,bool isFilterRegionChanged)2275 void RSRenderNode::MarkFilterStatusChanged(bool isForeground, bool isFilterRegionChanged)
2276 {
2277 #ifdef RS_ENABLE_GPU
2278     auto filterDrawable = GetFilterDrawable(isForeground);
2279     if (filterDrawable == nullptr) {
2280         return;
2281     }
2282     auto& flag = isForeground ?
2283         (isFilterRegionChanged ? foregroundFilterRegionChanged_ : foregroundFilterInteractWithDirty_) :
2284         (isFilterRegionChanged ? backgroundFilterRegionChanged_ : backgroundFilterInteractWithDirty_);
2285     flag = true;
2286     isFilterRegionChanged ?
2287         filterDrawable->MarkFilterRegionChanged() : filterDrawable->MarkFilterRegionInteractWithDirty();
2288 #endif
2289 }
2290 #ifdef RS_ENABLE_GPU
GetFilterDrawable(bool isForeground) const2291 std::shared_ptr<DrawableV2::RSFilterDrawable> RSRenderNode::GetFilterDrawable(bool isForeground) const
2292 {
2293     auto slot = isForeground ? RSDrawableSlot::COMPOSITING_FILTER : RSDrawableSlot::BACKGROUND_FILTER;
2294     if (auto& drawable = drawableVec_[static_cast<uint32_t>(slot)]) {
2295         if (auto filterDrawable = std::static_pointer_cast<DrawableV2::RSFilterDrawable>(drawable)) {
2296             return filterDrawable;
2297         }
2298     }
2299     return nullptr;
2300 }
2301 #endif
UpdateFilterCacheWithBackgroundDirty()2302 void RSRenderNode::UpdateFilterCacheWithBackgroundDirty()
2303 {
2304 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2305     if (!RSProperties::filterCacheEnabled_) {
2306         return;
2307     }
2308     auto filterDrawable = GetFilterDrawable(false);
2309     if (filterDrawable == nullptr || IsForceClearOrUseFilterCache(filterDrawable)) {
2310         return;
2311     }
2312     auto hasBackground = drawableVec_[static_cast<int32_t>(RSDrawableSlot::BACKGROUND_COLOR)] ||
2313                          drawableVec_[static_cast<int32_t>(RSDrawableSlot::BACKGROUND_SHADER)] ||
2314                          drawableVec_[static_cast<int32_t>(RSDrawableSlot::BACKGROUND_IMAGE)];
2315     auto alphaDirty = dirtyTypesNG_.test(static_cast<size_t>(ModifierNG::RSModifierType::ALPHA));
2316     if (alphaDirty && hasBackground) {
2317         RS_OPTIONAL_TRACE_NAME_FMT(
2318             "RSRenderNode[%llu] background color or shader or image is dirty due to changes in alpha", GetId());
2319         filterDrawable->MarkFilterForceClearCache();
2320     }
2321 #endif
2322 }
2323 
UpdateFilterCacheWithBelowDirty(const Occlusion::Region & belowDirty,bool isForeground)2324 bool RSRenderNode::UpdateFilterCacheWithBelowDirty(const Occlusion::Region& belowDirty, bool isForeground)
2325 {
2326 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2327     if (!RSProperties::filterCacheEnabled_) {
2328         ROSEN_LOGE("RSRenderNode::UpdateFilterCacheWithBelowDirty filter cache is disabled.");
2329         return false;
2330     }
2331     auto filterDrawable = GetFilterDrawable(isForeground);
2332     if (filterDrawable == nullptr || IsForceClearOrUseFilterCache(filterDrawable)) {
2333         return false;
2334     }
2335     RS_OPTIONAL_TRACE_NAME_FMT("UpdateFilterCacheWithBelowDirty:node[%llu] foreground:%d, lastRect:%s, dirtyRegion:%s",
2336         GetId(), isForeground, lastFilterRegion_.ToString().c_str(), belowDirty.GetRegionInfo().c_str());
2337     if (!belowDirty.IsIntersectWith(lastFilterRegion_)) {
2338         return false;
2339     }
2340     MarkFilterStatusChanged(isForeground, false);
2341     return true;
2342 #else
2343     return false;
2344 #endif
2345 }
2346 
UpdateFilterCacheWithSelfDirty()2347 void RSRenderNode::UpdateFilterCacheWithSelfDirty()
2348 {
2349 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2350     if (!RSProperties::filterCacheEnabled_) {
2351         ROSEN_LOGE("RSRenderNode::UpdateFilterCacheWithSelfDirty filter cache is disabled.");
2352         return;
2353     }
2354     RS_OPTIONAL_TRACE_NAME_FMT("node[%llu] UpdateFilterCacheWithSelfDirty lastRect:%s, currRegion:%s",
2355         GetId(), lastFilterRegion_.ToString().c_str(), filterRegion_.ToString().c_str());
2356     const auto& properties = GetRenderProperties();
2357     if ((properties.GetBackgroundFilter() && !filterRegion_.IsInsideOf(lastFilterRegion_)) ||
2358         (properties.GetNeedDrawBehindWindow() && filterRegion_ != lastFilterRegion_)) {
2359         auto filterDrawable = GetFilterDrawable(false);
2360         if (filterDrawable != nullptr) {
2361             if (!IsForceClearOrUseFilterCache(filterDrawable)) {
2362                 MarkFilterStatusChanged(false, true);
2363             }
2364         }
2365     }
2366     if (properties.GetFilter() && filterRegion_ != lastFilterRegion_) {
2367         auto filterDrawable = GetFilterDrawable(true);
2368         if (filterDrawable != nullptr) {
2369             if (!IsForceClearOrUseFilterCache(filterDrawable)) {
2370                 MarkFilterStatusChanged(true, true);
2371             }
2372         }
2373     }
2374 #endif
2375 }
2376 
UpdateDirtySlotsAndPendingNodes(RSDrawableSlot slot)2377 void RSRenderNode::UpdateDirtySlotsAndPendingNodes(RSDrawableSlot slot)
2378 {
2379     dirtySlots_.emplace(slot);
2380     AddToPendingSyncList();
2381 }
2382 #ifdef RS_ENABLE_GPU
IsLargeArea(int width,int height)2383 inline static bool IsLargeArea(int width, int height)
2384 {
2385     static const auto threshold = RSSystemProperties::GetFilterCacheSizeThreshold();
2386     return width > threshold && height > threshold;
2387 }
2388 #endif
PostPrepareForBlurFilterNode(RSDirtyRegionManager & dirtyManager,bool needRequestNextVsync)2389 void RSRenderNode::PostPrepareForBlurFilterNode(RSDirtyRegionManager& dirtyManager, bool needRequestNextVsync)
2390 {
2391 #ifdef RS_ENABLE_GPU
2392     MarkFilterHasEffectChildren();
2393     if (!RSProperties::filterCacheEnabled_) {
2394         ROSEN_LOGE("RSRenderNode::PostPrepareForBlurFilterNode filter cache is disabled.");
2395         return;
2396     }
2397     const auto& properties = GetRenderProperties();
2398     if (properties.GetBackgroundFilter() || properties.GetNeedDrawBehindWindow()) {
2399         auto filterDrawable = GetFilterDrawable(false);
2400         if (filterDrawable != nullptr) {
2401             MarkFilterCacheFlags(filterDrawable, dirtyManager, needRequestNextVsync);
2402             CheckFilterCacheAndUpdateDirtySlots(filterDrawable, RSDrawableSlot::BACKGROUND_FILTER);
2403         }
2404     }
2405     if (properties.GetFilter()) {
2406         auto filterDrawable = GetFilterDrawable(true);
2407         if (filterDrawable != nullptr) {
2408             MarkFilterCacheFlags(filterDrawable, dirtyManager, needRequestNextVsync);
2409             CheckFilterCacheAndUpdateDirtySlots(filterDrawable, RSDrawableSlot::COMPOSITING_FILTER);
2410         }
2411     }
2412     OnFilterCacheStateChanged();
2413     UpdateLastFilterCacheRegion();
2414 #endif
2415 }
2416 #ifdef RS_ENABLE_GPU
MarkFilterCacheFlags(std::shared_ptr<DrawableV2::RSFilterDrawable> & filterDrawable,RSDirtyRegionManager & dirtyManager,bool needRequestNextVsync)2417 void RSRenderNode::MarkFilterCacheFlags(std::shared_ptr<DrawableV2::RSFilterDrawable>& filterDrawable,
2418     RSDirtyRegionManager& dirtyManager, bool needRequestNextVsync)
2419 {
2420     if (IsForceClearOrUseFilterCache(filterDrawable)) {
2421         return;
2422     }
2423 
2424     RS_OPTIONAL_TRACE_NAME_FMT("MarkFilterCacheFlags:node[%llu], NeedPendingPurge:%d,"
2425         " forceClearWithoutNextVsync:%d, filterRegion: %s",
2426         GetId(), filterDrawable->NeedPendingPurge(), (!needRequestNextVsync && filterDrawable->IsSkippingFrame()),
2427         filterRegion_.ToString().c_str());
2428     // force update if last frame use cache because skip-frame and current frame background is not dirty
2429     if (filterDrawable->NeedPendingPurge()) {
2430         dirtyManager.MergeDirtyRect(filterRegion_);
2431         isDirtyRegionUpdated_ = true;
2432         return;
2433     }
2434     // force update if no next vsync when skip-frame enabled
2435     if (!needRequestNextVsync && filterDrawable->IsSkippingFrame()) {
2436         filterDrawable->MarkForceClearCacheWithLastFrame();
2437         return;
2438     }
2439 
2440     // when background changed, skip-frame will enabled if filter region > 400 and blur radius > 25
2441     if (IsLargeArea(filterRegion_.GetWidth(), filterRegion_.GetHeight())) {
2442         filterDrawable->MarkFilterRegionIsLargeArea();
2443     }
2444 }
2445 
CheckFilterCacheAndUpdateDirtySlots(std::shared_ptr<DrawableV2::RSFilterDrawable> & filterDrawable,RSDrawableSlot slot)2446 void RSRenderNode::CheckFilterCacheAndUpdateDirtySlots(
2447     std::shared_ptr<DrawableV2::RSFilterDrawable>& filterDrawable, RSDrawableSlot slot)
2448 {
2449     if (filterDrawable == nullptr) {
2450         return;
2451     }
2452     filterDrawable->MarkNeedClearFilterCache();
2453     UpdateDirtySlotsAndPendingNodes(slot);
2454 }
2455 #endif
MarkForceClearFilterCacheWithInvisible()2456 void RSRenderNode::MarkForceClearFilterCacheWithInvisible()
2457 {
2458 #ifdef RS_ENABLE_GPU
2459     if (GetRenderProperties().GetBackgroundFilter()) {
2460         auto filterDrawable = GetFilterDrawable(false);
2461         if (filterDrawable != nullptr) {
2462             filterDrawable->MarkFilterForceClearCache();
2463             CheckFilterCacheAndUpdateDirtySlots(filterDrawable, RSDrawableSlot::BACKGROUND_FILTER);
2464         }
2465     }
2466     if (GetRenderProperties().GetFilter()) {
2467         auto filterDrawable = GetFilterDrawable(true);
2468         if (filterDrawable != nullptr) {
2469             filterDrawable->MarkFilterForceClearCache();
2470             CheckFilterCacheAndUpdateDirtySlots(filterDrawable, RSDrawableSlot::COMPOSITING_FILTER);
2471         }
2472     }
2473 #endif
2474 }
2475 
SetOccludedStatus(bool occluded)2476 void RSRenderNode::SetOccludedStatus(bool occluded)
2477 {
2478 #ifdef RS_ENABLE_GPU
2479     if (GetRenderProperties().GetBackgroundFilter()) {
2480         auto filterDrawable = GetFilterDrawable(false);
2481         if (filterDrawable != nullptr) {
2482             filterDrawable->MarkNodeIsOccluded(occluded);
2483         }
2484     }
2485     if (GetRenderProperties().GetFilter()) {
2486         auto filterDrawable = GetFilterDrawable(true);
2487         if (filterDrawable != nullptr) {
2488             filterDrawable->MarkNodeIsOccluded(occluded);
2489         }
2490     }
2491     isOccluded_ = occluded;
2492 #endif
2493 }
2494 
RenderTraceDebug() const2495 void RSRenderNode::RenderTraceDebug() const
2496 {
2497     if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
2498         RSPropertyTrace::GetInstance().PropertiesDisplayByTrace(GetId(),
2499             std::static_pointer_cast<RSObjAbsGeometry>(GetRenderProperties().GetBoundsGeometry()));
2500         RSPropertyTrace::GetInstance().TracePropertiesByNodeName(GetId(), GetNodeName(), GetRenderProperties());
2501     }
2502 }
2503 
DrawPropertyDrawable(RSDrawableSlot slot,RSPaintFilterCanvas & canvas)2504 void RSRenderNode::DrawPropertyDrawable(RSDrawableSlot slot, RSPaintFilterCanvas& canvas)
2505 {
2506     auto& drawablePtr = drawableVec_[static_cast<size_t>(slot)];
2507     if (!drawablePtr) {
2508         return;
2509     }
2510 
2511     auto recordingCanvas = canvas.GetRecordingCanvas();
2512     if (recordingCanvas == nullptr || !canvas.GetRecordDrawable()) {
2513         // non-recording canvas, draw directly
2514         Drawing::Rect rect = { 0, 0, GetRenderProperties().GetFrameWidth(), GetRenderProperties().GetFrameHeight() };
2515         drawablePtr->OnSync();
2516         drawablePtr->CreateDrawFunc()(&canvas, &rect);
2517         return;
2518     }
2519 
2520     auto castRecordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas());
2521     auto drawFunc = [sharedPtr = shared_from_this(), slot](Drawing::Canvas* canvas, const Drawing::Rect* rect) -> void {
2522         if (auto canvasPtr = static_cast<RSPaintFilterCanvas*>(canvas)) {
2523             sharedPtr->DrawPropertyDrawable(slot, *canvasPtr);
2524         }
2525     };
2526     // recording canvas, record lambda that draws the drawable
2527     castRecordingCanvas->DrawDrawFunc(std::move(drawFunc));
2528 }
2529 
DrawPropertyDrawableRange(RSDrawableSlot begin,RSDrawableSlot end,RSPaintFilterCanvas & canvas)2530 void RSRenderNode::DrawPropertyDrawableRange(RSDrawableSlot begin, RSDrawableSlot end, RSPaintFilterCanvas& canvas)
2531 {
2532     auto recordingCanvas = canvas.GetRecordingCanvas();
2533     if (recordingCanvas == nullptr || !canvas.GetRecordDrawable()) {
2534         // non-recording canvas, draw directly
2535         Drawing::Rect rect = { 0, 0, GetRenderProperties().GetFrameWidth(), GetRenderProperties().GetFrameHeight() };
2536         std::for_each(drawableVec_.begin() + static_cast<size_t>(begin),
2537             drawableVec_.begin() + static_cast<size_t>(end) + 1, // +1 since we need to include end
2538             [&](auto& drawablePtr) {
2539                 if (drawablePtr) {
2540                     drawablePtr->OnSync();
2541                     drawablePtr->CreateDrawFunc()(&canvas, &rect);
2542                 }
2543             });
2544         return;
2545     }
2546 
2547     auto castRecordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas());
2548     auto drawFunc = [sharedPtr = shared_from_this(), begin, end](
2549                         Drawing::Canvas* canvas, const Drawing::Rect* rect) -> void {
2550         if (auto canvasPtr = static_cast<RSPaintFilterCanvas*>(canvas)) {
2551             sharedPtr->DrawPropertyDrawableRange(begin, end, *canvasPtr);
2552         }
2553     };
2554     // recording canvas, record lambda that draws the drawable
2555     castRecordingCanvas->DrawDrawFunc(std::move(drawFunc));
2556 }
2557 
ApplyAlphaAndBoundsGeometry(RSPaintFilterCanvas & canvas)2558 void RSRenderNode::ApplyAlphaAndBoundsGeometry(RSPaintFilterCanvas& canvas)
2559 {
2560     canvas.ConcatMatrix(GetRenderProperties().GetBoundsGeometry()->GetMatrix());
2561     auto alpha = GetRenderProperties().GetAlpha();
2562     if (alpha == 1) {
2563         return;
2564     }
2565     if (GetRenderProperties().GetAlphaOffscreen()) {
2566         auto rect = RSPropertiesPainter::Rect2DrawingRect(GetRenderProperties().GetBoundsRect());
2567         Drawing::Brush brush;
2568         brush.SetAlpha(std::clamp(alpha, 0.f, 1.f) * UINT8_MAX);
2569         Drawing::SaveLayerOps slr(&rect, &brush);
2570         canvas.SaveLayer(slr);
2571         return;
2572     }
2573     canvas.MultiplyAlpha(alpha);
2574 }
2575 
ProcessTransitionBeforeChildren(RSPaintFilterCanvas & canvas)2576 void RSRenderNode::ProcessTransitionBeforeChildren(RSPaintFilterCanvas& canvas)
2577 {
2578     DrawPropertyDrawableRange(RSDrawableSlot::SAVE_ALL, RSDrawableSlot::MASK, canvas);
2579 }
2580 
ProcessRenderBeforeChildren(RSPaintFilterCanvas & canvas)2581 void RSRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
2582 {
2583     RSRenderNode::ProcessTransitionBeforeChildren(canvas);
2584 }
2585 
ProcessTransitionAfterChildren(RSPaintFilterCanvas & canvas)2586 void RSRenderNode::ProcessTransitionAfterChildren(RSPaintFilterCanvas& canvas)
2587 {
2588     DrawPropertyDrawable(RSDrawableSlot::RESTORE_ALL, canvas);
2589 }
2590 
ProcessRenderAfterChildren(RSPaintFilterCanvas & canvas)2591 void RSRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
2592 {
2593     DrawPropertyDrawable(RSDrawableSlot::RESTORE_ALL, canvas);
2594 }
2595 
SetUifirstSyncFlag(bool needSync)2596 void RSRenderNode::SetUifirstSyncFlag(bool needSync)
2597 {
2598     uifirstNeedSync_ = needSync;
2599 }
2600 
GetProperty(PropertyId id)2601 std::shared_ptr<RSRenderPropertyBase> RSRenderNode::GetProperty(PropertyId id)
2602 {
2603     auto it = properties_.find(id);
2604     if (it == properties_.end()) {
2605         return nullptr;
2606     }
2607     return it->second;
2608 }
2609 
RegisterProperty(const std::shared_ptr<RSRenderPropertyBase> & property)2610 void RSRenderNode::RegisterProperty(const std::shared_ptr<RSRenderPropertyBase>& property)
2611 {
2612     if (property) {
2613         properties_.emplace(property->GetId(), property);
2614     }
2615 }
2616 
UnregisterProperty(const std::shared_ptr<RSRenderPropertyBase> & property)2617 void RSRenderNode::UnregisterProperty(const std::shared_ptr<RSRenderPropertyBase>& property)
2618 {
2619     if (property) {
2620         properties_.erase(property->GetId());
2621     }
2622 }
2623 
UnregisterProperty(PropertyId id)2624 void RSRenderNode::UnregisterProperty(PropertyId id)
2625 {
2626     properties_.erase(id);
2627 }
2628 
DumpNodeInfo(DfxString & log)2629 void RSRenderNode::DumpNodeInfo(DfxString& log)
2630 {
2631     // Drawing is not supported
2632 }
2633 
AccumulateDirtyInOcclusion(bool isOccluded)2634 void RSRenderNode::AccumulateDirtyInOcclusion(bool isOccluded)
2635 {
2636     if (isOccluded) {
2637         // accumulate dirtytypes for modifiers
2638         AccumulateDirtyTypes();
2639         // accumulate dirtystatus in rendernode
2640         AccumulateDirtyStatus();
2641         // accumulate dirtystatus in render properties(isDirty, geoDirty, contentDirty)
2642         GetMutableRenderProperties().AccumulateDirtyStatus();
2643         return;
2644     }
2645     ResetAccumulateDirtyTypes();
2646     ResetAccumulateDirtyStatus();
2647 }
2648 
RecordCurDirtyStatus()2649 void RSRenderNode::RecordCurDirtyStatus()
2650 {
2651     curDirtyStatus_ = dirtyStatus_;
2652     GetMutableRenderProperties().RecordCurDirtyStatus();
2653 }
2654 
AccumulateDirtyStatus()2655 void RSRenderNode::AccumulateDirtyStatus()
2656 {
2657     GetMutableRenderProperties().AccumulateDirtyStatus();
2658     if (curDirtyStatus_ == NodeDirty::CLEAN) {
2659         return;
2660     }
2661     SetDirty();
2662 }
2663 
ResetAccumulateDirtyStatus()2664 void RSRenderNode::ResetAccumulateDirtyStatus()
2665 {
2666     dirtyStatus_ = NodeDirty::CLEAN;
2667     GetMutableRenderProperties().ResetDirty();
2668 }
2669 
RecordCurDirtyTypes()2670 void RSRenderNode::RecordCurDirtyTypes()
2671 {
2672     curDirtyTypesNG_ |= ~dirtyTypesNG_;
2673 }
2674 
AccumulateDirtyTypes()2675 void RSRenderNode::AccumulateDirtyTypes()
2676 {
2677     dirtyTypesNG_ |= ~curDirtyTypesNG_;
2678 }
2679 
ResetAccumulateDirtyTypes()2680 void RSRenderNode::ResetAccumulateDirtyTypes()
2681 {
2682     dirtyTypesNG_.reset();
2683 }
2684 
ApplyPositionZModifier()2685 void RSRenderNode::ApplyPositionZModifier()
2686 {
2687     constexpr auto transformModifierTypeNG = static_cast<uint16_t>(ModifierNG::RSModifierType::TRANSFORM);
2688     if (!dirtyTypesNG_.test(transformModifierTypeNG)) {
2689         return;
2690     }
2691     auto& transformModifiers = modifiersNG_[transformModifierTypeNG];
2692     if (transformModifiers.empty()) {
2693         return;
2694     }
2695     auto displayNode = RSBaseRenderNode::ReinterpretCast<RSLogicalDisplayRenderNode>(shared_from_this());
2696     int32_t currentScbPid = displayNode == nullptr ? -1 : displayNode->GetCurrentScbPid();
2697     ModifierNG::RSTransformRenderModifier::ResetProperties(GetMutableRenderProperties());
2698     for (auto& modifier : transformModifiers) {
2699         if (currentScbPid == -1 || ExtractPid(modifier->GetId()) == currentScbPid) {
2700             modifier->ApplyLegacyProperty(GetMutableRenderProperties());
2701         }
2702     }
2703     dirtyTypesNG_.reset(transformModifierTypeNG);
2704 }
2705 
SetChildHasSharedTransition(bool val)2706 void RSRenderNode::SetChildHasSharedTransition(bool val)
2707 {
2708     childHasSharedTransition_ = val;
2709 }
2710 
ChildHasSharedTransition() const2711 bool RSRenderNode::ChildHasSharedTransition() const
2712 {
2713     return childHasSharedTransition_;
2714 }
2715 
MarkForegroundFilterCache()2716 void RSRenderNode::MarkForegroundFilterCache()
2717 {
2718     if (GetRenderProperties().GetForegroundFilterCache() != nullptr) {
2719         MarkNodeGroup(NodeGroupType::GROUPED_BY_FOREGROUND_FILTER, true, true);
2720     } else if (nodeGroupType_ & NodeGroupType::GROUPED_BY_FOREGROUND_FILTER) { // clear foreground filter cache
2721         MarkNodeGroup(NodeGroupType::GROUPED_BY_FOREGROUND_FILTER, false, false);
2722     }
2723 }
2724 
ResetAndApplyModifiers()2725 void RSRenderNode::ResetAndApplyModifiers()
2726 {
2727     auto displayNode = RSBaseRenderNode::ReinterpretCast<RSLogicalDisplayRenderNode>(shared_from_this());
2728     int32_t currentScbPid = displayNode == nullptr ? -1 : displayNode->GetCurrentScbPid();
2729     bool needUseCmdlistDrawRegion = GetNeedUseCmdlistDrawRegion();
2730     for (const auto& [modifierType, resetFunc] : ModifierNG::RSRenderModifier::GetResetFuncMap()) {
2731         if (dirtyTypesNG_.test(static_cast<size_t>(modifierType))) {
2732             resetFunc(GetMutableRenderProperties());
2733         }
2734     }
2735     for (uint16_t type = 0; type < ModifierNG::MODIFIER_TYPE_COUNT; type++) {
2736         auto& slot = modifiersNG_[type];
2737         if (slot.empty() || !dirtyTypesNG_.test(type)) {
2738             continue;
2739         }
2740         for (auto modifier : slot) {
2741             if (currentScbPid == -1 || ExtractPid(modifier->GetId()) == currentScbPid) {
2742                 modifier->ApplyLegacyProperty(GetMutableRenderProperties());
2743                 if (needUseCmdlistDrawRegion) {
2744                     cmdlistDrawRegion_ =
2745                         RSOptimizeCanvasDirtyCollector::GetInstance().CalcCmdlistDrawRegionFromOpItem(modifier);
2746                 }
2747             }
2748         }
2749     }
2750     // execute hooks
2751     GetMutableRenderProperties().OnApplyModifiers();
2752     OnApplyModifiers();
2753 }
2754 
ApplyModifiers()2755 CM_INLINE void RSRenderNode::ApplyModifiers()
2756 {
2757     RS_LOGI_IF(DEBUG_NODE, "RSRenderNode::apply modifiers isFullChildrenListValid_:%{public}d"
2758         " isChildrenSorted_:%{public}d childrenHasSharedTransition_:%{public}d",
2759         isFullChildrenListValid_, isChildrenSorted_, childrenHasSharedTransition_);
2760     if (const auto& sharedTransitionParam = GetSharedTransitionParam()) {
2761         sharedTransitionParam->UpdateHierarchy(GetId());
2762         SharedTransitionParam::UpdateUnpairedSharedTransitionMap(sharedTransitionParam);
2763     }
2764     if (UNLIKELY(!isFullChildrenListValid_)) {
2765         GenerateFullChildrenList();
2766         AddDirtyType(ModifierNG::RSModifierType::CHILDREN);
2767     } else if (UNLIKELY(!isChildrenSorted_)) {
2768         ResortChildren();
2769         AddDirtyType(ModifierNG::RSModifierType::CHILDREN);
2770     } else if (UNLIKELY(childrenHasSharedTransition_)) {
2771         // if children has shared transition, force regenerate RSChildrenDrawable
2772         AddDirtyType(ModifierNG::RSModifierType::CHILDREN);
2773     } else if (!RSRenderNode::IsDirty() || dirtyTypesNG_.none()) {
2774         RS_LOGD("RSRenderNode::apply modifiers RSRenderNode's dirty is false or dirtyTypes_ is none");
2775         // clean node, skip apply
2776         return;
2777     }
2778     RecordCurDirtyTypes();
2779     // Reset and re-apply all modifiers
2780     ResetAndApplyModifiers();
2781     MarkForegroundFilterCache();
2782     UpdateShouldPaint();
2783 
2784     if (dirtyTypesNG_.test(static_cast<size_t>(ModifierNG::RSModifierType::USE_EFFECT))) {
2785         ProcessBehindWindowAfterApplyModifiers();
2786     }
2787 
2788     RS_LOGI_IF(DEBUG_NODE,
2789         "RSRenderNode::apply modifiers RenderProperties's sandBox's hasValue is %{public}d"
2790         " isTextureExportNode_:%{public}d", GetRenderProperties().GetSandBox().has_value(),
2791         isTextureExportNode_);
2792     if ((dirtyTypesNG_.test(static_cast<size_t>(ModifierNG::RSModifierType::TRANSFORM))) &&
2793         !GetRenderProperties().GetSandBox().has_value() && sharedTransitionParam_) {
2794         auto paramCopy = sharedTransitionParam_;
2795         paramCopy->InternalUnregisterSelf();
2796     }
2797     if (dirtyTypesNG_.test(static_cast<size_t>(ModifierNG::RSModifierType::FOREGROUND_FILTER)) ||
2798         dirtyTypesNG_.test(static_cast<size_t>(ModifierNG::RSModifierType::BOUNDS))) {
2799         std::shared_ptr<RSFilter> foregroundFilter = nullptr;
2800         if (RSProperties::IS_UNI_RENDER) {
2801             foregroundFilter = GetRenderProperties().GetForegroundFilterCache();
2802         } else {
2803             foregroundFilter = GetRenderProperties().GetForegroundFilter();
2804         }
2805         if (foregroundFilter) {
2806             GetMutableRenderProperties().SetForegroundEffectDirty(true);
2807         }
2808     }
2809 
2810     // Temporary code, copy matrix into render params
2811     if (GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) {
2812         auto canvasdrawingnode = ReinterpretCastTo<RSCanvasDrawingRenderNode>();
2813         canvasdrawingnode->CheckCanvasDrawingPostPlaybacked();
2814     }
2815     UpdateDrawableVecV2();
2816 
2817     UpdateFilterCacheWithBackgroundDirty();
2818 
2819     // Clear node some resource
2820     ClearResource();
2821     // update state
2822     dirtyTypesNG_.reset();
2823     AddToPendingSyncList();
2824 
2825     // update rate decider scale reference size and scale.
2826     animationManager_.SetRateDeciderSize(GetRenderProperties().GetBoundsWidth(),
2827         GetRenderProperties().GetBoundsHeight());
2828     animationManager_.SetRateDeciderScale(GetRenderProperties().GetScaleX(), GetRenderProperties().GetScaleY());
2829     auto& rect = GetRenderProperties().GetBoundsGeometry()->GetAbsRect();
2830     animationManager_.SetRateDeciderAbsRect(rect.GetWidth(), rect.GetHeight());
2831 }
2832 
MarkParentNeedRegenerateChildren() const2833 void RSRenderNode::MarkParentNeedRegenerateChildren() const
2834 {
2835     auto parent = GetParent().lock();
2836     if (parent == nullptr) {
2837         return;
2838     }
2839     parent->isChildrenSorted_ = false;
2840 }
2841 
GetBlurEffectDrawbleCount()2842 int RSRenderNode::GetBlurEffectDrawbleCount()
2843 {
2844     bool fgFilterValid = drawableVec_[static_cast<int32_t>(RSDrawableSlot::FOREGROUND_FILTER)] != nullptr;
2845     bool bgFilterValid = drawableVec_[static_cast<int32_t>(RSDrawableSlot::BACKGROUND_FILTER)] != nullptr;
2846     bool cpFilterValid = drawableVec_[static_cast<int32_t>(RSDrawableSlot::COMPOSITING_FILTER)] != nullptr;
2847     return static_cast<int>(fgFilterValid) + static_cast<int>(bgFilterValid) + static_cast<int>(cpFilterValid);
2848 }
2849 
UpdateDrawableVecV2()2850 void RSRenderNode::UpdateDrawableVecV2()
2851 {
2852 #ifdef RS_ENABLE_GPU
2853     // Step 1: Collect dirty slots
2854     auto dirtySlots = RSDrawable::CalculateDirtySlotsNG(dirtyTypesNG_, drawableVec_);
2855     if (dirtySlots.empty()) {
2856         RS_LOGD("RSRenderNode::update drawable VecV2 dirtySlots is empty");
2857         return;
2858     }
2859     auto preBlurDrawableCnt = GetBlurEffectDrawbleCount();
2860     // Step 2: Update or regenerate drawable if needed
2861     bool drawableChanged = RSDrawable::UpdateDirtySlots(*this, drawableVec_, dirtySlots);
2862     // Step 2.1 (optional): fuze some drawables
2863     RSDrawable::FuzeDrawableSlots(*this, drawableVec_);
2864     // If any drawable has changed, or the CLIP_TO_BOUNDS slot has changed, then we need to recalculate
2865     // save/clip/restore.
2866     RS_LOGI_IF(DEBUG_NODE,
2867         "RSRenderNode::update drawable VecV2 drawableChanged:%{public}d", drawableChanged);
2868     if (GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) {
2869         auto canvasdrawingnode = ReinterpretCastTo<RSCanvasDrawingRenderNode>();
2870         drawableChanged |= canvasdrawingnode->GetIsPostPlaybacked();
2871     }
2872     if (drawableChanged || dirtySlots.count(RSDrawableSlot::CLIP_TO_BOUNDS)) {
2873         // Step 3: Recalculate save/clip/restore on demands
2874         RSDrawable::UpdateSaveRestore(*this, drawableVec_, drawableVecStatus_);
2875         // if shadow changed, update shadow rect
2876         UpdateShadowRect();
2877         UpdateDirtySlotsAndPendingNodes(RSDrawableSlot::SHADOW);
2878         std::unordered_set<RSDrawableSlot> dirtySlotShadow;
2879         dirtySlotShadow.emplace(RSDrawableSlot::SHADOW);
2880         RSDrawable::UpdateDirtySlots(*this, drawableVec_, dirtySlotShadow);
2881         // Step 4: Generate drawCmdList from drawables
2882         UpdateDisplayList();
2883         UpdateBlurEffectCounter(GetBlurEffectDrawbleCount() - preBlurDrawableCnt);
2884     }
2885     // If any effect drawable become dirty, check all effect drawable and do edr update
2886     auto needUpdateEDR = std::any_of(edrDrawableSlots.begin(), edrDrawableSlots.end(), [&dirtySlots](auto slot) {
2887          return dirtySlots.count(slot);
2888     });
2889     if (needUpdateEDR) {
2890         UpdateDrawableEnableEDR();
2891     }
2892     // Merge dirty slots
2893     if (dirtySlots_.empty()) {
2894         dirtySlots_ = std::move(dirtySlots);
2895     } else {
2896         dirtySlots_.insert(dirtySlots.begin(), dirtySlots.end());
2897     }
2898 
2899     waitSync_ = true;
2900 #endif
2901 }
2902 
UpdateShadowRect()2903 void RSRenderNode::UpdateShadowRect()
2904 {
2905 #ifdef RS_ENABLE_GPU
2906     if (drawableVec_[static_cast<int8_t>(RSDrawableSlot::SHADOW)] != nullptr &&
2907         GetRenderProperties().GetShadowColorStrategy() != SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE) {
2908         RectI shadowRect;
2909         auto rRect = GetRenderProperties().GetRRect();
2910         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &rRect, false, false);
2911         stagingRenderParams_->SetShadowRect(Drawing::Rect(
2912             static_cast<float>(shadowRect.GetLeft()),
2913             static_cast<float>(shadowRect.GetTop()),
2914             static_cast<float>(shadowRect.GetRight()),
2915             static_cast<float>(shadowRect.GetBottom())));
2916         RS_OPTIONAL_TRACE_NAME_FMT("UpdateShadowRect id:%llu shadowRect:%s",
2917             GetId(), shadowRect.ToString().c_str());
2918     } else {
2919         stagingRenderParams_->SetShadowRect(Drawing::Rect());
2920     }
2921 #endif
2922 }
2923 
UpdateDisplayList()2924 void RSRenderNode::UpdateDisplayList()
2925 {
2926 #ifndef ROSEN_ARKUI_X
2927     // Planning: use the mask from DrawableVecStatus in rs_drawable.cpp
2928     constexpr uint8_t FRAME_NOT_EMPTY = 1 << 4;
2929 #ifdef RS_ENABLE_GPU
2930     constexpr uint8_t NODE_NOT_EMPTY = 1 << 5;
2931 #endif
2932     stagingDrawCmdList_.clear();
2933     drawCmdListNeedSync_ = true;
2934 #ifdef RS_ENABLE_GPU
2935     if (UNLIKELY((drawableVecStatus_ & NODE_NOT_EMPTY) == 0)) {
2936         // NODE_NOT_EMPTY is not set, so nothing to draw, just skip
2937         stagingRenderParams_->SetContentEmpty(GetType() == RSRenderNodeType::CANVAS_NODE);
2938         return;
2939     }
2940 #endif
2941 
2942     int8_t index = 0;
2943     // Process all drawables in [index, end], end is included.
2944     // Note: After this loop, index will be end+1
2945     auto AppendDrawFunc = [&](RSDrawableSlot end) -> int8_t {
2946         auto endIndex = static_cast<int8_t>(end);
2947         for (; index <= endIndex; ++index) {
2948             if (const auto& drawable = drawableVec_[index]) {
2949                 stagingDrawCmdList_.emplace_back(drawable->CreateDrawFunc());
2950             }
2951         }
2952         // If the end drawable exist, return its index, otherwise return -1
2953         return drawableVec_[endIndex] != nullptr ? stagingDrawCmdList_.size() - 1 : -1;
2954     };
2955     // Update index of TRANSITION
2956     stagingDrawCmdIndex_.transitionIndex_ = AppendDrawFunc(RSDrawableSlot::TRANSITION);
2957 
2958     // Update index of ENV_FOREGROUND_COLOR
2959     stagingDrawCmdIndex_.envForeGroundColorIndex_ = AppendDrawFunc(RSDrawableSlot::ENV_FOREGROUND_COLOR);
2960 
2961     // Update index of SHADOW
2962     stagingDrawCmdIndex_.shadowIndex_ = AppendDrawFunc(RSDrawableSlot::SHADOW);
2963 
2964     AppendDrawFunc(RSDrawableSlot::OUTLINE);
2965     stagingDrawCmdIndex_.renderGroupBeginIndex_ = stagingDrawCmdList_.size();
2966     stagingDrawCmdIndex_.foregroundFilterBeginIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
2967 
2968     stagingDrawCmdIndex_.bgSaveBoundsIndex_ = AppendDrawFunc(RSDrawableSlot::BG_SAVE_BOUNDS);
2969     // Update index of CLIP_TO_BOUNDS
2970     stagingDrawCmdIndex_.clipToBoundsIndex_ = AppendDrawFunc(RSDrawableSlot::CLIP_TO_BOUNDS);
2971 
2972     // Update index of BACKGROUND_COLOR
2973     stagingDrawCmdIndex_.backgroundColorIndex_ = AppendDrawFunc(RSDrawableSlot::BACKGROUND_COLOR);
2974 
2975     // Update index of BACKGROUND_IMAGE
2976     stagingDrawCmdIndex_.backgroundImageIndex_ = AppendDrawFunc(RSDrawableSlot::BACKGROUND_IMAGE);
2977 
2978     // Update index of BACKGROUND_FILTER
2979     stagingDrawCmdIndex_.backgroundFilterIndex_ = AppendDrawFunc(RSDrawableSlot::BACKGROUND_FILTER);
2980 
2981     // Update index of USE_EFFECT
2982     stagingDrawCmdIndex_.useEffectIndex_ = AppendDrawFunc(RSDrawableSlot::USE_EFFECT);
2983 
2984     // Update index of BACKGROUND_STYLE
2985     stagingDrawCmdIndex_.backgroudStyleIndex_ = AppendDrawFunc(RSDrawableSlot::BACKGROUND_STYLE);
2986 
2987     // Update index of ENV_FOREGROUND_COLOR_STRATEGY
2988     stagingDrawCmdIndex_.envForegroundColorStrategyIndex_ = AppendDrawFunc(
2989         RSDrawableSlot::ENV_FOREGROUND_COLOR_STRATEGY);
2990 
2991     stagingDrawCmdIndex_.bgRestoreBoundsIndex_ = AppendDrawFunc(RSDrawableSlot::BG_RESTORE_BOUNDS);
2992 
2993     if (drawableVecStatus_ & FRAME_NOT_EMPTY) {
2994         // Update index of FRAME_OFFSET
2995         stagingDrawCmdIndex_.frameOffsetIndex_ = AppendDrawFunc(RSDrawableSlot::FRAME_OFFSET);
2996 
2997         // Update index of CLIP_TO_FRAME
2998         stagingDrawCmdIndex_.clipToFrameIndex_ = AppendDrawFunc(RSDrawableSlot::CLIP_TO_FRAME);
2999 
3000         // Update index of CUSTOM_CLIP_TO_FRAME
3001         stagingDrawCmdIndex_.customClipToFrameIndex_ = AppendDrawFunc(RSDrawableSlot::CUSTOM_CLIP_TO_FRAME);
3002 
3003         // Update index of CONTENT_STYLE
3004         stagingDrawCmdIndex_.contentIndex_ = AppendDrawFunc(RSDrawableSlot::CONTENT_STYLE);
3005 
3006         // Update index of BACKGROUND_END
3007         stagingDrawCmdIndex_.backgroundEndIndex_ = stagingDrawCmdIndex_.contentIndex_ == -1
3008             ? static_cast<int8_t>(stagingDrawCmdList_.size()) : stagingDrawCmdIndex_.contentIndex_;
3009 
3010         // Update index of CHILDREN
3011         stagingDrawCmdIndex_.childrenIndex_ = AppendDrawFunc(RSDrawableSlot::CHILDREN);
3012         stagingDrawCmdIndex_.foregroundBeginIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
3013 
3014         AppendDrawFunc(RSDrawableSlot::RESTORE_FRAME);
3015     } else {
3016         // Nothing inside frame, skip useless slots and update indexes
3017         stagingDrawCmdIndex_.contentIndex_ = -1;
3018         stagingDrawCmdIndex_.childrenIndex_ = -1;
3019         stagingDrawCmdIndex_.backgroundEndIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
3020         stagingDrawCmdIndex_.foregroundBeginIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
3021         index = static_cast<int8_t>(RSDrawableSlot::FG_SAVE_BOUNDS);
3022     }
3023     stagingDrawCmdIndex_.renderGroupEndIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
3024 
3025     AppendDrawFunc(RSDrawableSlot::RESTORE_BLENDER);
3026     stagingDrawCmdIndex_.foregroundFilterEndIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
3027     AppendDrawFunc(RSDrawableSlot::RESTORE_ALL);
3028     stagingDrawCmdIndex_.endIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
3029 #ifdef RS_ENABLE_GPU
3030     stagingRenderParams_->SetContentEmpty(false);
3031 #endif
3032 #endif
3033 }
3034 
UpdateEffectRegion(std::optional<Drawing::RectI> & region,bool isForced)3035 void RSRenderNode::UpdateEffectRegion(std::optional<Drawing::RectI>& region, bool isForced)
3036 {
3037     if (!region.has_value()) {
3038         return;
3039     }
3040     const auto& property = GetRenderProperties();
3041     if (!isForced && !property.GetUseEffect()) {
3042         return;
3043     }
3044 
3045     auto absRect = property.GetBoundsGeometry()->GetAbsRect();
3046     region->Join(Drawing::RectI(absRect.GetLeft(), absRect.GetTop(), absRect.GetRight(), absRect.GetBottom()));
3047 }
3048 
FilterModifiersByPid(pid_t pid)3049 void RSRenderNode::FilterModifiersByPid(pid_t pid)
3050 {
3051     for (auto& slot : modifiersNG_) {
3052         auto it = std::find_if(slot.begin(), slot.end(),
3053             [pid](const auto& modifier) -> bool { return ExtractPid(modifier->GetId()) == pid; });
3054         if (it != slot.end()) {
3055             slot.erase(it);
3056         }
3057     }
3058 }
3059 
UpdateShouldPaint()3060 void RSRenderNode::UpdateShouldPaint()
3061 {
3062     // node should be painted if either it is visible or it has disappearing transition animation,
3063     // but only when its alpha is not zero.
3064     // Besides, if one node has sharedTransitionParam, it should be painted no matter what alpha it has.
3065     shouldPaint_ = ((ROSEN_GNE(GetRenderProperties().GetAlpha(), 0.0f)) &&
3066                    (GetRenderProperties().GetVisible() || HasDisappearingTransition(false))) ||
3067                    sharedTransitionParam_;
3068     if (!shouldPaint_ && HasBlurFilter()) { // force clear blur cache
3069         RS_OPTIONAL_TRACE_NAME_FMT("node[%llu] is invisible", GetId());
3070         MarkForceClearFilterCacheWithInvisible();
3071     }
3072 }
3073 
SetSharedTransitionParam(const std::shared_ptr<SharedTransitionParam> & sharedTransitionParam)3074 void RSRenderNode::SetSharedTransitionParam(const std::shared_ptr<SharedTransitionParam>& sharedTransitionParam)
3075 {
3076     if (!sharedTransitionParam_ && !sharedTransitionParam) {
3077         // both are empty, do nothing
3078         return;
3079     }
3080     sharedTransitionParam_ = sharedTransitionParam;
3081     SetDirty();
3082     // tell parent to regenerate children drawable
3083     if (auto parent = parent_.lock()) {
3084         parent->AddDirtyType(ModifierNG::RSModifierType::CHILDREN);
3085         parent->SetDirty();
3086     }
3087 }
3088 
SetGlobalAlpha(float alpha)3089 void RSRenderNode::SetGlobalAlpha(float alpha)
3090 {
3091     if (globalAlpha_ == alpha) {
3092         return;
3093     }
3094     if ((ROSEN_EQ(globalAlpha_, 1.0f) && !ROSEN_EQ(alpha, 1.0f)) ||
3095         (ROSEN_EQ(alpha, 1.0f) && !ROSEN_EQ(globalAlpha_, 1.0f))) {
3096         OnAlphaChanged();
3097     }
3098     globalAlpha_ = alpha;
3099 #ifdef RS_ENABLE_GPU
3100     if (stagingRenderParams_) {
3101         stagingRenderParams_->SetGlobalAlpha(alpha);
3102     }
3103 #endif
3104 }
3105 
SetBootAnimation(bool isBootAnimation)3106 void RSRenderNode::SetBootAnimation(bool isBootAnimation)
3107 {
3108     ROSEN_LOGD("SetBootAnimation:: id:%{public}" PRIu64 "isBootAnimation %{public}d",
3109         GetId(), isBootAnimation);
3110     isBootAnimation_ = isBootAnimation;
3111     if (GetType() == RSRenderNodeType::LOGICAL_DISPLAY_NODE) {
3112         if (auto parent = GetParent().lock()) {
3113             parent->SetBootAnimation(isBootAnimation);
3114         }
3115     } else if (GetType() == RSRenderNodeType::SCREEN_NODE) {
3116         if (!isBootAnimation) {
3117             return;
3118         }
3119         SetContainBootAnimation(true);
3120     }
3121 }
3122 
GetBootAnimation() const3123 bool RSRenderNode::GetBootAnimation() const
3124 {
3125     return isBootAnimation_;
3126 }
3127 
GetGlobalPositionEnabled() const3128 bool RSRenderNode::GetGlobalPositionEnabled() const
3129 {
3130     return false;
3131 }
3132 
NeedInitCacheSurface()3133 bool RSRenderNode::NeedInitCacheSurface()
3134 {
3135     auto cacheType = GetCacheType();
3136     int width = 0;
3137     int height = 0;
3138     if (cacheType == CacheType::ANIMATE_PROPERTY && GetRenderProperties().IsShadowValid() &&
3139         !GetRenderProperties().IsSpherizeValid() && !GetRenderProperties().IsAttractionValid()) {
3140         const RectF boundsRect = GetRenderProperties().GetBoundsRect();
3141         RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
3142         RectI shadowRect;
3143         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &rrect, false);
3144         width = shadowRect.GetWidth();
3145         height = shadowRect.GetHeight();
3146     } else {
3147         Vector2f size = GetOptionalBufferSize();
3148         width =  size.x_;
3149         height = size.y_;
3150     }
3151     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3152     if (cacheSurface_ == nullptr) {
3153         return true;
3154     }
3155     auto cacheCanvas = cacheSurface_->GetCanvas();
3156     if (cacheCanvas == nullptr) {
3157         return true;
3158     }
3159     return cacheCanvas->GetWidth() != width || cacheCanvas->GetHeight() != height;
3160 }
3161 
NeedInitCacheCompletedSurface()3162 bool RSRenderNode::NeedInitCacheCompletedSurface()
3163 {
3164     Vector2f size = GetOptionalBufferSize();
3165     int width = static_cast<int>(size.x_);
3166     int height = static_cast<int>(size.y_);
3167     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3168     if (cacheCompletedSurface_ == nullptr) {
3169         return true;
3170     }
3171     auto cacheCanvas = cacheCompletedSurface_->GetCanvas();
3172     if (cacheCanvas == nullptr) {
3173         return true;
3174     }
3175     return cacheCanvas->GetWidth() != width || cacheCanvas->GetHeight() != height;
3176 }
3177 
InitCacheSurface(Drawing::GPUContext * gpuContext,ClearCacheSurfaceFunc func,uint32_t threadIndex)3178 void RSRenderNode::InitCacheSurface(Drawing::GPUContext* gpuContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
3179 {
3180     RS_TRACE_NAME_FMT("InitCacheSurface");
3181     if (func) {
3182         cacheSurfaceThreadIndex_ = threadIndex;
3183         if (!clearCacheSurfaceFunc_) {
3184             clearCacheSurfaceFunc_ = func;
3185         }
3186         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3187         if (cacheSurface_) {
3188             func(std::move(cacheSurface_), nullptr,
3189                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
3190             cacheSurface_ = nullptr;
3191         }
3192     } else {
3193         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3194         cacheSurface_ = nullptr;
3195     }
3196 #ifdef RS_ENABLE_VK
3197     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3198         OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3199         cacheCleanupHelper_ = nullptr;
3200     }
3201 #endif
3202     auto cacheType = GetCacheType();
3203     float width = 0.0f, height = 0.0f;
3204     Vector2f size = GetOptionalBufferSize();
3205     boundsWidth_ = size.x_;
3206     boundsHeight_ = size.y_;
3207     if (cacheType == CacheType::ANIMATE_PROPERTY && GetRenderProperties().IsShadowValid() &&
3208         !GetRenderProperties().IsSpherizeValid() && !GetRenderProperties().IsAttractionValid()) {
3209         const RectF boundsRect = GetRenderProperties().GetBoundsRect();
3210         RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
3211         RectI shadowRect;
3212         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &rrect, false);
3213         width = shadowRect.GetWidth();
3214         height = shadowRect.GetHeight();
3215         shadowRectOffsetX_ = -shadowRect.GetLeft();
3216         shadowRectOffsetY_ = -shadowRect.GetTop();
3217     } else {
3218         width = std::ceil(boundsWidth_);
3219         height = std::ceil(boundsHeight_);
3220     }
3221 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
3222     if (gpuContext == nullptr) {
3223         if (func) {
3224             std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3225             func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
3226                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
3227             ClearCacheSurface();
3228         }
3229         return;
3230     }
3231 #ifdef RS_ENABLE_GL
3232     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
3233         OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
3234         Drawing::ImageInfo info = Drawing::ImageInfo::MakeN32Premul(width, height);
3235         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3236         cacheSurface_ = Drawing::Surface::MakeRenderTarget(gpuContext, true, info);
3237     }
3238 #endif
3239 #ifdef RS_ENABLE_VK
3240     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3241         OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3242         auto initCacheBackendTexture = NativeBufferUtils::MakeBackendTexture(width, height, ExtractPid(GetId()));
3243         auto vkTextureInfo = initCacheBackendTexture.GetTextureInfo().GetVKTextureInfo();
3244         if (!initCacheBackendTexture.IsValid() || !vkTextureInfo) {
3245             if (func) {
3246                 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3247                 func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
3248                     cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
3249                 ClearCacheSurface();
3250             }
3251             return;
3252         }
3253         auto initCacheCleanupHelper = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
3254             vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory, vkTextureInfo->vkAlloc.statName);
3255         auto initCacheSurface = Drawing::Surface::MakeFromBackendTexture(
3256             gpuContext, initCacheBackendTexture.GetTextureInfo(), Drawing::TextureOrigin::BOTTOM_LEFT,
3257             1, Drawing::ColorType::COLORTYPE_RGBA_8888, nullptr,
3258             NativeBufferUtils::DeleteVkImage, initCacheCleanupHelper);
3259         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3260         cacheBackendTexture_ = initCacheBackendTexture;
3261         cacheCleanupHelper_ = initCacheCleanupHelper;
3262         cacheSurface_ = initCacheSurface;
3263     }
3264 #endif
3265 #else
3266     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3267     cacheSurface_ = Drawing::Surface::MakeRasterN32Premul(width, height);
3268 #endif
3269 }
3270 
IsCacheSurfaceValid() const3271 bool RSRenderNode::IsCacheSurfaceValid() const
3272 {
3273     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3274     return  (cacheSurface_ != nullptr);
3275 }
3276 
IsCacheCompletedSurfaceValid() const3277 bool RSRenderNode::IsCacheCompletedSurfaceValid() const
3278 {
3279     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3280     return  (cacheCompletedSurface_ != nullptr);
3281 }
3282 
GetOptionalBufferSize() const3283 Vector2f RSRenderNode::GetOptionalBufferSize() const
3284 {
3285     if (boundsModifierNG_ != nullptr) {
3286         auto bounds = boundsModifierNG_->Getter<Vector4f>(ModifierNG::RSPropertyType::BOUNDS);
3287         return { bounds.z_, bounds.w_ };
3288     }
3289     if (frameModifierNG_ != nullptr) {
3290         auto frame = frameModifierNG_->Getter<Vector4f>(ModifierNG::RSPropertyType::FRAME);
3291         return { frame.z_, frame.w_ };
3292     }
3293     return { 0.f, 0.f };
3294 }
3295 
GetCompletedImage(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)3296 std::shared_ptr<Drawing::Image> RSRenderNode::GetCompletedImage(
3297     RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
3298 {
3299     if (isUIFirst) {
3300 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3301         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3302         if (!cacheCompletedBackendTexture_.IsValid()) {
3303             RS_LOGE("invalid grBackendTexture_");
3304             return nullptr;
3305         }
3306 #ifdef RS_ENABLE_VK
3307         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3308             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3309             if (!cacheCompletedSurface_ || !cacheCompletedCleanupHelper_) {
3310                 return nullptr;
3311             }
3312         }
3313 #endif
3314         if (canvas.GetGPUContext() == nullptr) {
3315             RS_LOGE("canvas GetGPUContext failed");
3316             return nullptr;
3317         }
3318         auto image = std::make_shared<Drawing::Image>();
3319         Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
3320         Drawing::BitmapFormat info = Drawing::BitmapFormat{ Drawing::COLORTYPE_RGBA_8888,
3321             Drawing::ALPHATYPE_PREMUL };
3322 #ifdef RS_ENABLE_GL
3323         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
3324             OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
3325             image->BuildFromTexture(*canvas.GetGPUContext(), cacheCompletedBackendTexture_.GetTextureInfo(),
3326                 origin, info, nullptr);
3327         }
3328 #endif
3329 
3330 #ifdef RS_ENABLE_VK
3331         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3332             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3333             image->BuildFromTexture(*canvas.GetGPUContext(), cacheCompletedBackendTexture_.GetTextureInfo(),
3334                 origin, info, nullptr,
3335                 NativeBufferUtils::DeleteVkImage, cacheCompletedCleanupHelper_->Ref());
3336         }
3337 #endif
3338         return image;
3339 #endif
3340     }
3341 
3342     if (!cacheCompletedSurface_) {
3343         RS_LOGE("DrawCacheSurface invalid cacheCompletedSurface");
3344         return nullptr;
3345     }
3346     auto completeImage = cacheCompletedSurface_->GetImageSnapshot();
3347     if (!completeImage) {
3348         RS_LOGE("Get complete image failed");
3349         return nullptr;
3350     }
3351     if (threadIndex == completedSurfaceThreadIndex_) {
3352         return completeImage;
3353     }
3354 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3355     Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
3356     auto backendTexture = completeImage->GetBackendTexture(false, &origin);
3357     if (!backendTexture.IsValid()) {
3358         RS_LOGE("get backendTexture failed");
3359         return nullptr;
3360     }
3361     auto cacheImage = std::make_shared<Drawing::Image>();
3362     Drawing::BitmapFormat info =
3363         Drawing::BitmapFormat{ completeImage->GetColorType(), completeImage->GetAlphaType() };
3364     if (canvas.GetGPUContext() == nullptr) {
3365         RS_LOGE("canvas GetGPUContext failed");
3366         return nullptr;
3367     }
3368     bool ret = cacheImage->BuildFromTexture(*canvas.GetGPUContext(), backendTexture.GetTextureInfo(),
3369         origin, info, nullptr);
3370     if (!ret) {
3371         RS_LOGE("RSRenderNode::GetCompletedImage image BuildFromTexture failed");
3372         return nullptr;
3373     }
3374     return cacheImage;
3375 #else
3376     return completeImage;
3377 #endif
3378 }
3379 
3380 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
UpdateBackendTexture()3381 void RSRenderNode::UpdateBackendTexture()
3382 {
3383     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3384     if (cacheSurface_ == nullptr) {
3385         return;
3386     }
3387     cacheBackendTexture_ = cacheSurface_->GetBackendTexture();
3388 }
3389 #endif
3390 
GetCompletedCacheSurface(uint32_t threadIndex,bool needCheckThread,bool releaseAfterGet)3391 std::shared_ptr<Drawing::Surface> RSRenderNode::GetCompletedCacheSurface(uint32_t threadIndex, bool needCheckThread,
3392     bool releaseAfterGet)
3393 {
3394     {
3395         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3396         if (releaseAfterGet) {
3397 #ifdef RS_ENABLE_VK
3398             if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3399                 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3400                 cacheCompletedCleanupHelper_ = nullptr;
3401             }
3402 #endif
3403             return cacheCompletedSurface_;
3404         }
3405         if (!needCheckThread || completedSurfaceThreadIndex_ == threadIndex || !cacheCompletedSurface_) {
3406             return cacheCompletedSurface_;
3407         }
3408     }
3409 
3410     // freeze cache scene
3411     ClearCacheSurfaceInThread();
3412     return nullptr;
3413 }
3414 
ClearCacheSurfaceInThread()3415 void RSRenderNode::ClearCacheSurfaceInThread()
3416 {
3417     if (clearCacheSurfaceFunc_) {
3418         clearCacheSurfaceFunc_(std::move(cacheSurface_), std::move(cacheCompletedSurface_), cacheSurfaceThreadIndex_,
3419             completedSurfaceThreadIndex_);
3420     }
3421     ClearCacheSurface();
3422 }
3423 
GetCacheSurface(uint32_t threadIndex,bool needCheckThread,bool releaseAfterGet)3424 std::shared_ptr<Drawing::Surface> RSRenderNode::GetCacheSurface(uint32_t threadIndex, bool needCheckThread,
3425     bool releaseAfterGet)
3426 {
3427     {
3428         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3429         if (releaseAfterGet) {
3430 #ifdef RS_ENABLE_VK
3431             if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3432                 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3433                 cacheCleanupHelper_ = nullptr;
3434             }
3435 #endif
3436             return std::move(cacheSurface_);
3437         }
3438         if (!needCheckThread || cacheSurfaceThreadIndex_ == threadIndex || !cacheSurface_) {
3439             return cacheSurface_;
3440         }
3441     }
3442 
3443     // freeze cache scene
3444     ClearCacheSurfaceInThread();
3445     return nullptr;
3446 }
3447 
IsForcedDrawInGroup() const3448 bool RSRenderNode::IsForcedDrawInGroup() const
3449 {
3450     return nodeGroupType_ & NodeGroupType::GROUPED_BY_USER;
3451 }
3452 
IsSuggestedDrawInGroup() const3453 bool RSRenderNode::IsSuggestedDrawInGroup() const
3454 {
3455     return nodeGroupType_ != NodeGroupType::NONE;
3456 }
3457 
MarkNodeGroup(NodeGroupType type,bool isNodeGroup,bool includeProperty)3458 void RSRenderNode::MarkNodeGroup(NodeGroupType type, bool isNodeGroup, bool includeProperty)
3459 {
3460     RS_OPTIONAL_TRACE_NAME_FMT("MarkNodeGroup type:%d isNodeGroup:%d id:%llu", type, isNodeGroup, GetId());
3461     RS_LOGI_IF(DEBUG_NODE, "RSRenderNode::MarkNodeGP type:%{public}d isNodeGroup:%{public}d id:%{public}" PRIu64,
3462         type, isNodeGroup, GetId());
3463     if (isNodeGroup && type == NodeGroupType::GROUPED_BY_UI) {
3464         auto context = GetContext().lock();
3465         if (context && context->GetNodeMap().IsResidentProcessNode(GetId())) {
3466             nodeGroupType_ |= type;
3467             SetDirty();
3468 #ifdef RS_ENABLE_GPU
3469             if (stagingRenderParams_) {
3470                 stagingRenderParams_->SetDirtyType(RSRenderParamsDirtyType::DRAWING_CACHE_TYPE_DIRTY);
3471             }
3472 #endif
3473         }
3474     } else {
3475         if (isNodeGroup) {
3476             nodeGroupType_ |= type;
3477         } else {
3478             nodeGroupType_ &= ~type;
3479         }
3480         SetDirty();
3481 #ifdef RS_ENABLE_GPU
3482         if (stagingRenderParams_) {
3483             stagingRenderParams_->SetDirtyType(RSRenderParamsDirtyType::DRAWING_CACHE_TYPE_DIRTY);
3484         }
3485 #endif
3486     }
3487     if (nodeGroupType_ == static_cast<uint8_t>(NodeGroupType::NONE) && !isNodeGroup) {
3488         needClearSurface_ = true;
3489     }
3490     nodeGroupIncludeProperty_ = includeProperty;
3491 #ifdef ROSEN_PREVIEW
3492     if (type == NodeGroupType::GROUPED_BY_USER) {
3493         dirtyTypesNG_.set(static_cast<int>(ModifierNG::RSModifierType::ALPHA), true);
3494         GetMutableRenderProperties().SetAlphaOffscreen(isNodeGroup);
3495     }
3496 #endif
3497     AddToPendingSyncList();
3498 }
3499 
IsNodeGroupIncludeProperty() const3500 bool RSRenderNode::IsNodeGroupIncludeProperty() const
3501 {
3502     return nodeGroupIncludeProperty_;
3503 }
3504 
MarkNodeSingleFrameComposer(bool isNodeSingleFrameComposer,pid_t pid)3505 void RSRenderNode::MarkNodeSingleFrameComposer(bool isNodeSingleFrameComposer, pid_t pid)
3506 {
3507     isNodeSingleFrameComposer_ = isNodeSingleFrameComposer;
3508     appPid_ = pid;
3509 }
3510 
GetNodeIsSingleFrameComposer() const3511 bool RSRenderNode::GetNodeIsSingleFrameComposer() const
3512 {
3513     return isNodeSingleFrameComposer_;
3514 }
3515 
3516 // arkui mark
MarkSuggestOpincNode(bool isOpincNode,bool isNeedCalculate)3517 void RSRenderNode::MarkSuggestOpincNode(bool isOpincNode, bool isNeedCalculate)
3518 {
3519     RS_TRACE_NAME_FMT("mark opinc %llx, isopinc:%d. isCal:%d", GetId(), isOpincNode, isNeedCalculate);
3520     opincCache_.MarkSuggestOpincNode(isOpincNode, isNeedCalculate);
3521     SetDirty();
3522 }
3523 
UpdateOpincParam()3524 void RSRenderNode::UpdateOpincParam()
3525 {
3526     if (stagingRenderParams_) {
3527         stagingRenderParams_->OpincSetCacheChangeFlag(opincCache_.GetCacheChangeFlag(), lastFrameSynced_);
3528         stagingRenderParams_->OpincUpdateRootFlag(opincCache_.OpincGetRootFlag());
3529         stagingRenderParams_->OpincSetIsSuggest(opincCache_.IsSuggestOpincNode());
3530         stagingRenderParams_->OpincUpdateSupportFlag(opincCache_.GetCurNodeTreeSupportFlag());
3531     }
3532 }
3533 
CheckDrawingCacheType()3534 void RSRenderNode::CheckDrawingCacheType()
3535 {
3536     if (nodeGroupType_ == NodeGroupType::NONE) {
3537         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
3538     } else if (nodeGroupType_ & NodeGroupType::GROUPED_BY_FOREGROUND_FILTER) {
3539         SetDrawingCacheType(RSDrawingCacheType::FOREGROUND_FILTER_CACHE);
3540     } else if (nodeGroupType_ & NodeGroupType::GROUPED_BY_USER) {
3541         SetDrawingCacheType(RSDrawingCacheType::FORCED_CACHE);
3542     } else {
3543         SetDrawingCacheType(RSDrawingCacheType::TARGETED_CACHE);
3544     }
3545 }
3546 
3547 #ifdef RS_ENABLE_STACK_CULLING
SetFullSurfaceOpaqueMarks(const std::shared_ptr<RSRenderNode> curSurfaceNodeParam)3548 void RSRenderNode::SetFullSurfaceOpaqueMarks(const std::shared_ptr<RSRenderNode> curSurfaceNodeParam)
3549 {
3550     if (!isFullSurfaceOpaquCanvasNode_) {
3551         int32_t tempValue = coldDownCounter_;
3552         coldDownCounter_ = (coldDownCounter_ + 1) % MAX_COLD_DOWN_NUM;
3553         if (tempValue != 0) {
3554             return;
3555         }
3556     } else {
3557         coldDownCounter_ = 0;
3558     }
3559 
3560     isFullSurfaceOpaquCanvasNode_ = false;
3561     if (!ROSEN_EQ(GetGlobalAlpha(), 1.0f) || HasFilter()) {
3562         return;
3563     }
3564 
3565     if (GetRenderProperties().GetBackgroundColor().GetAlpha() < 255) {
3566         return;
3567     }
3568 
3569     if (!curSurfaceNodeParam) {
3570         return;
3571     }
3572 
3573     auto curSurfaceNode = std::static_pointer_cast<RSSurfaceRenderNode>(curSurfaceNodeParam);
3574     auto surfaceNodeAbsRect = curSurfaceNode->GetOldDirty();
3575     auto absRect = GetFilterRect();
3576     if (surfaceNodeAbsRect.IsInsideOf(absRect)) {
3577         isFullSurfaceOpaquCanvasNode_ = true;
3578 
3579         auto rsParent = GetParent().lock();
3580         while (rsParent) {
3581             //skip whern another child has set its parent or reach rootnode
3582             if (rsParent->hasChildFullSurfaceOpaquCanvasNode_) {
3583                 break;
3584             }
3585 
3586             rsParent->hasChildFullSurfaceOpaquCanvasNode_ = true;
3587             if (rsParent->IsInstanceOf<RSRootRenderNode>()) {
3588                 break;
3589             }
3590 
3591             rsParent = rsParent->GetParent().lock();
3592         }
3593     }
3594 }
3595 
SetSubNodesCovered()3596 void RSRenderNode::SetSubNodesCovered()
3597 {
3598     if (hasChildFullSurfaceOpaquCanvasNode_) {
3599         auto sortedChildren_ = GetSortedChildren();
3600         if (sortedChildren_->size() <= 1) {
3601             return;
3602         }
3603 
3604         bool found = false;
3605         for (auto child = sortedChildren_->rbegin(); child != sortedChildren_->rend(); child++) {
3606             if (!found && ((*child)->isFullSurfaceOpaquCanvasNode_ || (*child)->hasChildFullSurfaceOpaquCanvasNode_)) {
3607                 found = true;
3608                 continue;
3609             }
3610             if (found) {
3611                 (*child)->isCoveredByOtherNode_ = true;
3612             }
3613         }
3614     }
3615 }
ResetSubNodesCovered()3616 void RSRenderNode::ResetSubNodesCovered()
3617 {
3618     hasChildFullSurfaceOpaquCanvasNode_ = false;
3619 }
3620 #endif
3621 
ResetFilterRectsInCache(const std::unordered_set<NodeId> & curRects)3622 void RSRenderNode::ResetFilterRectsInCache(const std::unordered_set<NodeId>& curRects)
3623 {
3624     curCacheFilterRects_ = curRects;
3625 }
3626 
GetFilterRectsInCache(std::unordered_map<NodeId,std::unordered_set<NodeId>> & allRects) const3627 void RSRenderNode::GetFilterRectsInCache(std::unordered_map<NodeId, std::unordered_set<NodeId>>& allRects) const
3628 {
3629     if (!curCacheFilterRects_.empty()) {
3630         allRects.emplace(GetId(), curCacheFilterRects_);
3631     }
3632 }
3633 
IsFilterRectsInCache() const3634 bool RSRenderNode::IsFilterRectsInCache() const
3635 {
3636     return !curCacheFilterRects_.empty();
3637 }
3638 
GetFilterRect() const3639 RectI RSRenderNode::GetFilterRect() const
3640 {
3641     auto& properties = GetRenderProperties();
3642     auto& geoPtr = (properties.GetBoundsGeometry());
3643     if (!geoPtr) {
3644         return {};
3645     }
3646     if (properties.GetClipBounds() != nullptr) {
3647         auto filterRect = properties.GetClipBounds()->GetDrawingPath().GetBounds();
3648         Drawing::Rect absRect;
3649         geoPtr->GetAbsMatrix().MapRect(absRect, filterRect);
3650         return {absRect.GetLeft(), absRect.GetTop(), absRect.GetWidth(), absRect.GetHeight()};
3651     } else {
3652         return geoPtr->GetAbsRect();
3653     }
3654 }
3655 
CalVisibleFilterRect(const std::optional<RectI> & clipRect)3656 void RSRenderNode::CalVisibleFilterRect(const std::optional<RectI>& clipRect)
3657 {
3658     filterRegion_ = GetFilterRect();
3659     if (clipRect.has_value()) {
3660         filterRegion_ = filterRegion_.IntersectRect(*clipRect);
3661     }
3662 }
3663 
UpdateFullScreenFilterCacheRect(RSDirtyRegionManager & dirtyManager,bool isForeground) const3664 void RSRenderNode::UpdateFullScreenFilterCacheRect(
3665     RSDirtyRegionManager& dirtyManager, bool isForeground) const
3666 {
3667 }
3668 
OnTreeStateChanged()3669 void RSRenderNode::OnTreeStateChanged()
3670 {
3671     if (GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) {
3672         ClearNeverOnTree();
3673     }
3674 
3675     auto curBlurDrawableCnt = GetBlurEffectDrawbleCount();
3676     if (!isOnTheTree_) {
3677         UpdateBlurEffectCounter(-curBlurDrawableCnt);
3678         startingWindowFlag_ = false;
3679         if (stagingUECChildren_ && !stagingUECChildren_->empty()) {
3680             for (auto uiExtension : *stagingUECChildren_) {
3681                 uiExtension->RemoveFromTree();
3682             }
3683         }
3684     }
3685     if (isOnTheTree_) {
3686         UpdateBlurEffectCounter(curBlurDrawableCnt);
3687         // Set dirty and force add to active node list, re-generate children list if needed
3688         SetDirty(true);
3689         SetParentSubTreeDirty();
3690         if (stagingUECChildren_ && !stagingUECChildren_->empty()) {
3691             for (auto uiExtension : *stagingUECChildren_) {
3692                 AddChild(uiExtension);
3693             }
3694         }
3695     } else if (sharedTransitionParam_) {
3696         // Mark shared transition unpaired, and mark paired node dirty
3697         sharedTransitionParam_->paired_ = false;
3698         if (auto pairedNode = sharedTransitionParam_->GetPairedNode(id_)) {
3699             pairedNode->SetDirty(true);
3700         }
3701     }
3702     drawableVecNeedClear_ = !isOnTheTree_;
3703     if (!isOnTheTree_ && HasBlurFilter()) { // force clear blur cache
3704         RS_OPTIONAL_TRACE_NAME_FMT("node[%llu] off the tree", GetId());
3705         MarkForceClearFilterCacheWithInvisible();
3706     }
3707     // Clear fullChildrenList_ and RSChildrenDrawable of the parent node; otherwise, it may cause a memory leak.
3708     if (!isOnTheTree_) {
3709         isFullChildrenListValid_ = false;
3710         std::atomic_store_explicit(&fullChildrenList_, EmptyChildrenList, std::memory_order_release);
3711         drawableVec_[static_cast<int8_t>(RSDrawableSlot::CHILDREN)].reset();
3712         stagingDrawCmdList_.clear();
3713         RS_PROFILER_KEEP_DRAW_CMD(drawCmdListNeedSync_); // false only when used for debugging
3714         uifirstNeedSync_ = true;
3715         AddToPendingSyncList();
3716     }
3717     SetParentTreeStateChangeDirty();
3718     auto& properties = GetMutableRenderProperties();
3719     bool useEffect = properties.GetUseEffect();
3720     UseEffectType useEffectType = static_cast<UseEffectType>(properties.GetUseEffectType());
3721     if (useEffect && useEffectType == UseEffectType::BEHIND_WINDOW) {
3722         ProcessBehindWindowOnTreeStateChanged();
3723     }
3724 }
3725 
HasDisappearingTransition(bool recursive) const3726 bool RSRenderNode::HasDisappearingTransition(bool recursive) const
3727 {
3728     if (!isOnTheTree_) {
3729         return false;
3730     }
3731     if (disappearingTransitionCount_ > 0) {
3732         return true;
3733     }
3734     if (recursive == false) {
3735         return false;
3736     }
3737     auto parent = GetParent().lock();
3738     if (parent == nullptr) {
3739         return false;
3740     }
3741     return parent->HasDisappearingTransition(true);
3742 }
3743 
GetChildren() const3744 RSRenderNode::ChildrenListSharedPtr RSRenderNode::GetChildren() const
3745 {
3746     return std::atomic_load_explicit(&fullChildrenList_, std::memory_order_acquire);
3747 }
3748 
GetSortedChildren() const3749 RSRenderNode::ChildrenListSharedPtr RSRenderNode::GetSortedChildren() const
3750 {
3751     return std::atomic_load_explicit(&fullChildrenList_, std::memory_order_acquire);
3752 }
3753 
CollectAllChildren(const std::shared_ptr<RSBaseRenderNode> & node,std::vector<NodeId> & vec)3754 void RSRenderNode::CollectAllChildren(
3755     const std::shared_ptr<RSBaseRenderNode>& node, std::vector<NodeId>& vec)
3756 {
3757     if (!node) {
3758         ROSEN_LOGD("RSRenderNode::CollectAllChildren node is nullptr");
3759         return;
3760     }
3761     vec.push_back(node->GetId());
3762     for (auto& child : *node->GetSortedChildren()) {
3763         child->CollectAllChildren(child, vec);
3764     }
3765 }
3766 
GenerateFullChildrenList()3767 void RSRenderNode::GenerateFullChildrenList()
3768 {
3769     // both children_ and disappearingChildren_ are empty, no need to generate fullChildrenList_
3770     if (children_.empty() && disappearingChildren_.empty()) {
3771         auto prevFullChildrenList = fullChildrenList_;
3772         isFullChildrenListValid_ = true;
3773         isChildrenSorted_ = true;
3774         std::atomic_store_explicit(&fullChildrenList_, EmptyChildrenList, std::memory_order_release);
3775         return;
3776     }
3777 
3778     // Step 0: Initialize
3779     auto fullChildrenList = std::make_shared<std::vector<std::shared_ptr<RSRenderNode>>>();
3780 
3781     // Step 1: Copy all children into sortedChildren while checking and removing expired children.
3782     children_.remove_if([&](const auto& child) -> bool {
3783         auto existingChild = child.lock();
3784         if (existingChild == nullptr) {
3785             ROSEN_LOGI("RSRenderNode::GenerateSortedChildren removing expired child, this is rare but possible.");
3786             return true;
3787         }
3788         if (isContainBootAnimation_ && !existingChild->GetBootAnimation()) {
3789             ROSEN_LOGD("RSRenderNode::GenerateSortedChildren %{public}" PRIu64 " skip"
3790             " move not bootAnimation displaynode"
3791             "child(id %{public}" PRIu64 ")"" into children_", GetId(), existingChild->GetId());
3792             return false;
3793         }
3794         fullChildrenList->emplace_back(std::move(existingChild));
3795         return false;
3796     });
3797 
3798     // Step 2: Insert disappearing children into sortedChildren at their original position.
3799     // Note:
3800     //     1. We don't need to check if the disappearing transition is finished; it's already handled in
3801     //     RSRenderTransition::OnDetach.
3802     //     2. We don't need to check if the disappearing child is expired; it's already been checked when moving from
3803     //     children_ to disappearingChildren_. We hold ownership of the shared_ptr of the child after that.
3804     std::for_each(disappearingChildren_.begin(), disappearingChildren_.end(), [&](const auto& pair) -> void {
3805         auto& disappearingChild = pair.first;
3806         if (isContainBootAnimation_ && !disappearingChild->GetBootAnimation()) {
3807             ROSEN_LOGD("RSRenderNode::GenerateSortedChildren %{public}" PRIu64 " skip"
3808             " move not bootAnimation displaynode"
3809             "child(id %{public}" PRIu64 ")"" into disappearingChild", GetId(), disappearingChild->GetId());
3810             return;
3811         }
3812         fullChildrenList->emplace_back(disappearingChild);
3813     });
3814 
3815     // temporary fix for wrong z-order
3816     for (auto& child : *fullChildrenList) {
3817         child->ApplyPositionZModifier();
3818     }
3819 
3820     // Step 3: Sort all children by z-order
3821     std::stable_sort(
3822         fullChildrenList->begin(), fullChildrenList->end(), [](const auto& first, const auto& second) -> bool {
3823         return first->GetRenderProperties().GetPositionZ() < second->GetRenderProperties().GetPositionZ();
3824     });
3825 
3826     // Keep a reference to fullChildrenList_ to prevent its deletion when swapping it
3827     auto prevFullChildrenList = fullChildrenList_;
3828 
3829     // Update the flag to indicate that children are now valid and sorted
3830     isFullChildrenListValid_ = true;
3831     isChildrenSorted_ = true;
3832 
3833     // Move the fullChildrenList to fullChildrenList_ atomically
3834     ChildrenListSharedPtr constFullChildrenList = std::move(fullChildrenList);
3835     std::atomic_store_explicit(&fullChildrenList_, constFullChildrenList, std::memory_order_release);
3836 }
3837 
ResortChildren()3838 void RSRenderNode::ResortChildren()
3839 {
3840     // Make a copy of the fullChildrenList for sorting
3841     auto fullChildrenList = std::make_shared<std::vector<std::shared_ptr<RSRenderNode>>>(*fullChildrenList_);
3842 
3843     // temporary fix for wrong z-order
3844     for (auto& child : *fullChildrenList) {
3845         child->ApplyPositionZModifier();
3846     }
3847 
3848     // Sort the children by their z-order
3849     std::stable_sort(
3850         fullChildrenList->begin(), fullChildrenList->end(), [](const auto& first, const auto& second) -> bool {
3851         return first->GetRenderProperties().GetPositionZ() < second->GetRenderProperties().GetPositionZ();
3852     });
3853 
3854     // Keep a reference to fullChildrenList_ to prevent its deletion when swapping it
3855     auto prevFullChildrenList = fullChildrenList_;
3856 
3857     // Update the flag to indicate that children are now sorted
3858     isChildrenSorted_ = true;
3859 
3860     // Move the fullChildrenList to fullChildrenList_ atomically
3861     ChildrenListSharedPtr constFullChildrenList = std::move(fullChildrenList);
3862     std::atomic_store_explicit(&fullChildrenList_, constFullChildrenList, std::memory_order_release);
3863 }
3864 
GetChildrenList() const3865 std::list<RSRenderNode::WeakPtr> RSRenderNode::GetChildrenList() const
3866 {
3867     return children_;
3868 }
3869 
GetHDRBrightness() const3870 float RSRenderNode::GetHDRBrightness() const
3871 {
3872     if (modifiersNG_[static_cast<uint16_t>(ModifierNG::RSModifierType::HDR_BRIGHTNESS)].empty()) {
3873         return 1.0f; // 1.0f make sure HDR video is still HDR state if RSNode::SetHDRBrightness not called
3874     }
3875     auto modifier = modifiersNG_[static_cast<uint16_t>(ModifierNG::RSModifierType::HDR_BRIGHTNESS)].back();
3876     return modifier->Getter<float>(ModifierNG::RSPropertyType::HDR_BRIGHTNESS, 1.f); // 1.f defaule value
3877 }
3878 
HasChildrenOutOfRect() const3879 bool RSRenderNode::HasChildrenOutOfRect() const
3880 {
3881     if (GetRenderProperties().GetClipToBounds() || GetRenderProperties().GetClipToFrame()) {
3882         return false;
3883     }
3884     return hasChildrenOutOfRect_;
3885 }
UpdateChildrenOutOfRectFlag(bool flag)3886 void RSRenderNode::UpdateChildrenOutOfRectFlag(bool flag)
3887 {
3888     hasChildrenOutOfRect_ = flag;
3889 }
GetRemovedChildrenRect() const3890 RectI RSRenderNode::GetRemovedChildrenRect() const
3891 {
3892     return removedChildrenRect_;
3893 }
HasHpaeBackgroundFilter() const3894 bool RSRenderNode::HasHpaeBackgroundFilter() const
3895 {
3896     auto drawable = drawableVec_[static_cast<uint32_t>(RSDrawableSlot::BACKGROUND_FILTER)];
3897     return drawable != nullptr;
3898 }
SetChildHasVisibleFilter(bool val)3899 void RSRenderNode::SetChildHasVisibleFilter(bool val)
3900 {
3901     childHasVisibleFilter_ = val;
3902 #ifdef RS_ENABLE_GPU
3903     stagingRenderParams_->SetChildHasVisibleFilter(val);
3904 #endif
3905 }
SetChildHasVisibleEffect(bool val)3906 void RSRenderNode::SetChildHasVisibleEffect(bool val)
3907 {
3908     childHasVisibleEffect_ = val;
3909 #ifdef RS_ENABLE_GPU
3910     stagingRenderParams_->SetChildHasVisibleEffect(val);
3911 #endif
3912 }
UpdateVisibleFilterChild(RSRenderNode & childNode)3913 void RSRenderNode::UpdateVisibleFilterChild(RSRenderNode& childNode)
3914 {
3915     if (childNode.GetRenderProperties().NeedFilter() || childNode.GetHwcRecorder().IsBlendWithBackground() ||
3916         childNode.GetHwcRecorder().IsForegroundColorValid()) {
3917         visibleFilterChild_.emplace_back(childNode.GetId());
3918     }
3919     auto& childFilterNodes = childNode.GetVisibleFilterChild();
3920     visibleFilterChild_.insert(visibleFilterChild_.end(),
3921         childFilterNodes.begin(), childFilterNodes.end());
3922 }
UpdateVisibleEffectChild(RSRenderNode & childNode)3923 void RSRenderNode::UpdateVisibleEffectChild(RSRenderNode& childNode)
3924 {
3925     if (childNode.GetRenderProperties().GetUseEffect()) {
3926         visibleEffectChild_.emplace(childNode.GetId());
3927     }
3928     auto& childEffectNodes = childNode.GetVisibleEffectChild();
3929     visibleEffectChild_.insert(childEffectNodes.begin(), childEffectNodes.end());
3930 }
3931 
GetInstanceRootNode() const3932 const std::shared_ptr<RSRenderNode> RSRenderNode::GetInstanceRootNode() const
3933 {
3934     auto context = GetContext().lock();
3935     if (!context) {
3936         ROSEN_LOGD("RSRenderNode::GetInstanceRootNode: Invalid context");
3937         return nullptr;
3938     }
3939     return context->GetNodeMap().GetRenderNode(instanceRootNodeId_);
3940 }
3941 
UpdateTreeUifirstRootNodeId(NodeId id)3942 void RSRenderNode::UpdateTreeUifirstRootNodeId(NodeId id)
3943 {
3944 #ifdef RS_ENABLE_GPU
3945     uifirstRootNodeId_ = id;
3946     if (stagingRenderParams_ && stagingRenderParams_->SetUiFirstRootNode(uifirstRootNodeId_)) {
3947         AddToPendingSyncList();
3948     }
3949     for (auto& child : *GetChildren()) {
3950         if (child) {
3951             child->UpdateTreeUifirstRootNodeId(id);
3952         }
3953     }
3954 #endif
3955 }
3956 
GetFirstLevelNode() const3957 const std::shared_ptr<RSRenderNode> RSRenderNode::GetFirstLevelNode() const
3958 {
3959     auto context = GetContext().lock();
3960     if (!context) {
3961         ROSEN_LOGE("RSRenderNode::GetFirstLevelNode: Invalid context");
3962         return nullptr;
3963     }
3964     return context->GetNodeMap().GetRenderNode(firstLevelNodeId_);
3965 }
3966 
GetUifirstRootNode() const3967 const std::shared_ptr<RSRenderNode> RSRenderNode::GetUifirstRootNode() const
3968 {
3969     auto context = GetContext().lock();
3970     if (!context) {
3971         ROSEN_LOGE("RSRenderNode::GetUifirstRootNode: Invalid context");
3972         return nullptr;
3973     }
3974     return context->GetNodeMap().GetRenderNode(uifirstRootNodeId_);
3975 }
3976 
ResetDirtyStatus()3977 void RSRenderNode::ResetDirtyStatus()
3978 {
3979     RecordCurDirtyStatus();
3980     SetClean();
3981     auto& properties = GetMutableRenderProperties();
3982     properties.ResetDirty();
3983     isLastVisible_ = shouldPaint_;
3984     // The return of GetBoundsGeometry function must not be nullptr
3985     oldMatrix_ = properties.GetBoundsGeometry()->GetMatrix();
3986     cmdlistDrawRegion_.Clear();
3987 }
3988 
GenerateId()3989 NodeId RSRenderNode::GenerateId()
3990 {
3991     static pid_t pid_ = GetRealPid();
3992     static std::atomic<uint32_t> currentId_ = 0; // surfaceNode is seted correctly during boot when currentId is 1
3993 
3994     auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
3995     if (currentId == UINT32_MAX) {
3996         // [PLANNING]:process the overflow situations
3997         ROSEN_LOGE("Node Id overflow");
3998     }
3999 
4000     // concat two 32-bit numbers to one 64-bit number
4001     return ((NodeId)pid_ << 32) | currentId;
4002 }
4003 
IsRenderUpdateIgnored() const4004 bool RSRenderNode::IsRenderUpdateIgnored() const
4005 {
4006     return isRenderUpdateIgnored_;
4007 }
GetAnimationManager()4008 RSAnimationManager& RSRenderNode::GetAnimationManager()
4009 {
4010     return animationManager_;
4011 }
GetOldDirty() const4012 RectI RSRenderNode::GetOldDirty() const
4013 {
4014     return oldDirty_;
4015 }
4016 
IsForegroundFilterEnable()4017 bool RSRenderNode::IsForegroundFilterEnable()
4018 {
4019     return drawableVec_[static_cast<uint32_t>(RSDrawableSlot::FOREGROUND_FILTER)] != nullptr;
4020 }
4021 
SetStaticCached(bool isStaticCached)4022 void RSRenderNode::SetStaticCached(bool isStaticCached)
4023 {
4024     isStaticCached_ = isStaticCached;
4025     // ensure defrost subtree would be updated
4026 #ifdef RS_ENABLE_GPU
4027     stagingRenderParams_->SetRSFreezeFlag(isStaticCached);
4028 #else
4029     isStaticCached = false;
4030 #endif
4031     if (!isStaticCached_) {
4032         SetContentDirty();
4033     }
4034 }
IsStaticCached() const4035 bool RSRenderNode::IsStaticCached() const
4036 {
4037     return isStaticCached_;
4038 }
SetNodeName(const std::string & nodeName)4039 void RSRenderNode::SetNodeName(const std::string& nodeName)
4040 {
4041     nodeName_ = nodeName;
4042     auto context = GetContext().lock();
4043     if (!context || nodeName.empty()) {
4044         return;
4045     }
4046     // For LTPO: Record nodes that match the interested UI framework.
4047     auto& uiFrameworkTypeTable = context->GetUiFrameworkTypeTable();
4048     for (auto uiFwkType : uiFrameworkTypeTable) {
4049         if (nodeName.rfind(uiFwkType, 0) == 0) {
4050             context->UpdateUIFrameworkDirtyNodes(weak_from_this());
4051         }
4052     }
4053 }
GetNodeName() const4054 const std::string& RSRenderNode::GetNodeName() const
4055 {
4056     return nodeName_;
4057 }
UpdateCompletedCacheSurface()4058 void RSRenderNode::UpdateCompletedCacheSurface()
4059 {
4060     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
4061     std::swap(cacheSurface_, cacheCompletedSurface_);
4062     std::swap(cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
4063 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
4064     std::swap(cacheBackendTexture_, cacheCompletedBackendTexture_);
4065 #ifdef RS_ENABLE_VK
4066     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
4067         OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
4068         std::swap(cacheCleanupHelper_, cacheCompletedCleanupHelper_);
4069     }
4070 #endif
4071     SetTextureValidFlag(true);
4072 #endif
4073 }
SetTextureValidFlag(bool isValid)4074 void RSRenderNode::SetTextureValidFlag(bool isValid)
4075 {
4076 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
4077     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
4078     isTextureValid_ = isValid;
4079 #endif
4080 }
ClearCacheSurface(bool isClearCompletedCacheSurface)4081 void RSRenderNode::ClearCacheSurface(bool isClearCompletedCacheSurface)
4082 {
4083     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
4084     cacheSurface_ = nullptr;
4085 #ifdef RS_ENABLE_VK
4086     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
4087         OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
4088         cacheCleanupHelper_ = nullptr;
4089     }
4090 #endif
4091     if (isClearCompletedCacheSurface) {
4092         cacheCompletedSurface_ = nullptr;
4093 #ifdef RS_ENABLE_VK
4094         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
4095             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
4096             cacheCompletedCleanupHelper_ = nullptr;
4097         }
4098 #endif
4099 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
4100         isTextureValid_ = false;
4101 #endif
4102     }
4103 }
SetCacheType(CacheType cacheType)4104 void RSRenderNode::SetCacheType(CacheType cacheType)
4105 {
4106     cacheType_ = cacheType;
4107 }
GetShadowRectOffsetX() const4108 int RSRenderNode::GetShadowRectOffsetX() const
4109 {
4110     return shadowRectOffsetX_;
4111 }
GetShadowRectOffsetY() const4112 int RSRenderNode::GetShadowRectOffsetY() const
4113 {
4114     return shadowRectOffsetY_;
4115 }
SetDrawingCacheType(RSDrawingCacheType cacheType)4116 void RSRenderNode::SetDrawingCacheType(RSDrawingCacheType cacheType)
4117 {
4118     drawingCacheType_ = cacheType;
4119 }
SetDrawingCacheChanged(bool cacheChanged)4120 void RSRenderNode::SetDrawingCacheChanged(bool cacheChanged)
4121 {
4122 #ifdef RS_ENABLE_GPU
4123     stagingRenderParams_->SetDrawingCacheChanged(cacheChanged, lastFrameSynced_);
4124 #endif
4125 }
GetDrawingCacheChanged() const4126 bool RSRenderNode::GetDrawingCacheChanged() const
4127 {
4128 #ifdef RS_ENABLE_GPU
4129     return stagingRenderParams_->GetDrawingCacheChanged();
4130 #else
4131     return false;
4132 #endif
4133 }
ResetDrawingCacheNeedUpdate()4134 void RSRenderNode::ResetDrawingCacheNeedUpdate()
4135 {
4136     drawingCacheNeedUpdate_ = false;
4137 }
SetGeoUpdateDelay(bool val)4138 void RSRenderNode::SetGeoUpdateDelay(bool val)
4139 {
4140     geoUpdateDelay_ = geoUpdateDelay_ || val;
4141 }
ResetGeoUpdateDelay()4142 void RSRenderNode::ResetGeoUpdateDelay()
4143 {
4144     geoUpdateDelay_ = false;
4145 }
GetGeoUpdateDelay() const4146 bool RSRenderNode::GetGeoUpdateDelay() const
4147 {
4148     return geoUpdateDelay_;
4149 }
4150 
SetVisitedCacheRootIds(const std::unordered_set<NodeId> & visitedNodes)4151 void RSRenderNode::SetVisitedCacheRootIds(const std::unordered_set<NodeId>& visitedNodes)
4152 {
4153     visitedCacheRoots_ = visitedNodes;
4154 }
GetVisitedCacheRootIds() const4155 const std::unordered_set<NodeId>& RSRenderNode::GetVisitedCacheRootIds() const
4156 {
4157     return visitedCacheRoots_;
4158 }
AddSubSurfaceUpdateInfo(SharedPtr curParent,SharedPtr preParent)4159 void RSRenderNode::AddSubSurfaceUpdateInfo(SharedPtr curParent, SharedPtr preParent)
4160 {
4161     if (!selfAddForSubSurfaceCnt_ && GetType() == RSRenderNodeType::SURFACE_NODE) {
4162         auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
4163         subSurfaceCnt_ = (surfaceNode && (surfaceNode->IsLeashWindow() || surfaceNode->IsAppWindow())) ?
4164             subSurfaceCnt_ + 1 : subSurfaceCnt_;
4165         selfAddForSubSurfaceCnt_ = true;
4166     }
4167     if (subSurfaceCnt_ == 0) {
4168         return;
4169     }
4170     if (auto context = context_.lock()) {
4171         context->AddSubSurfaceCntUpdateInfo({subSurfaceCnt_,
4172             preParent == nullptr ? INVALID_NODEID : preParent->GetId(),
4173             curParent == nullptr ? INVALID_NODEID : curParent->GetId()});
4174     }
4175 }
UpdateSubSurfaceCnt(int updateCnt)4176 void RSRenderNode::UpdateSubSurfaceCnt(int updateCnt)
4177 {
4178     // avoid loop
4179     if (visitedForSubSurfaceCnt_) {
4180         RS_LOGE("RSRenderNode::UpdateSubSurfaceCnt: %{public}" PRIu64" has loop tree", GetId());
4181         return;
4182     }
4183     visitedForSubSurfaceCnt_ = true;
4184     if (updateCnt == 0) {
4185         visitedForSubSurfaceCnt_ = false;
4186         return;
4187     }
4188     int cnt = subSurfaceCnt_ + updateCnt;
4189     subSurfaceCnt_ = cnt < 0 ? 0 : cnt;
4190     if (auto parent = GetParent().lock()) {
4191         parent->UpdateSubSurfaceCnt(updateCnt);
4192     }
4193     visitedForSubSurfaceCnt_ = false;
4194 }
HasSubSurface() const4195 bool RSRenderNode::HasSubSurface() const
4196 {
4197     return subSurfaceCnt_ > 0;
4198 }
SetDrawingCacheRootId(NodeId id)4199 void RSRenderNode::SetDrawingCacheRootId(NodeId id)
4200 {
4201     drawingCacheRootId_ = id;
4202 }
GetDrawingCacheRootId() const4203 NodeId RSRenderNode::GetDrawingCacheRootId() const
4204 {
4205     return drawingCacheRootId_;
4206 }
HasAnimation() const4207 bool RSRenderNode::HasAnimation() const
4208 {
4209     return !animationManager_.animations_.empty();
4210 }
SetHasFilter(bool hasFilter)4211 void RSRenderNode::SetHasFilter(bool hasFilter)
4212 {
4213     hasFilter_ = hasFilter;
4214 }
GetSurfaceMutex() const4215 std::recursive_mutex& RSRenderNode::GetSurfaceMutex() const
4216 {
4217     return surfaceMutex_;
4218 }
4219 
SetHasAbilityComponent(bool hasAbilityComponent)4220 void RSRenderNode::SetHasAbilityComponent(bool hasAbilityComponent)
4221 {
4222     hasAbilityComponent_ = hasAbilityComponent;
4223 }
GetCacheSurfaceThreadIndex() const4224 uint32_t RSRenderNode::GetCacheSurfaceThreadIndex() const
4225 {
4226     return cacheSurfaceThreadIndex_;
4227 }
GetCompletedSurfaceThreadIndex() const4228 uint32_t RSRenderNode::GetCompletedSurfaceThreadIndex() const
4229 {
4230     return completedSurfaceThreadIndex_;
4231 }
4232 
IsMainThreadNode() const4233 bool RSRenderNode::IsMainThreadNode() const
4234 {
4235     return isMainThreadNode_;
4236 }
SetIsMainThreadNode(bool isMainThreadNode)4237 void RSRenderNode::SetIsMainThreadNode(bool isMainThreadNode)
4238 {
4239     isMainThreadNode_ = isMainThreadNode;
4240 }
IsScaleInPreFrame() const4241 bool RSRenderNode::IsScaleInPreFrame() const
4242 {
4243     return isScaleInPreFrame_;
4244 }
SetPriority(NodePriorityType priority)4245 void RSRenderNode::SetPriority(NodePriorityType priority)
4246 {
4247     priority_ = priority;
4248 }
GetPriority()4249 NodePriorityType RSRenderNode::GetPriority()
4250 {
4251     return priority_;
4252 }
IsAncestorDirty() const4253 bool RSRenderNode::IsAncestorDirty() const
4254 {
4255     return isAncestorDirty_;
4256 }
SetIsAncestorDirty(bool isAncestorDirty)4257 void RSRenderNode::SetIsAncestorDirty(bool isAncestorDirty)
4258 {
4259     isAncestorDirty_ = isAncestorDirty;
4260 }
IsParentLeashWindow() const4261 bool RSRenderNode::IsParentLeashWindow() const
4262 {
4263     return isParentLeashWindow_;
4264 }
SetParentLeashWindow()4265 void RSRenderNode::SetParentLeashWindow()
4266 {
4267     isParentLeashWindow_ = true;
4268 }
IsParentScbScreen() const4269 bool RSRenderNode::IsParentScbScreen() const
4270 {
4271     return isParentScbScreen_;
4272 }
SetParentScbScreen()4273 void RSRenderNode::SetParentScbScreen()
4274 {
4275     isParentScbScreen_ = true;
4276 }
HasCachedTexture() const4277 bool RSRenderNode::HasCachedTexture() const
4278 {
4279 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
4280     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
4281     return isTextureValid_;
4282 #else
4283     return true;
4284 #endif
4285 }
SetDrawRegion(const std::shared_ptr<RectF> & rect)4286 void RSRenderNode::SetDrawRegion(const std::shared_ptr<RectF>& rect)
4287 {
4288     if (rect && (rect->GetHeight() >= std::numeric_limits<uint16_t>::max() ||
4289         rect->GetWidth() >= std::numeric_limits<uint16_t>::max())) {
4290         RS_LOGW("node %{public}" PRIu64" set large draw region from arkui: %{public}s",
4291             GetId(), rect->ToString().c_str());
4292         RS_OPTIONAL_TRACE_NAME_FMT("node %" PRIu64" set large draw region from arkui: %s",
4293             GetId(), rect->ToString().c_str());
4294     }
4295     drawRegion_ = rect;
4296     GetMutableRenderProperties().SetDrawRegion(rect);
4297 }
GetDrawRegion() const4298 const std::shared_ptr<RectF>& RSRenderNode::GetDrawRegion() const
4299 {
4300     return drawRegion_;
4301 }
SetOutOfParent(OutOfParentType outOfParent)4302 void RSRenderNode::SetOutOfParent(OutOfParentType outOfParent)
4303 {
4304     outOfParent_ = outOfParent;
4305 }
GetOutOfParent() const4306 OutOfParentType RSRenderNode::GetOutOfParent() const
4307 {
4308     return outOfParent_;
4309 }
GetNodeGroupType() const4310 RSRenderNode::NodeGroupType RSRenderNode::GetNodeGroupType() const
4311 {
4312     uint8_t type = NodeGroupType::GROUP_TYPE_BUTT;
4313     while (type != NodeGroupType::NONE) {
4314         if (nodeGroupType_ & type) {
4315             return static_cast<NodeGroupType>(type);
4316         } else {
4317             type = type >> 1;
4318         }
4319     }
4320     return NodeGroupType::NONE;
4321 }
4322 
UpdateVirtualScreenWhiteListInfo()4323 void RSRenderNode::UpdateVirtualScreenWhiteListInfo()
4324 {
4325     if (IsInstanceOf<RSSurfaceRenderNode>()) {
4326         return;
4327     }
4328     auto nodeParent = GetParent().lock();
4329     if (nodeParent == nullptr) {
4330         return;
4331     }
4332     for (const auto& [screenId, ret] : hasVirtualScreenWhiteList_) {
4333         nodeParent->SetHasWhiteListNode(screenId, ret);
4334     }
4335 }
4336 
MarkNonGeometryChanged()4337 void RSRenderNode::MarkNonGeometryChanged()
4338 {
4339     geometryChangeNotPerceived_ = true;
4340 }
4341 
GetIsUsedBySubThread() const4342 bool RSRenderNode::GetIsUsedBySubThread() const
4343 {
4344     return isUsedBySubThread_.load();
4345 }
SetIsUsedBySubThread(bool isUsedBySubThread)4346 void RSRenderNode::SetIsUsedBySubThread(bool isUsedBySubThread)
4347 {
4348     isUsedBySubThread_.store(isUsedBySubThread);
4349 }
4350 
GetLastIsNeedAssignToSubThread() const4351 bool RSRenderNode::GetLastIsNeedAssignToSubThread() const
4352 {
4353     return lastIsNeedAssignToSubThread_;
4354 }
SetLastIsNeedAssignToSubThread(bool lastIsNeedAssignToSubThread)4355 void RSRenderNode::SetLastIsNeedAssignToSubThread(bool lastIsNeedAssignToSubThread)
4356 {
4357     lastIsNeedAssignToSubThread_ = lastIsNeedAssignToSubThread;
4358 }
4359 
InitRenderParams()4360 void RSRenderNode::InitRenderParams()
4361 {
4362 #ifdef RS_ENABLE_GPU
4363     stagingRenderParams_ = std::make_unique<RSRenderParams>(GetId());
4364     DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(shared_from_this());
4365     if (renderDrawable_ == nullptr) {
4366 #ifndef ROSEN_ARKUI_X
4367         RS_LOGE("RSRenderNode::InitRenderParams failed");
4368 #endif
4369         return;
4370     }
4371 #endif
4372 }
4373 
UpdateRenderParams()4374 void RSRenderNode::UpdateRenderParams()
4375 {
4376 #ifdef RS_ENABLE_GPU
4377     auto& boundGeo = GetRenderProperties().GetBoundsGeometry();
4378     if (!boundGeo) {
4379         return;
4380     }
4381     bool hasSandbox = sharedTransitionParam_ && GetRenderProperties().GetSandBox();
4382     stagingRenderParams_->SetHasSandBox(hasSandbox);
4383     stagingRenderParams_->SetMatrix(boundGeo->GetMatrix());
4384 #ifdef RS_ENABLE_PREFETCH
4385     __builtin_prefetch(&boundsModifierNG_, 0, 1);
4386 #endif
4387     stagingRenderParams_->SetFrameGravity(GetRenderProperties().GetFrameGravity());
4388     stagingRenderParams_->SetBoundsRect({ 0, 0, boundGeo->GetWidth(), boundGeo->GetHeight() });
4389     stagingRenderParams_->SetFrameRect({ 0, 0, GetRenderProperties().GetFrameWidth(),
4390         GetRenderProperties().GetFrameHeight() });
4391     stagingRenderParams_->SetShouldPaint(shouldPaint_);
4392     stagingRenderParams_->SetCacheSize(GetOptionalBufferSize());
4393     stagingRenderParams_->SetAlphaOffScreen(GetRenderProperties().GetAlphaOffscreen());
4394     stagingRenderParams_->SetForegroundFilterCache(GetRenderProperties().GetForegroundFilterCache());
4395     stagingRenderParams_->SetNeedFilter(GetRenderProperties().NeedFilter());
4396     stagingRenderParams_->SetHDRBrightness(GetHDRBrightness() *
4397         GetRenderProperties().GetCanvasNodeHDRBrightnessFactor());
4398     stagingRenderParams_->SetHasBlurFilter(HasBlurFilter());
4399     stagingRenderParams_->SetNodeType(GetType());
4400     stagingRenderParams_->SetEffectNodeShouldPaint(EffectNodeShouldPaint());
4401     stagingRenderParams_->SetHasGlobalCorner(!globalCornerRadius_.IsZero());
4402     stagingRenderParams_->SetFirstLevelCrossNode(isFirstLevelCrossNode_);
4403     stagingRenderParams_->SetAbsRotation(absRotation_);
4404     stagingRenderParams_->SetVirtualScreenWhiteListInfo(hasVirtualScreenWhiteList_);
4405     auto cloneSourceNode = GetSourceCrossNode().lock();
4406     if (cloneSourceNode) {
4407         stagingRenderParams_->SetCloneSourceDrawable(cloneSourceNode->GetRenderDrawable());
4408     }
4409     stagingRenderParams_->MarkRepaintBoundary(isRepaintBoundary_);
4410 #endif
4411 }
4412 
UpdateSubTreeInfo(const RectI & clipRect)4413 void RSRenderNode::UpdateSubTreeInfo(const RectI& clipRect)
4414 {
4415     auto& geoPtr = GetRenderProperties().GetBoundsGeometry();
4416     if (geoPtr == nullptr) {
4417         return;
4418     }
4419     lastFrameHasChildrenOutOfRect_ = HasChildrenOutOfRect();
4420     oldChildrenRect_ = childrenRect_;
4421     oldClipRect_ = clipRect;
4422     oldAbsMatrix_ = geoPtr->GetAbsMatrix();
4423 }
4424 
SetCrossNodeOffScreenStatus(CrossNodeOffScreenRenderDebugType isCrossNodeOffscreenOn_)4425 void RSRenderNode::SetCrossNodeOffScreenStatus(CrossNodeOffScreenRenderDebugType isCrossNodeOffscreenOn_)
4426 {
4427     stagingRenderParams_->SetCrossNodeOffScreenStatus(isCrossNodeOffscreenOn_);
4428 }
4429 
UpdateLocalDrawRect()4430 bool RSRenderNode::UpdateLocalDrawRect()
4431 {
4432 #ifdef RS_ENABLE_GPU
4433     auto drawRect = selfDrawRect_.JoinRect(childrenRect_.ConvertTo<float>());
4434     return stagingRenderParams_->SetLocalDrawRect(drawRect);
4435 #else
4436     return false;
4437 #endif
4438 }
4439 
UpdateAbsDrawRect()4440 void RSRenderNode::UpdateAbsDrawRect()
4441 {
4442     auto absRect = GetAbsDrawRect();
4443     stagingRenderParams_->SetAbsDrawRect(absRect);
4444 }
4445 
UpdateCurCornerRadius(Vector4f & curCornerRadius)4446 void RSRenderNode::UpdateCurCornerRadius(Vector4f& curCornerRadius)
4447 {
4448     Vector4f::Max(GetRenderProperties().GetCornerRadius(), curCornerRadius, curCornerRadius);
4449     globalCornerRadius_ = curCornerRadius;
4450 }
4451 
ResetChangeState()4452 void RSRenderNode::ResetChangeState()
4453 {
4454     srcOrClipedAbsDrawRectChangeFlag_ = false;
4455     geometryChangeNotPerceived_ = false;
4456     removedChildrenRect_.Clear();
4457 }
4458 
UpdateSrcOrClipedAbsDrawRectChangeState(const RectI & clipRect)4459 void RSRenderNode::UpdateSrcOrClipedAbsDrawRectChangeState(const RectI& clipRect)
4460 {
4461     if (RSSystemProperties::GetSkipGeometryNotChangeEnabled()) {
4462         if (geometryChangeNotPerceived_) {
4463             srcOrClipedAbsDrawRectChangeFlag_ = false;
4464             return;
4465         }
4466     }
4467     auto clipedAbsDrawRect = absDrawRect_.IntersectRect(clipRect);
4468     // The old dirty In surface is equivalent to the old clipped absolute draw rectangle
4469     srcOrClipedAbsDrawRectChangeFlag_ = (absDrawRect_ != oldAbsDrawRect_ || clipedAbsDrawRect != oldDirtyInSurface_);
4470 }
4471 
NodeDrawLargeAreaBlur(std::pair<bool,bool> & nodeDrawLargeAreaBlur)4472 void RSRenderNode::NodeDrawLargeAreaBlur(std::pair<bool, bool>& nodeDrawLargeAreaBlur)
4473 {
4474     auto backgroundFilterDrawable = GetFilterDrawable(false);
4475     auto compositingFilterDrawable = GetFilterDrawable(true);
4476     bool flagPredict = false;
4477     bool flagCurrent = false;
4478     if (backgroundFilterDrawable) {
4479         flagPredict = flagPredict || backgroundFilterDrawable->WouldDrawLargeAreaBlur();
4480         flagCurrent = flagCurrent || backgroundFilterDrawable->WouldDrawLargeAreaBlurPrecisely();
4481     }
4482     if (compositingFilterDrawable) {
4483         flagPredict = flagPredict || compositingFilterDrawable->WouldDrawLargeAreaBlur();
4484         flagCurrent = flagCurrent || compositingFilterDrawable->WouldDrawLargeAreaBlurPrecisely();
4485     }
4486     nodeDrawLargeAreaBlur.first = flagPredict;
4487     nodeDrawLargeAreaBlur.second = flagCurrent;
4488 }
4489 
OnSync()4490 void RSRenderNode::OnSync()
4491 {
4492     addedToPendingSyncList_ = false;
4493     bool isLeashWindowPartialSkip = false;
4494 
4495     if (renderDrawable_ == nullptr) {
4496         return;
4497     }
4498     // uifirstSkipPartialSync means don't need to trylock whether drawable is onDraw or not
4499     DrawableV2::RSRenderNodeSingleDrawableLocker
4500         singleLocker(uifirstSkipPartialSync_ ? nullptr : renderDrawable_.get());
4501     if (!uifirstSkipPartialSync_ && UNLIKELY(!singleLocker.IsLocked())) {
4502 #ifdef RS_ENABLE_GPU
4503         singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
4504 #endif
4505         RS_LOGE("Drawable try to Sync when node %{public}" PRIu64 " onDraw!!!", GetId());
4506         if (RSSystemProperties::GetSingleDrawableLockerEnabled()) {
4507             return;
4508         }
4509     }
4510 
4511     if (drawCmdListNeedSync_) {
4512         std::swap(stagingDrawCmdList_, renderDrawable_->drawCmdList_);
4513         stagingDrawCmdList_.clear();
4514         renderDrawable_->drawCmdIndex_ = stagingDrawCmdIndex_;
4515         drawCmdListNeedSync_ = false;
4516     }
4517 
4518     if (drawableVecNeedClear_) {
4519         ClearDrawableVec2();
4520     }
4521 
4522 #ifdef RS_ENABLE_GPU
4523     renderDrawable_->backgroundFilterDrawable_ = GetFilterDrawable(false);
4524     renderDrawable_->compositingFilterDrawable_ = GetFilterDrawable(true);
4525     if (stagingRenderParams_->NeedSync()) {
4526         stagingRenderParams_->OnSync(renderDrawable_->renderParams_);
4527     }
4528 #endif
4529     if (unobscuredUECChildrenNeedSync_) {
4530         renderDrawable_->UECChildrenIds_->clear();
4531         for (auto childUEC : *stagingUECChildren_) {
4532             renderDrawable_->UECChildrenIds_->insert(childUEC->GetId());
4533         }
4534         unobscuredUECChildrenNeedSync_ = false;
4535     }
4536     if (!uifirstSkipPartialSync_) {
4537         if (!dirtySlots_.empty()) {
4538             for (const auto& slot : dirtySlots_) {
4539                 if (auto& drawable = drawableVec_[static_cast<uint32_t>(slot)]) {
4540                     drawable->OnSync();
4541                 }
4542             }
4543             dirtySlots_.clear();
4544         }
4545 
4546         // copy newest for uifirst root node, now force sync done nodes
4547         if (uifirstNeedSync_) {
4548             RS_OPTIONAL_TRACE_NAME_FMT("uifirst_sync %lld", GetId());
4549             renderDrawable_->uifirstDrawCmdList_.assign(renderDrawable_->drawCmdList_.begin(),
4550                                                         renderDrawable_->drawCmdList_.end());
4551             renderDrawable_->uifirstDrawCmdIndex_ = renderDrawable_->drawCmdIndex_;
4552             renderDrawable_->renderParams_->OnSync(renderDrawable_->uifirstRenderParams_);
4553             uifirstNeedSync_ = false;
4554         }
4555     } else {
4556         RS_TRACE_NAME_FMT("partial_sync %lld", GetId());
4557         std::vector<RSDrawableSlot> todele;
4558         if (!dirtySlots_.empty()) {
4559             for (const auto& slot : dirtySlots_) {
4560                 if (slot != RSDrawableSlot::CONTENT_STYLE && slot != RSDrawableSlot::CHILDREN) { // SAVE_FRAME
4561                     if (auto& drawable = drawableVec_[static_cast<uint32_t>(slot)]) {
4562                         drawable->OnSync();
4563                     }
4564                     todele.push_back(slot);
4565                 }
4566             }
4567             for (const auto& slot : todele) {
4568                 dirtySlots_.erase(slot);
4569             }
4570         }
4571         uifirstSkipPartialSync_ = false;
4572         isLeashWindowPartialSkip = true;
4573     }
4574 #ifdef RS_ENABLE_GPU
4575     if (ShouldClearSurface()) {
4576         renderDrawable_->TryClearSurfaceOnSync();
4577         needClearSurface_ = false;
4578     }
4579 #endif
4580     // Reset FilterCache Flags
4581     backgroundFilterRegionChanged_ = false;
4582     backgroundFilterInteractWithDirty_ = false;
4583     foregroundFilterRegionChanged_ = false;
4584     foregroundFilterInteractWithDirty_ = false;
4585 
4586     // Reset Sync Flag
4587     // only canvas drawing node use SetNeedDraw function
4588     if (GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE && waitSync_) {
4589         renderDrawable_->SetNeedDraw(true);
4590     }
4591     waitSync_ = false;
4592 
4593     lastFrameSynced_ = !isLeashWindowPartialSkip;
4594 }
4595 
OnSkipSync()4596 void RSRenderNode::OnSkipSync()
4597 {
4598     lastFrameSynced_ = false;
4599     // clear flag: after skips sync, node not in RSMainThread::Instance()->GetContext.pendingSyncNodes_
4600     addedToPendingSyncList_ = false;
4601 }
4602 
ShouldClearSurface()4603 bool RSRenderNode::ShouldClearSurface()
4604 {
4605 #ifdef RS_ENABLE_GPU
4606     bool renderGroupFlag = GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE ||
4607         opincCache_.OpincGetRootFlag();
4608     bool freezeFlag = stagingRenderParams_->GetRSFreezeFlag();
4609     return (renderGroupFlag || freezeFlag || nodeGroupType_ == static_cast<uint8_t>(NodeGroupType::NONE)) &&
4610         needClearSurface_;
4611 #else
4612     return (nodeGroupType_ == static_cast<uint8_t>(NodeGroupType::NONE)) && needClearSurface_;
4613 #endif
4614 }
4615 
ValidateLightResources()4616 void RSRenderNode::ValidateLightResources()
4617 {
4618     auto& properties = GetMutableRenderProperties();
4619     if (properties.lightSourcePtr_ && properties.lightSourcePtr_->IsLightSourceValid()) {
4620         properties.CalculateAbsLightPosition();
4621         RSPointLightManager::Instance()->AddDirtyLightSource(weak_from_this());
4622     }
4623     if (properties.illuminatedPtr_ && properties.illuminatedPtr_->IsIlluminatedValid()) {
4624         RSPointLightManager::Instance()->AddDirtyIlluminated(weak_from_this());
4625     }
4626 }
4627 
MarkBlurIntersectWithDRM(bool intersectWithDRM,bool isDark)4628 void RSRenderNode::MarkBlurIntersectWithDRM(bool intersectWithDRM, bool isDark)
4629 {
4630 #ifdef RS_ENABLE_GPU
4631     const auto& properties = GetRenderProperties();
4632     if (properties.GetBackgroundFilter()) {
4633         if (auto filterDrawable = GetFilterDrawable(false)) {
4634             filterDrawable->MarkBlurIntersectWithDRM(intersectWithDRM, isDark);
4635         }
4636     }
4637 #endif
4638 }
4639 
GetUifirstSupportFlag()4640 bool RSRenderNode::GetUifirstSupportFlag()
4641 {
4642     if (sharedTransitionParam_ && !sharedTransitionParam_->IsInAppTranSition()) {
4643         return false;
4644     }
4645     return isChildSupportUifirst_ && isUifirstNode_;
4646 }
4647 
UpdatePointLightDirtySlot()4648 void RSRenderNode::UpdatePointLightDirtySlot()
4649 {
4650     UpdateDirtySlotsAndPendingNodes(RSDrawableSlot::POINT_LIGHT);
4651 }
4652 
AddToPendingSyncList()4653 void RSRenderNode::AddToPendingSyncList()
4654 {
4655     if (addedToPendingSyncList_) {
4656         return;
4657     }
4658 
4659     if (auto context = GetContext().lock()) {
4660         context->AddPendingSyncNode(shared_from_this());
4661         addedToPendingSyncList_ = true;
4662     } else {
4663         ROSEN_LOGE("RSRenderNode::AddToPendingSyncList context is null");
4664         OnSync();
4665     }
4666 }
4667 
SetStartingWindowFlag(bool startingFlag)4668 void RSRenderNode::SetStartingWindowFlag(bool startingFlag)
4669 {
4670     if (startingWindowFlag_ == startingFlag) {
4671         return;
4672     }
4673     startingWindowFlag_ = startingFlag;
4674     auto stagingParams = stagingRenderParams_.get();
4675     if (stagingParams) {
4676         stagingParams->SetStartingWindowFlag(startingFlag);
4677         AddToPendingSyncList();
4678     }
4679 }
4680 
MarkUifirstNode(bool isUifirstNode)4681 void RSRenderNode::MarkUifirstNode(bool isUifirstNode)
4682 {
4683     RS_OPTIONAL_TRACE_NAME_FMT("MarkUifirstNode id:%lld, isUifirstNode:%d", GetId(), isUifirstNode);
4684     isUifirstNode_ = isUifirstNode;
4685     isUifirstDelay_ = 0;
4686 }
4687 
4688 
MarkUifirstNode(bool isForceFlag,bool isUifirstEnable)4689 void RSRenderNode::MarkUifirstNode(bool isForceFlag, bool isUifirstEnable)
4690 {
4691     RS_TRACE_NAME_FMT("MarkUifirstNode id:%lld, isForceFlag:%d, isUifirstEnable:%d",
4692         GetId(), isForceFlag, isUifirstEnable);
4693     ROSEN_LOGI("MarkUifirstNode id:%{public}" PRIu64 " isForceFlag:%{public}d, isUifirstEnable:%{public}d",
4694         GetId(), isForceFlag, isUifirstEnable);
4695     isForceFlag_ = isForceFlag;
4696     isUifirstEnable_ = isUifirstEnable;
4697 }
4698 
GetUifirstNodeForceFlag() const4699 bool RSRenderNode::GetUifirstNodeForceFlag() const
4700 {
4701     return isForceFlag_;
4702 }
4703 
SetUIFirstSwitch(RSUIFirstSwitch uiFirstSwitch)4704 void RSRenderNode::SetUIFirstSwitch(RSUIFirstSwitch uiFirstSwitch)
4705 {
4706     uiFirstSwitch_ = uiFirstSwitch;
4707     if (auto& firstNode = GetFirstLevelNode()) {
4708         firstNode->uiFirstSwitch_ = uiFirstSwitch;
4709     }
4710 }
4711 
SetChildrenHasSharedTransition(bool hasSharedTransition)4712 void RSRenderNode::SetChildrenHasSharedTransition(bool hasSharedTransition)
4713 {
4714     childrenHasSharedTransition_ = hasSharedTransition;
4715 }
4716 
RemoveChildFromFulllist(NodeId id)4717 void RSRenderNode::RemoveChildFromFulllist(NodeId id)
4718 {
4719     // Make a copy of the fullChildrenList
4720     if (!fullChildrenList_) {
4721         return;
4722     }
4723     auto fullChildrenList = std::make_shared<std::vector<std::shared_ptr<RSRenderNode>>>(*fullChildrenList_);
4724 
4725     fullChildrenList->erase(std::remove_if(fullChildrenList->begin(),
4726         fullChildrenList->end(), [id](const auto& node) { return id == node->GetId(); }), fullChildrenList->end());
4727 
4728     // Move the fullChildrenList to fullChildrenList_ atomically
4729     ChildrenListSharedPtr constFullChildrenList = std::move(fullChildrenList);
4730     std::atomic_store_explicit(&fullChildrenList_, constFullChildrenList, std::memory_order_release);
4731 }
4732 
4733 std::map<NodeId, std::weak_ptr<SharedTransitionParam>> SharedTransitionParam::unpairedShareTransitions_;
4734 
SharedTransitionParam(RSRenderNode::SharedPtr inNode,RSRenderNode::SharedPtr outNode,bool isInSameWindow)4735 SharedTransitionParam::SharedTransitionParam(RSRenderNode::SharedPtr inNode, RSRenderNode::SharedPtr outNode,
4736     bool isInSameWindow)
4737     : inNode_(inNode), outNode_(outNode), inNodeId_(inNode->GetId()), outNodeId_(outNode->GetId()),
4738       crossApplication_(!isInSameWindow)
4739 {}
4740 
GetPairedNode(const NodeId nodeId) const4741 RSRenderNode::SharedPtr SharedTransitionParam::GetPairedNode(const NodeId nodeId) const
4742 {
4743     if (inNodeId_ == nodeId) {
4744         return outNode_.lock();
4745     }
4746     if (outNodeId_ == nodeId) {
4747         return inNode_.lock();
4748     }
4749     return nullptr;
4750 }
4751 
SetChildrenHasUIExtension(bool childrenHasUIExtension)4752 void RSRenderNode::SetChildrenHasUIExtension(bool childrenHasUIExtension)
4753 {
4754     childrenHasUIExtension_ = childrenHasUIExtension;
4755     auto parent = GetParent().lock();
4756     if (parent && parent->ChildrenHasUIExtension() != childrenHasUIExtension) {
4757         parent->SetChildrenHasUIExtension(childrenHasUIExtension);
4758     }
4759 }
4760 
HasRelation()4761 bool SharedTransitionParam::HasRelation()
4762 {
4763     return relation_ != NodeHierarchyRelation::UNKNOWN;
4764 }
4765 
SetNeedGenerateDrawable(const bool needGenerateDrawable)4766 void SharedTransitionParam::SetNeedGenerateDrawable(const bool needGenerateDrawable)
4767 {
4768     needGenerateDrawable_ = needGenerateDrawable;
4769 }
4770 
GenerateDrawable(const RSRenderNode & node)4771 void SharedTransitionParam::GenerateDrawable(const RSRenderNode& node)
4772 {
4773     if (!needGenerateDrawable_ || !HasRelation() || IsLower(node.GetId())) {
4774         return;
4775     }
4776     if (auto parent = node.GetParent().lock()) {
4777         parent->ApplyModifiers();
4778     }
4779     SetNeedGenerateDrawable(false);
4780 }
4781 
UpdateUnpairedSharedTransitionMap(const std::shared_ptr<SharedTransitionParam> & param)4782 void SharedTransitionParam::UpdateUnpairedSharedTransitionMap(const std::shared_ptr<SharedTransitionParam>& param)
4783 {
4784     if (auto it = unpairedShareTransitions_.find(param->inNodeId_);
4785         it != unpairedShareTransitions_.end()) {
4786         // remove successfully paired share transition
4787         unpairedShareTransitions_.erase(it);
4788         param->paired_ = true;
4789     } else {
4790         // add unpaired share transition
4791         unpairedShareTransitions_.emplace(param->inNodeId_, param);
4792     }
4793 }
4794 
IsLower(const NodeId nodeId) const4795 bool SharedTransitionParam::IsLower(const NodeId nodeId) const
4796 {
4797     if (relation_ == NodeHierarchyRelation::UNKNOWN) {
4798         return false;
4799     }
4800     return relation_ == NodeHierarchyRelation::IN_NODE_BELOW_OUT_NODE ? inNodeId_ == nodeId : outNodeId_ == nodeId;
4801 }
4802 
UpdateHierarchy(const NodeId nodeId)4803 void SharedTransitionParam::UpdateHierarchy(const NodeId nodeId)
4804 {
4805     // Skip if the hierarchy is already established
4806     if (relation_ != NodeHierarchyRelation::UNKNOWN) {
4807         return;
4808     }
4809 
4810     bool visitingInNode = (nodeId == inNodeId_);
4811     if (!visitingInNode && nodeId != outNodeId_) {
4812         return;
4813     }
4814     // Nodes in the same application will be traversed by order (first visited node has lower hierarchy), while
4815     // applications will be traversed by reverse order. If visitingInNode matches crossApplication_, inNode is above
4816     // outNode. Otherwise, inNode is below outNode.
4817     relation_ = (visitingInNode == crossApplication_) ? NodeHierarchyRelation::IN_NODE_ABOVE_OUT_NODE
4818                                                       : NodeHierarchyRelation::IN_NODE_BELOW_OUT_NODE;
4819 }
4820 
Dump() const4821 std::string SharedTransitionParam::Dump() const
4822 {
4823     return ", SharedTransitionParam: [" + std::to_string(inNodeId_) + " -> " + std::to_string(outNodeId_) + "]";
4824 }
4825 
ResetRelation()4826 void SharedTransitionParam::ResetRelation()
4827 {
4828     relation_ = NodeHierarchyRelation::UNKNOWN;
4829 }
4830 
InternalUnregisterSelf()4831 void SharedTransitionParam::InternalUnregisterSelf()
4832 {
4833     auto inNode = inNode_.lock();
4834     if (inNode) {
4835         inNode->SetSharedTransitionParam(nullptr);
4836     }
4837     auto outNode = outNode_.lock();
4838     if (outNode) {
4839         outNode->SetSharedTransitionParam(nullptr);
4840     }
4841     if (inNode) {
4842         if (auto parent = inNode->GetParent().lock()) {
4843             parent->ApplyModifiers();
4844         }
4845     }
4846     if (outNode) {
4847         if (auto parent = outNode->GetParent().lock()) {
4848             parent->ApplyModifiers();
4849         }
4850     }
4851 }
4852 
ProcessBehindWindowOnTreeStateChanged()4853 void RSRenderNode::ProcessBehindWindowOnTreeStateChanged()
4854 {
4855     auto rootNode = GetInstanceRootNode();
4856     if (!rootNode) {
4857         return;
4858     }
4859     RS_LOGD("RSSurfaceRenderNode::ProcessBehindWindowOnTreeStateChanged nodeId = %{public}" PRIu64
4860         ", isOnTheTree_ = %{public}d", GetId(), isOnTheTree_);
4861     if (isOnTheTree_) {
4862         rootNode->AddChildBlurBehindWindow(GetId());
4863     } else {
4864         rootNode->RemoveChildBlurBehindWindow(GetId());
4865     }
4866 }
4867 
ProcessBehindWindowAfterApplyModifiers()4868 void RSRenderNode::ProcessBehindWindowAfterApplyModifiers()
4869 {
4870     auto rootNode = GetInstanceRootNode();
4871     if (!rootNode) {
4872         return;
4873     }
4874     auto& properties = GetMutableRenderProperties();
4875     bool useEffect = properties.GetUseEffect();
4876     UseEffectType useEffectType = static_cast<UseEffectType>(properties.GetUseEffectType());
4877     RS_LOGD("RSSurfaceRenderNode::ProcessBehindWindowAfterApplyModifiers nodeId = %{public}" PRIu64
4878         ", isOnTheTree_ = %{public}d, useEffect = %{public}d, useEffectType = %{public}hd",
4879         GetId(), isOnTheTree_, useEffect, useEffectType);
4880     if (useEffect && useEffectType == UseEffectType::BEHIND_WINDOW) {
4881         rootNode->AddChildBlurBehindWindow(GetId());
4882     } else {
4883         rootNode->RemoveChildBlurBehindWindow(GetId());
4884     }
4885 }
4886 
UpdateDrawableBehindWindow()4887 void RSRenderNode::UpdateDrawableBehindWindow()
4888 {
4889     AddDirtyType(ModifierNG::RSModifierType::BACKGROUND_FILTER);
4890     SetContentDirty();
4891 #ifdef RS_ENABLE_GPU
4892     auto dirtySlots = RSDrawable::CalculateDirtySlotsNG(dirtyTypesNG_, drawableVec_);
4893     if (dirtySlots.empty()) {
4894         RS_LOGD("RSRenderNode::UpdateDrawableBehindWindow dirtySlots is empty");
4895         return;
4896     }
4897     bool drawableChanged = RSDrawable::UpdateDirtySlots(*this, drawableVec_, dirtySlots);
4898     RSDrawable::FuzeDrawableSlots(*this, drawableVec_);
4899     RS_LOGD("RSRenderNode::UpdateDrawableBehindWindow drawableChanged:%{public}d", drawableChanged);
4900     if (drawableChanged) {
4901         RSDrawable::UpdateSaveRestore(*this, drawableVec_, drawableVecStatus_);
4902         UpdateDisplayList();
4903     }
4904     if (dirtySlots_.empty()) {
4905         dirtySlots_ = std::move(dirtySlots);
4906     } else {
4907         dirtySlots_.insert(dirtySlots.begin(), dirtySlots.end());
4908     }
4909 #endif
4910 }
4911 
GetAllModifierSize()4912 size_t RSRenderNode::GetAllModifierSize()
4913 {
4914     size_t totalSize = 0;
4915     for (auto& slot : modifiersNG_) {
4916         for (auto& modifier : slot) {
4917             if (modifier) {
4918                 totalSize += modifier->GetPropertySize();
4919             }
4920         }
4921     }
4922 
4923     return totalSize;
4924 }
4925 
ClearDrawableVec2()4926 void RSRenderNode::ClearDrawableVec2()
4927 {
4928     if (drawableVecNeedClear_) {
4929         if (GetType() != RSRenderNodeType::CANVAS_DRAWING_NODE &&
4930             drawableVec_[static_cast<int8_t>(RSDrawableSlot::CONTENT_STYLE)]) {
4931             if (isPurgeable_) {
4932                 drawableVec_[static_cast<int8_t>(RSDrawableSlot::CONTENT_STYLE)]->OnPurge();
4933             }
4934             drawableVec_[static_cast<int8_t>(RSDrawableSlot::CONTENT_STYLE)].reset();
4935             dirtyTypesNG_.set(static_cast<int>(ModifierNG::RSModifierType::CONTENT_STYLE), true);
4936         }
4937         if (drawableVec_[static_cast<int8_t>(RSDrawableSlot::TRANSITION)]) {
4938             drawableVec_[static_cast<int8_t>(RSDrawableSlot::TRANSITION)].reset();
4939             dirtyTypesNG_.set(static_cast<int>(ModifierNG::RSModifierType::TRANSITION_STYLE), true);
4940         }
4941         if (drawableVec_[static_cast<int8_t>(RSDrawableSlot::BACKGROUND_STYLE)]) {
4942             drawableVec_[static_cast<int8_t>(RSDrawableSlot::BACKGROUND_STYLE)].reset();
4943             dirtyTypesNG_.set(static_cast<int>(ModifierNG::RSModifierType::BACKGROUND_STYLE), true);
4944         }
4945         if (drawableVec_[static_cast<int8_t>(RSDrawableSlot::FOREGROUND_STYLE)]) {
4946             drawableVec_[static_cast<int8_t>(RSDrawableSlot::FOREGROUND_STYLE)].reset();
4947             dirtyTypesNG_.set(static_cast<int>(ModifierNG::RSModifierType::FOREGROUND_STYLE), true);
4948         }
4949         if (drawableVec_[static_cast<int8_t>(RSDrawableSlot::OVERLAY)]) {
4950             drawableVec_[static_cast<int8_t>(RSDrawableSlot::OVERLAY)].reset();
4951             dirtyTypesNG_.set(static_cast<int>(ModifierNG::RSModifierType::OVERLAY_STYLE), true);
4952         }
4953         drawableVecNeedClear_ = false;
4954     }
4955 }
4956 
AddModifier(const std::shared_ptr<ModifierNG::RSRenderModifier> & modifier,bool isSingleFrameComposer)4957 void RSRenderNode::AddModifier(
4958     const std::shared_ptr<ModifierNG::RSRenderModifier>& modifier, bool isSingleFrameComposer)
4959 {
4960     if (modifier == nullptr) {
4961         ROSEN_LOGW("RSRenderNode::AddModifier: null modifier, add failed.");
4962         return;
4963     }
4964     if (RSSystemProperties::GetSingleFrameComposerEnabled() &&
4965         GetNodeIsSingleFrameComposer() && isSingleFrameComposer) {
4966         SetDirty();
4967         if (singleFrameComposer_ == nullptr) {
4968             singleFrameComposer_ = std::make_shared<RSSingleFrameComposer>();
4969         }
4970         singleFrameComposer_->SingleFrameAddModifierNG(modifier);
4971         ROSEN_LOGI_IF(DEBUG_MODIFIER, "RSRenderNode:add modifierNG for single frame, node id: %{public}" PRIu64 ","
4972             "type: %{public}d", GetId(), (int)modifier->GetType());
4973         return;
4974     }
4975     if (modifier->IsAttached()) {
4976         // other cleanup
4977         modifier->OnDetachModifier();
4978     }
4979     // bounds and frame modifiers must be unique
4980     if (modifier->GetType() == ModifierNG::RSModifierType::BOUNDS) {
4981         boundsModifierNG_ = modifier;
4982     }
4983     if (modifier->GetType() == ModifierNG::RSModifierType::FRAME) {
4984         frameModifierNG_ = modifier;
4985     }
4986     if (modifier->IsCustom()) {
4987         modifier->SetSingleFrameModifier(false);
4988     }
4989     modifiersNG_[static_cast<uint16_t>(modifier->GetType())].emplace_back(modifier);
4990     modifier->OnAttachModifier(*this);
4991 }
4992 
RemoveModifier(ModifierNG::RSModifierType type,ModifierId id)4993 void RSRenderNode::RemoveModifier(ModifierNG::RSModifierType type, ModifierId id)
4994 {
4995     auto& slot = modifiersNG_[static_cast<uint16_t>(type)];
4996     auto it =
4997         std::find_if(slot.begin(), slot.end(), [id](const auto& modifier) -> bool { return modifier->GetId() == id; });
4998     if (it == slot.end()) {
4999         return;
5000     }
5001     (*it)->OnDetachModifier();
5002     slot.erase(it);
5003 }
5004 
RemoveModifierNG(ModifierId id)5005 void RSRenderNode::RemoveModifierNG(ModifierId id)
5006 {
5007     SetDirty();
5008     for (auto& slot : modifiersNG_) {
5009         auto it = std::find_if(
5010             slot.begin(), slot.end(), [id](const auto& modifier) -> bool { return modifier->GetId() == id; });
5011         if (it == slot.end()) {
5012             continue;
5013         }
5014         AddDirtyType((*it)->GetType());
5015         (*it)->OnDetachModifier();
5016         slot.erase(it);
5017     }
5018 }
5019 
RemoveAllModifiersNG()5020 void RSRenderNode::RemoveAllModifiersNG()
5021 {
5022     for (auto& slot : modifiersNG_) {
5023         for (auto& modifier : slot) {
5024             modifier->OnDetachModifier();
5025         }
5026         slot.clear();
5027     }
5028 }
5029 
GetModifierNG(ModifierNG::RSModifierType type,ModifierId id) const5030 std::shared_ptr<ModifierNG::RSRenderModifier> RSRenderNode::GetModifierNG(
5031     ModifierNG::RSModifierType type, ModifierId id) const
5032 {
5033     auto& slot = modifiersNG_[static_cast<uint16_t>(type)];
5034     if (id == 0) {
5035         return slot.empty() ? nullptr : slot.back();
5036     }
5037     auto it =
5038         std::find_if(slot.begin(), slot.end(), [id](const auto& modifier) -> bool { return modifier->GetId() == id; });
5039     if (it == slot.end()) {
5040         return nullptr;
5041     }
5042     return *it;
5043 }
5044 
GetModifiersNG(ModifierNG::RSModifierType type) const5045 const RSRenderNode::ModifierNGContainer& RSRenderNode::GetModifiersNG(ModifierNG::RSModifierType type) const
5046 {
5047     return modifiersNG_[static_cast<uint16_t>(type)];
5048 }
5049 
GetAllModifiers() const5050 const RSRenderNode::ModifiersNGContainer& RSRenderNode::GetAllModifiers() const
5051 {
5052     return modifiersNG_;
5053 }
5054 
HasDrawCmdModifiers() const5055 bool RSRenderNode::HasDrawCmdModifiers() const
5056 {
5057     bool ret = !GetModifiersNG(ModifierNG::RSModifierType::CONTENT_STYLE).empty() ||
5058                !GetModifiersNG(ModifierNG::RSModifierType::TRANSITION_STYLE).empty() ||
5059                !GetModifiersNG(ModifierNG::RSModifierType::BACKGROUND_STYLE).empty() ||
5060                !GetModifiersNG(ModifierNG::RSModifierType::FOREGROUND_STYLE).empty() ||
5061                !GetModifiersNG(ModifierNG::RSModifierType::OVERLAY_STYLE).empty() ||
5062                !GetModifiersNG(ModifierNG::RSModifierType::NODE_MODIFIER).empty() ||
5063                !GetModifiersNG(ModifierNG::RSModifierType::BEHIND_WINDOW_FILTER).empty() ||
5064                !GetModifiersNG(ModifierNG::RSModifierType::ENV_FOREGROUND_COLOR).empty() ||
5065                !GetModifiersNG(ModifierNG::RSModifierType::HDR_BRIGHTNESS).empty() ||
5066                !GetModifiersNG(ModifierNG::RSModifierType::CHILDREN).empty();
5067     if (!ret) {
5068         const auto& clipToFrameModifiers = GetModifiersNG(ModifierNG::RSModifierType::CLIP_TO_FRAME);
5069         for (auto modifier : clipToFrameModifiers) {
5070             if (modifier->HasProperty(ModifierNG::RSPropertyType::CUSTOM_CLIP_TO_FRAME)) {
5071                 ret = true;
5072                 break;
5073             }
5074         }
5075     }
5076     return ret;
5077 }
5078 
HasContentStyleModifierOnly() const5079 bool RSRenderNode::HasContentStyleModifierOnly() const
5080 {
5081     bool ret = !GetModifiersNG(ModifierNG::RSModifierType::CONTENT_STYLE).empty() &&
5082                GetModifiersNG(ModifierNG::RSModifierType::TRANSITION_STYLE).empty() &&
5083                GetModifiersNG(ModifierNG::RSModifierType::BACKGROUND_STYLE).empty() &&
5084                GetModifiersNG(ModifierNG::RSModifierType::FOREGROUND_STYLE).empty() &&
5085                GetModifiersNG(ModifierNG::RSModifierType::OVERLAY_STYLE).empty() &&
5086                GetModifiersNG(ModifierNG::RSModifierType::NODE_MODIFIER).empty() &&
5087                GetModifiersNG(ModifierNG::RSModifierType::BEHIND_WINDOW_FILTER).empty() &&
5088                GetModifiersNG(ModifierNG::RSModifierType::ENV_FOREGROUND_COLOR).empty() &&
5089                GetModifiersNG(ModifierNG::RSModifierType::HDR_BRIGHTNESS).empty() &&
5090                GetModifiersNG(ModifierNG::RSModifierType::CHILDREN).empty();
5091     if (ret) {
5092         const auto& clipToFrameModifiers = GetModifiersNG(ModifierNG::RSModifierType::CLIP_TO_FRAME);
5093         for (auto modifier : clipToFrameModifiers) {
5094             if (modifier->HasProperty(ModifierNG::RSPropertyType::CUSTOM_CLIP_TO_FRAME)) {
5095                 ret = false;
5096                 break;
5097             }
5098         }
5099     }
5100     return ret;
5101 }
5102 
SetNeedUseCmdlistDrawRegion(bool needUseCmdlistDrawRegion)5103 void RSRenderNode::SetNeedUseCmdlistDrawRegion(bool needUseCmdlistDrawRegion)
5104 {
5105     needUseCmdlistDrawRegion_ = needUseCmdlistDrawRegion;
5106 }
5107 
GetNeedUseCmdlistDrawRegion()5108 bool RSRenderNode::GetNeedUseCmdlistDrawRegion()
5109 {
5110     // Only the target node of the target scene can usd the cmdlistDrawRegion when optimize open.
5111     return RSSystemProperties::GetOptimizeCanvasDrawRegionEnabled() && needUseCmdlistDrawRegion_ &&
5112            RSOptimizeCanvasDirtyCollector::GetInstance().IsOptimizeCanvasDirtyEnabled(GetId());
5113 }
5114 
SubTreeSkipPrepare(RSDirtyRegionManager & dirtyManager,bool isDirty,bool accumGeoDirty,const RectI & clipRect)5115 void RSRenderNode::SubTreeSkipPrepare(
5116     RSDirtyRegionManager& dirtyManager, bool isDirty, bool accumGeoDirty, const RectI& clipRect)
5117 {
5118     // [planning] Prev and current dirty rect need to be joined only when accumGeoDirty is true.
5119     if ((isDirty || accumGeoDirty) && (HasChildrenOutOfRect() || lastFrameHasChildrenOutOfRect_)) {
5120         auto& geoPtr = GetRenderProperties().GetBoundsGeometry();
5121         if (geoPtr == nullptr) {
5122             return;
5123         }
5124         auto oldDirtyRect = geoPtr->MapRect(oldChildrenRect_.ConvertTo<float>(), oldAbsMatrix_);
5125         auto oldDirtyRectClip = oldDirtyRect.IntersectRect(oldClipRect_);
5126         auto dirtyRect = geoPtr->MapAbsRect(childrenRect_.ConvertTo<float>());
5127         auto dirtyRectClip = dirtyRect.IntersectRect(clipRect);
5128         dirtyRectClip = dirtyRectClip.JoinRect(oldDirtyRectClip);
5129         IsFirstLevelCrossNode() ?
5130             dirtyManager.MergeDirtyRect(dirtyRect.JoinRect(oldDirtyRect)) : dirtyManager.MergeDirtyRect(dirtyRectClip);
5131         UpdateSubTreeSkipDirtyForDFX(dirtyManager, dirtyRectClip);
5132     }
5133     if (isDirty && GetChildrenCount() == 0) {
5134 #ifdef SUBTREE_PARALLEL_ENABLE
5135         ClearSubtreeParallelNodes();
5136 #endif
5137         ResetChildRelevantFlags();
5138     }
5139     SetGeoUpdateDelay(accumGeoDirty);
5140     UpdateSubTreeInfo(clipRect);
5141     lastFrameSubTreeSkipped_ = true;
5142 }
5143 
MapAndUpdateChildrenRect()5144 void RSRenderNode::MapAndUpdateChildrenRect()
5145 {
5146     auto geoPtr = GetRenderProperties().GetBoundsGeometry();
5147     if (!shouldPaint_ || geoPtr == nullptr) {
5148         return;
5149     }
5150     auto childRect = selfDrawRect_;
5151     // all child must map to its direct parent
5152     if (!childrenRect_.IsEmpty()) {
5153         // clean subtree means childrenRect maps to parent already
5154         childRect = childRect.JoinRect(childrenRect_.ConvertTo<float>());
5155     }
5156     // map before update parent, if parent has clip property, use clipped children rect instead.
5157     // node with sharedTransitionParam should recalculate childRelativeToParentMatrix from absMatrix due to sandbox.
5158     if (auto parentNode = parent_.lock()) {
5159         const auto& parentProperties = parentNode->GetRenderProperties();
5160         const auto& sandbox = GetRenderProperties().GetSandBox();
5161         RectI childRectMapped;
5162         if (LIKELY(!sandbox.has_value())) {
5163             childRectMapped = geoPtr->MapRect(childRect, geoPtr->GetMatrix());
5164         } else {
5165             Drawing::Matrix invertAbsParentMatrix;
5166             const auto& parentGeoPtr = parentProperties.GetBoundsGeometry();
5167             if (parentGeoPtr && parentGeoPtr->GetAbsMatrix().Invert(invertAbsParentMatrix)) {
5168                 auto childRelativeToParentMatrix = geoPtr->GetAbsMatrix();
5169                 childRelativeToParentMatrix.PostConcat(invertAbsParentMatrix);
5170                 childRectMapped = geoPtr->MapRect(childRect, childRelativeToParentMatrix);
5171             } else {
5172                 childRectMapped = geoPtr->MapRect(childRect, geoPtr->GetMatrix());
5173             }
5174         }
5175         if (parentProperties.GetClipToBounds() || parentProperties.GetClipToFrame()) {
5176             childRectMapped = parentNode->GetSelfDrawRect().ConvertTo<int>().IntersectRect(childRectMapped);
5177         }
5178         parentNode->UpdateChildrenRect(childRectMapped);
5179         // check each child is inside of parent
5180         childRect = childRectMapped.ConvertTo<float>();
5181         if (!childRect.IsInsideOf(parentNode->GetSelfDrawRect())) {
5182             parentNode->UpdateChildrenOutOfRectFlag(true);
5183         }
5184     }
5185 }
5186 
UpdateDrawingCacheInfoAfterChildren(bool isInBlackList)5187 void RSRenderNode::UpdateDrawingCacheInfoAfterChildren(bool isInBlackList)
5188 {
5189     RS_LOGI_IF(DEBUG_NODE, "RSRenderNode::UpdateDrawingCacheInfoAC uifirstArkTsCardNode:%{public}d"
5190         " startingWindowFlag_:%{public}d HasChildrenOutOfRect:%{public}d drawingCacheType:%{public}d",
5191         IsUifirstArkTsCardNode(), startingWindowFlag_, HasChildrenOutOfRect(), GetDrawingCacheType());
5192     if (IsUifirstArkTsCardNode()) {
5193         // disable render group because cards will use uifirst cache.
5194         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
5195     } else if (isInBlackList) {
5196         stagingRenderParams_->SetNodeGroupHasChildInBlacklist(true);
5197     }
5198     if (HasChildrenOutOfRect() && GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
5199         RS_OPTIONAL_TRACE_NAME_FMT("DrawingCacheInfoAfter ChildrenOutOfRect id:%llu", GetId());
5200         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
5201     }
5202 #ifdef RS_ENABLE_GPU
5203     stagingRenderParams_->SetDrawingCacheType(GetDrawingCacheType());
5204 #endif
5205     if (GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE) {
5206         RS_OPTIONAL_TRACE_NAME_FMT("DrawingCacheInfoAfter id:%llu cacheType:%d childHasVisibleFilter:%d " \
5207             "childHasVisibleEffect:%d",
5208             GetId(), GetDrawingCacheType(), childHasVisibleFilter_, childHasVisibleEffect_);
5209     }
5210     AddToPendingSyncList();
5211 }
5212 
IsUifirstArkTsCardNode()5213 bool RSRenderNode::IsUifirstArkTsCardNode()
5214 {
5215     if (nodeGroupType_ == NodeGroupType::NONE) {
5216         return false;
5217     }
5218     for (auto& child : *GetChildren()) {
5219         if (!child) {
5220             continue;
5221         }
5222         auto surfaceChild = child->ReinterpretCastTo<RSSurfaceRenderNode>();
5223         if (!surfaceChild) {
5224             continue;
5225         }
5226         if (surfaceChild->GetLastFrameUifirstFlag() == MultiThreadCacheType::ARKTS_CARD) {
5227             return true;
5228         }
5229     }
5230     return false;
5231 }
5232 
NodePostPrepare(std::shared_ptr<RSSurfaceRenderNode> curSurfaceNode,const RectI & clipRect)5233 void RSRenderNode::NodePostPrepare(
5234     std::shared_ptr<RSSurfaceRenderNode> curSurfaceNode, const RectI& clipRect)
5235 {
5236     MapAndUpdateChildrenRect();
5237     UpdateSubTreeInfo(clipRect);
5238     UpdateLocalDrawRect();
5239     UpdateAbsDrawRect();
5240     ResetChangeState();
5241     SetHasUnobscuredUEC();
5242     if (curSurfaceNode == nullptr) {
5243         UpdateVirtualScreenWhiteListInfo();
5244     }
5245 }
5246 
UpdateDrawableEnableEDR()5247 void RSRenderNode::UpdateDrawableEnableEDR()
5248 {
5249     bool hasEDREffect = std::any_of(edrDrawableSlots.begin(), edrDrawableSlots.end(), [this](auto slot) {
5250         auto drawable = this->drawableVec_[static_cast<int8_t>(slot)];
5251         return drawable && drawable->GetEnableEDR();
5252     });
5253     SetEnableHdrEffect(hasEDREffect);
5254 }
5255 } // namespace Rosen
5256 } // namespace OHOS
5257