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