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 "rs_trace.h"
26 
27 #include "animation/rs_render_animation.h"
28 #include "common/rs_common_def.h"
29 #include "common/rs_obj_abs_geometry.h"
30 #include "common/rs_optional_trace.h"
31 #include "drawable/rs_misc_drawable.h"
32 #include "drawable/rs_property_drawable_foreground.h"
33 #include "drawable/rs_render_node_drawable_adapter.h"
34 #include "modifier/rs_modifier_type.h"
35 #include "offscreen_render/rs_offscreen_render_thread.h"
36 #include "params/rs_render_params.h"
37 #include "pipeline/rs_context.h"
38 #include "pipeline/rs_display_render_node.h"
39 #include "pipeline/rs_effect_render_node.h"
40 #include "pipeline/rs_paint_filter_canvas.h"
41 #include "pipeline/rs_root_render_node.h"
42 #include "pipeline/rs_surface_render_node.h"
43 #include "pipeline/sk_resource_manager.h"
44 #include "platform/common/rs_log.h"
45 #include "platform/common/rs_system_properties.h"
46 #include "property/rs_point_light_manager.h"
47 #include "property/rs_properties_painter.h"
48 #include "property/rs_property_trace.h"
49 #include "render/rs_foreground_effect_filter.h"
50 #include "transaction/rs_transaction_proxy.h"
51 #include "visitor/rs_node_visitor.h"
52 
53 #ifdef RS_ENABLE_VK
54 #include "include/gpu/GrBackendSurface.h"
55 #include "platform/ohos/backend/native_buffer_utils.h"
56 #include "platform/ohos/backend/rs_vulkan_context.h"
57 #endif
58 
59 #ifdef RS_ENABLE_VK
60 namespace {
findMemoryType(uint32_t typeFilter,VkMemoryPropertyFlags properties)61 uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
62 {
63     auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
64     VkPhysicalDevice physicalDevice = vkContext.GetPhysicalDevice();
65 
66     VkPhysicalDeviceMemoryProperties memProperties;
67     vkContext.vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
68 
69     for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
70         if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
71             return i;
72         }
73     }
74 
75     return UINT32_MAX;
76 }
77 
SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,const VkImageCreateInfo & imageInfo)78 void SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,
79     const VkImageCreateInfo& imageInfo)
80 {
81     vkImageInfo->imageTiling = imageInfo.tiling;
82     vkImageInfo->imageLayout = imageInfo.initialLayout;
83     vkImageInfo->format = imageInfo.format;
84     vkImageInfo->imageUsageFlags = imageInfo.usage;
85     vkImageInfo->levelCount = imageInfo.mipLevels;
86     vkImageInfo->currentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL;
87     vkImageInfo->ycbcrConversionInfo = {};
88     vkImageInfo->sharingMode = imageInfo.sharingMode;
89 }
90 
MakeBackendTexture(uint32_t width,uint32_t height,VkFormat format=VK_FORMAT_R8G8B8A8_UNORM)91 OHOS::Rosen::Drawing::BackendTexture MakeBackendTexture(uint32_t width, uint32_t height,
92     VkFormat format = VK_FORMAT_R8G8B8A8_UNORM)
93 {
94     VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
95     VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
96         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
97     VkImageCreateInfo imageInfo {
98         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
99         .pNext = nullptr,
100         .flags = 0,
101         .imageType = VK_IMAGE_TYPE_2D,
102         .format = format,
103         .extent = {width, height, 1},
104         .mipLevels = 1,
105         .arrayLayers = 1,
106         .samples = VK_SAMPLE_COUNT_1_BIT,
107         .tiling = tiling,
108         .usage = usage,
109         .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
110         .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
111     };
112 
113     auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
114     VkDevice device = vkContext.GetDevice();
115     VkImage image = VK_NULL_HANDLE;
116     VkDeviceMemory memory = VK_NULL_HANDLE;
117 
118     if (width * height > OHOS::Rosen::NativeBufferUtils::VKIMAGE_LIMIT_SIZE) {
119         ROSEN_LOGE("NativeBufferUtils: vkCreateImag failed, image is too large, width:%{public}u, height::%{public}u",
120             width, height);
121         return {};
122     }
123 
124     if (vkContext.vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
125         return {};
126     }
127 
128     VkMemoryRequirements memRequirements;
129     vkContext.vkGetImageMemoryRequirements(device, image, &memRequirements);
130 
131     VkMemoryAllocateInfo allocInfo{};
132     allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
133     allocInfo.allocationSize = memRequirements.size;
134     allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
135     if (allocInfo.memoryTypeIndex == UINT32_MAX) {
136         return {};
137     }
138 
139     if (vkContext.vkAllocateMemory(device, &allocInfo, nullptr, &memory) != VK_SUCCESS) {
140         return {};
141     }
142 
143     vkContext.vkBindImageMemory(device, image, memory, 0);
144 
145     OHOS::Rosen::RsVulkanMemStat& memStat = vkContext.GetRsVkMemStat();
146     auto time = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now());
147     std::string timeStamp = std::to_string(static_cast<uint64_t>(time.time_since_epoch().count()));
148     memStat.InsertResource(timeStamp, static_cast<uint64_t>(memRequirements.size));
149     OHOS::Rosen::Drawing::BackendTexture backendTexture(true);
150     OHOS::Rosen::Drawing::TextureInfo textureInfo;
151     textureInfo.SetWidth(width);
152     textureInfo.SetHeight(height);
153 
154     std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo =
155         std::make_shared<OHOS::Rosen::Drawing::VKTextureInfo>();
156     vkImageInfo->vkImage = image;
157     vkImageInfo->vkAlloc.memory = memory;
158     vkImageInfo->vkAlloc.size = memRequirements.size;
159     vkImageInfo->vkAlloc.statName = timeStamp;
160 
161     SetVkImageInfo(vkImageInfo, imageInfo);
162     textureInfo.SetVKTextureInfo(vkImageInfo);
163     backendTexture.SetTextureInfo(textureInfo);
164     return backendTexture;
165 }
166 } // un-named
167 #endif
168 
169 namespace OHOS {
170 namespace Rosen {
OnRegister(const std::weak_ptr<RSContext> & context)171 void RSRenderNode::OnRegister(const std::weak_ptr<RSContext>& context)
172 {
173     context_ = context;
174     renderContent_->type_ = GetType();
175     renderContent_->renderProperties_.backref_ = weak_from_this();
176     SetDirty(true);
177     InitRenderParams();
178 }
179 
IsPureContainer() const180 bool RSRenderNode::IsPureContainer() const
181 {
182     auto& drawCmdModifiers_ = renderContent_->drawCmdModifiers_;
183     return (drawCmdModifiers_.empty() && !GetRenderProperties().isDrawn_ && !GetRenderProperties().alphaNeedApply_);
184 }
185 
IsContentNode() const186 bool RSRenderNode::IsContentNode() const
187 {
188     auto& drawCmdModifiers_ = renderContent_->drawCmdModifiers_;
189     return ((drawCmdModifiers_.size() == 1 && drawCmdModifiers_.count(RSModifierType::CONTENT_STYLE)) ||
190                drawCmdModifiers_.empty()) &&
191            !GetRenderProperties().isDrawn_;
192 }
193 
194 namespace {
195 const std::set<RSModifierType> GROUPABLE_ANIMATION_TYPE = {
196     RSModifierType::ALPHA,
197     RSModifierType::ROTATION,
198     RSModifierType::SCALE,
199 };
200 const std::set<RSModifierType> CACHEABLE_ANIMATION_TYPE = {
201     RSModifierType::BOUNDS,
202     RSModifierType::FRAME,
203 };
204 const std::set<RSModifierType> BASIC_GEOTRANSFORM_ANIMATION_TYPE = {
205     RSModifierType::TRANSLATE,
206     RSModifierType::SCALE,
207     RSModifierType::ALPHA,
208 };
209 }
210 
IsPurgeAble()211 static inline bool IsPurgeAble()
212 {
213     return RSSystemProperties::GetRenderNodePurgeEnabled() && RSUniRenderJudgement::IsUniRender();
214 }
215 
RSRenderNode(NodeId id,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)216 RSRenderNode::RSRenderNode(NodeId id, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
217     : id_(id), context_(context), isTextureExportNode_(isTextureExportNode), isPurgeable_(IsPurgeAble())
218 {}
219 
RSRenderNode(NodeId id,bool isOnTheTree,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)220 RSRenderNode::RSRenderNode(
221     NodeId id, bool isOnTheTree, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
222     : isOnTheTree_(isOnTheTree), id_(id), context_(context), isTextureExportNode_(isTextureExportNode),
223       isPurgeable_(IsPurgeAble())
224 {}
225 
AddChild(SharedPtr child,int index)226 void RSRenderNode::AddChild(SharedPtr child, int index)
227 {
228     // sanity check, avoid loop
229     if (child == nullptr || child->GetId() == GetId()) {
230         return;
231     }
232     // if child already has a parent, remove it from its previous parent
233     if (auto prevParent = child->GetParent().lock()) {
234         prevParent->RemoveChild(child, true);
235         child->InternalRemoveSelfFromDisappearingChildren();
236     }
237 
238     // Set parent-child relationship
239     child->SetParent(weak_from_this());
240     if (index < 0 || index >= static_cast<int>(children_.size())) {
241         children_.emplace_back(child);
242     } else {
243         children_.emplace(std::next(children_.begin(), index), child);
244     }
245 
246     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
247     // A child is not on the tree until its parent is on the tree
248     if (isOnTheTree_) {
249         child->SetIsOnTheTree(true, instanceRootNodeId_, firstLevelNodeId_, drawingCacheRootId_,
250             uifirstRootNodeId_, displayNodeId_);
251     } else {
252         if (child->GetType() == RSRenderNodeType::SURFACE_NODE) {
253             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
254             ROSEN_LOGI("RSRenderNode:: add child surfaceNode[id:%{public}" PRIu64 " name:%{public}s]"
255             " parent'S isOnTheTree_:%{public}d", surfaceNode->GetId(), surfaceNode->GetNodeName().c_str(),
256             isOnTheTree_);
257         }
258     }
259     SetContentDirty();
260     isFullChildrenListValid_ = false;
261 }
262 
SetContainBootAnimation(bool isContainBootAnimation)263 void RSRenderNode::SetContainBootAnimation(bool isContainBootAnimation)
264 {
265     isContainBootAnimation_ = isContainBootAnimation;
266     isFullChildrenListValid_ = false;
267 }
268 
MoveChild(SharedPtr child,int index)269 void RSRenderNode::MoveChild(SharedPtr child, int index)
270 {
271     if (child == nullptr || child->GetParent().lock().get() != this) {
272         return;
273     }
274     auto it = std::find_if(children_.begin(), children_.end(),
275         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
276     if (it == children_.end()) {
277         return;
278     }
279 
280     // Reset parent-child relationship
281     if (index < 0 || index >= static_cast<int>(children_.size())) {
282         children_.emplace_back(child);
283     } else {
284         children_.emplace(std::next(children_.begin(), index), child);
285     }
286     children_.erase(it);
287     SetContentDirty();
288     isFullChildrenListValid_ = false;
289 }
290 
RemoveChild(SharedPtr child,bool skipTransition)291 void RSRenderNode::RemoveChild(SharedPtr child, bool skipTransition)
292 {
293     if (child == nullptr) {
294         return;
295     }
296     // break parent-child relationship
297     auto it = std::find_if(children_.begin(), children_.end(),
298         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
299     if (it == children_.end()) {
300         return;
301     }
302     // avoid duplicate entry in disappearingChildren_ (this should not happen)
303     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
304     // if child has disappearing transition, add it to disappearingChildren_
305     if (skipTransition == false && child->HasDisappearingTransition(true)) {
306         ROSEN_LOGD("RSRenderNode::RemoveChild %{public}" PRIu64 " move child(id %{public}" PRIu64 ") into"
307             " disappearingChildren", GetId(), child->GetId());
308         // keep shared_ptr alive for transition
309         uint32_t origPos = static_cast<uint32_t>(std::distance(children_.begin(), it));
310         disappearingChildren_.emplace_back(child, origPos);
311     } else {
312         child->ResetParent();
313     }
314     children_.erase(it);
315     if (child->GetBootAnimation()) {
316         SetContainBootAnimation(false);
317     }
318     SetContentDirty();
319     isFullChildrenListValid_ = false;
320 }
321 
SetHdrNum(bool flag,NodeId instanceRootNodeId)322 void RSRenderNode::SetHdrNum(bool flag, NodeId instanceRootNodeId)
323 {
324     auto context = GetContext().lock();
325     if (!context) {
326         ROSEN_LOGE("RSRenderNode::SetHdrNum: Invalid context");
327         return;
328     }
329     auto parentInstance = context->GetNodeMap().GetRenderNode(instanceRootNodeId);
330     if (!parentInstance) {
331         ROSEN_LOGE("RSRenderNode::SetHdrNum get parent instance root node info failed.");
332         return;
333     }
334     if (auto parentSurface = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>()) {
335         if (flag) {
336             parentSurface->IncreaseHDRNum();
337         } else {
338             parentSurface->ReduceHDRNum();
339         }
340     }
341 }
342 
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId,NodeId firstLevelNodeId,NodeId cacheNodeId,NodeId uifirstRootNodeId,NodeId displayNodeId)343 void RSRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId, NodeId firstLevelNodeId,
344     NodeId cacheNodeId, NodeId uifirstRootNodeId, NodeId displayNodeId)
345 {
346     // We do not need to label a child when the child is removed from a parent that is not on the tree
347     if (flag == isOnTheTree_) {
348         return;
349     }
350 
351     SetPurgeStatus(flag);
352 
353     // Need to count upeer or lower trees of HDR nodes
354     if (GetType() == RSRenderNodeType::CANVAS_NODE) {
355         auto canvasNode = RSBaseRenderNode::ReinterpretCast<RSCanvasRenderNode>(shared_from_this());
356         if (canvasNode != nullptr && canvasNode->GetHDRPresent()) {
357             NodeId parentNodeId = flag ? instanceRootNodeId : instanceRootNodeId_;
358             ROSEN_LOGD("RSRenderNode::SetIsOnTheTree HDRClient canvasNode[id:%{public}" PRIu64 " name:%{public}s]"
359                 " parent'S id:%{public}" PRIu64 " ", canvasNode->GetId(), canvasNode->GetNodeName().c_str(),
360                 parentNodeId);
361             SetHdrNum(flag, parentNodeId);
362         }
363     }
364 
365     isNewOnTree_ = flag && !isOnTheTree_;
366     isOnTheTree_ = flag;
367     displayNodeId_ = displayNodeId;
368     if (isOnTheTree_) {
369         instanceRootNodeId_ = instanceRootNodeId;
370         firstLevelNodeId_ = firstLevelNodeId;
371         OnTreeStateChanged();
372     } else {
373         OnTreeStateChanged();
374         instanceRootNodeId_ = instanceRootNodeId;
375         if (firstLevelNodeId_ != INVALID_NODEID) {
376             preFirstLevelNodeIdSet_.insert(firstLevelNodeId_);
377         }
378         firstLevelNodeId_ = firstLevelNodeId;
379     }
380     // if node is marked as cacheRoot, update subtree status when update surface
381     // in case prepare stage upper cacheRoot cannot specify dirty subnode
382     if (cacheNodeId != INVALID_NODEID) {
383         drawingCacheRootId_ = cacheNodeId;
384     }
385     if (uifirstRootNodeId != INVALID_NODEID) {
386         uifirstRootNodeId_ = uifirstRootNodeId;
387     }
388 
389     if (stagingRenderParams_) {
390         bool ret = stagingRenderParams_->SetFirstLevelNode(firstLevelNodeId_);
391         ret |= stagingRenderParams_->SetUiFirstRootNode(uifirstRootNodeId_);
392         if (ret) {
393             AddToPendingSyncList();
394         }
395     }
396 
397     for (auto& weakChild : children_) {
398         auto child = weakChild.lock();
399         if (child == nullptr) {
400             continue;
401         }
402         if (isOnTheTree_) {
403             AddPreFirstLevelNodeIdSet(child->GetPreFirstLevelNodeIdSet());
404         }
405         child->SetIsOnTheTree(flag, instanceRootNodeId, firstLevelNodeId, cacheNodeId,
406             INVALID_NODEID, displayNodeId);
407     }
408 
409     for (auto& [child, _] : disappearingChildren_) {
410         child->SetIsOnTheTree(flag, instanceRootNodeId, firstLevelNodeId, cacheNodeId,
411             INVALID_NODEID, displayNodeId);
412     }
413 }
414 
ResetChildRelevantFlags()415 void RSRenderNode::ResetChildRelevantFlags()
416 {
417     childHasVisibleFilter_ = false;
418     childHasVisibleEffect_ = false;
419     childHasSharedTransition_ = false;
420     visibleFilterChild_.clear();
421     visibleEffectChild_.clear();
422     childrenRect_.Clear();
423     hasChildrenOutOfRect_ = false;
424 }
425 
UpdateChildrenRect(const RectI & subRect)426 void RSRenderNode::UpdateChildrenRect(const RectI& subRect)
427 {
428     if (!subRect.IsEmpty()) {
429         if (childrenRect_.IsEmpty()) {
430             // init as not empty subRect in case join RectI enlarging area
431             childrenRect_ = subRect;
432         } else {
433             childrenRect_ = childrenRect_.JoinRect(subRect);
434         }
435     }
436 }
437 
UpdateSubTreeInfo(const RectI & clipRect)438 void RSRenderNode::UpdateSubTreeInfo(const RectI& clipRect)
439 {
440     auto& geoPtr = GetRenderProperties().GetBoundsGeometry();
441     if (geoPtr == nullptr) {
442         return;
443     }
444     lastFrameHasChildrenOutOfRect_ = HasChildrenOutOfRect();
445     oldChildrenRect_ = childrenRect_;
446     oldClipRect_ = clipRect;
447     oldAbsMatrix_ = geoPtr->GetAbsMatrix();
448 }
449 
AddCrossParentChild(const SharedPtr & child,int32_t index)450 void RSRenderNode::AddCrossParentChild(const SharedPtr& child, int32_t index)
451 {
452     // AddCrossParentChild only used as: the child is under multiple parents(e.g. a window cross multi-screens),
453     // so this child will not remove from the old parent.
454     if (child == nullptr) {
455         return;
456     }
457 
458     // Set parent-child relationship
459     child->SetParent(weak_from_this());
460     if (index < 0 || index >= static_cast<int32_t>(children_.size())) {
461         children_.emplace_back(child);
462     } else {
463         children_.emplace(std::next(children_.begin(), index), child);
464     }
465 
466     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
467     // A child is not on the tree until its parent is on the tree
468     if (isOnTheTree_) {
469         child->SetIsOnTheTree(true, instanceRootNodeId_, firstLevelNodeId_, drawingCacheRootId_, uifirstRootNodeId_);
470     }
471     SetContentDirty();
472     isFullChildrenListValid_ = false;
473 }
474 
RemoveCrossParentChild(const SharedPtr & child,const WeakPtr & newParent)475 void RSRenderNode::RemoveCrossParentChild(const SharedPtr& child, const WeakPtr& newParent)
476 {
477     // RemoveCrossParentChild only used as: the child is under multiple parents(e.g. a window cross multi-screens),
478     // set the newParentId to rebuild the parent-child relationship.
479     if (child == nullptr) {
480         return;
481     }
482     // break parent-child relationship
483     auto it = std::find_if(children_.begin(), children_.end(),
484         [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
485     if (it == children_.end()) {
486         return;
487     }
488     // avoid duplicate entry in disappearingChildren_ (this should not happen)
489     disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
490     // if child has disappearing transition, add it to disappearingChildren_
491     if (child->HasDisappearingTransition(true)) {
492         ROSEN_LOGD("RSRenderNode::RemoveChild %{public}" PRIu64 " move child(id %{public}" PRIu64 ")"
493             " into disappearingChildren", GetId(), child->GetId());
494         // keep shared_ptr alive for transition
495         uint32_t origPos = static_cast<uint32_t>(std::distance(children_.begin(), it));
496         disappearingChildren_.emplace_back(child, origPos);
497     } else {
498         child->SetParent(newParent);
499         // attention: set new parent means 'old' parent has removed this child
500         hasRemovedChild_ = true;
501     }
502     children_.erase(it);
503     SetContentDirty();
504     isFullChildrenListValid_ = false;
505 }
506 
RemoveFromTree(bool skipTransition)507 void RSRenderNode::RemoveFromTree(bool skipTransition)
508 {
509     auto parentPtr = parent_.lock();
510     if (parentPtr == nullptr) {
511         return;
512     }
513     auto child = shared_from_this();
514     parentPtr->RemoveChild(child, skipTransition);
515     if (skipTransition == false) {
516         return;
517     }
518     // force remove child from disappearingChildren_ and clean sortChildren_ cache
519     parentPtr->disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
520     parentPtr->isFullChildrenListValid_ = false;
521     child->ResetParent();
522 }
523 
ClearChildren()524 void RSRenderNode::ClearChildren()
525 {
526     if (children_.empty()) {
527         return;
528     }
529     // Cache the parent's transition state to avoid redundant recursively check
530     bool parentHasDisappearingTransition = HasDisappearingTransition(true);
531     uint32_t pos = 0;
532     for (auto& childWeakPtr : children_) {
533         auto child = childWeakPtr.lock();
534         if (child == nullptr) {
535             ++pos;
536             continue;
537         }
538         // avoid duplicate entry in disappearingChildren_ (this should not happen)
539         disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
540         if (parentHasDisappearingTransition || child->HasDisappearingTransition(false)) {
541             // keep shared_ptr alive for transition
542             disappearingChildren_.emplace_back(child, pos);
543         } else {
544             child->ResetParent();
545         }
546         ++pos;
547     }
548     children_.clear();
549     SetContentDirty();
550     isFullChildrenListValid_ = false;
551 }
552 
SetParent(WeakPtr parent)553 void RSRenderNode::SetParent(WeakPtr parent)
554 {
555     AddSubSurfaceUpdateInfo(parent.lock(), parent_.lock());
556     parent_ = parent;
557     if (isSubSurfaceEnabled_) {
558         AddSubSurfaceNode(parent.lock());
559     }
560 }
561 
ResetParent()562 void RSRenderNode::ResetParent()
563 {
564     if (auto parentNode = parent_.lock()) {
565         if (isSubSurfaceEnabled_) {
566             auto it = std::find_if(parentNode->disappearingChildren_.begin(), parentNode->disappearingChildren_.end(),
567                 [childPtr = shared_from_this()](const auto& pair) -> bool { return pair.first == childPtr; });
568             if (it == parentNode->disappearingChildren_.end()) {
569                 RemoveSubSurfaceNode(parentNode);
570             }
571         }
572         parentNode->hasRemovedChild_ = true;
573         parentNode->SetContentDirty();
574         AddSubSurfaceUpdateInfo(nullptr, parentNode);
575     }
576     SetIsOnTheTree(false);
577     parent_.reset();
578     OnResetParent();
579 }
580 
IsFirstLevelNode()581 bool RSRenderNode::IsFirstLevelNode()
582 {
583     return id_ == firstLevelNodeId_;
584 }
585 
AddSubSurfaceNode(SharedPtr parent)586 void RSRenderNode::AddSubSurfaceNode(SharedPtr parent)
587 {
588     if (parent && parent->subSurfaceNodes_.find(GetId()) != parent->subSurfaceNodes_.end()) {
589         return;
590     }
591     std::vector<WeakPtr> subSurfaceNodes;
592     if (IsInstanceOf<RSSurfaceRenderNode>() &&
593         RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(shared_from_this())->IsLeashOrMainWindow()) {
594         subSurfaceNodes.push_back(weak_from_this());
595     } else {
596         for (auto &node : subSurfaceNodes_) {
597             subSurfaceNodes.insert(subSurfaceNodes.end(), node.second.begin(), node.second.end());
598         }
599     }
600     if (subSurfaceNodes.size() == 0) {
601         return;
602     }
603 
604     auto childNode = shared_from_this();
605     auto parentNode = parent;
606     while (parentNode && !parentNode->IsInstanceOf<RSDisplayRenderNode>()) {
607         auto id = childNode->GetId();
608         if (parentNode->subSurfaceNodes_.find(id) == parentNode->subSurfaceNodes_.end()) {
609             parentNode->subSurfaceNodes_.insert({id, subSurfaceNodes});
610         } else {
611             parentNode->subSurfaceNodes_[id].insert(parentNode->subSurfaceNodes_[id].end(),
612                 subSurfaceNodes.begin(), subSurfaceNodes.end());
613         }
614         std::sort(parentNode->subSurfaceNodes_[id].begin(), parentNode->subSurfaceNodes_[id].end(),
615             [](const auto &first, const auto &second) {
616             return
617                 first.lock()->GetRenderProperties().GetPositionZ() <
618                 second.lock()->GetRenderProperties().GetPositionZ();
619         });
620         if (parentNode->IsInstanceOf<RSSurfaceRenderNode>() &&
621             RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentNode)->IsLeashOrMainWindow()) {
622             break;
623         }
624         childNode = parentNode;
625         parentNode = parentNode->GetParent().lock();
626     }
627 }
628 
RemoveSubSurfaceNode(SharedPtr parent)629 void RSRenderNode::RemoveSubSurfaceNode(SharedPtr parent)
630 {
631     if (parent && parent->subSurfaceNodes_.find(GetId()) == parent->subSurfaceNodes_.end()) {
632         return;
633     }
634     auto subSurfaceNodes = parent->subSurfaceNodes_[GetId()];
635     parent->subSurfaceNodes_.erase(GetId());
636     SharedPtr childNode;
637     SharedPtr parentNode = parent;
638     while (parentNode && !parentNode->IsInstanceOf<RSDisplayRenderNode>()) {
639         if (parentNode->IsInstanceOf<RSSurfaceRenderNode>() &&
640             RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentNode)->IsLeashOrMainWindow()) {
641             break;
642         }
643         childNode = parentNode;
644         parentNode = parentNode->GetParent().lock();
645         if (!parentNode) {
646             break;
647         }
648         auto id = childNode->GetId();
649         // If sizes are equal means that parentNode having no other subSurface nodes.
650         if (parentNode->subSurfaceNodes_[id].size() == subSurfaceNodes.size()) {
651             parentNode->subSurfaceNodes_.erase(id);
652         }
653         for (auto &node : subSurfaceNodes) {
654             parentNode->subSurfaceNodes_[id].erase(
655                 remove_if(parentNode->subSurfaceNodes_[id].begin(), parentNode->subSurfaceNodes_[id].end(),
656                     [node](WeakPtr iter) {
657                         return node.lock() && iter.lock() && node.lock()->GetId() == iter.lock()->GetId();
658                     }),
659                 parentNode->subSurfaceNodes_[id].end()
660             );
661         }
662     }
663 }
664 
DumpTree(int32_t depth,std::string & out) const665 void RSRenderNode::DumpTree(int32_t depth, std::string& out) const
666 {
667     for (int32_t i = 0; i < depth; ++i) {
668         out += "  ";
669     }
670     out += "| ";
671     DumpNodeType(GetType(), out);
672     out += "[" + std::to_string(GetId()) + "], instanceRootNodeId" + "[" +
673         std::to_string(GetInstanceRootNodeId()) + "]";
674     if (auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>()) {
675 #if defined(ROSEN_OHOS)
676         if (surfaceNode->GetRSSurfaceHandler() && surfaceNode->GetRSSurfaceHandler()->GetConsumer()) {
677             out +=
678                 ", uniqueId[" + std::to_string(surfaceNode->GetRSSurfaceHandler()->GetConsumer()->GetUniqueId()) + "]";
679         }
680 #endif
681         if (surfaceNode->HasSubSurfaceNodes()) {
682             out += surfaceNode->SubSurfaceNodesDump();
683         }
684         out += ", abilityState: " +
685             std::string(surfaceNode->GetAbilityState() == RSSurfaceNodeAbilityState::FOREGROUND ?
686             "foreground" : "background");
687     }
688     if (sharedTransitionParam_) {
689         out += sharedTransitionParam_->Dump();
690     }
691     if (IsSuggestedDrawInGroup()) {
692         out += ", [nodeGroup" + std::to_string(nodeGroupType_) + "]"; // adapt for SmartPerf Editor tree tool
693     }
694     if (HasChildrenOutOfRect()) {
695         out += ", [ChildrenOutOfParent: true]";
696     }
697     if (uifirstRootNodeId_ != INVALID_NODEID) {
698         out += ", uifirstRootNodeId_: " + std::to_string(uifirstRootNodeId_);
699     }
700     if (HasSubSurface()) {
701         out += ", subSurfaceCnt: " + std::to_string(subSurfaceCnt_);
702     }
703     DumpSubClassNode(out);
704     out += ", Properties: " + GetRenderProperties().Dump();
705     if (GetBootAnimation()) {
706         out += ", GetBootAnimation: true";
707     }
708     if (isContainBootAnimation_) {
709         out += ", isContainBootAnimation: true";
710     }
711     if (dirtyStatus_ != NodeDirty::CLEAN) {
712         out += ", isNodeDirty: " + std::to_string(static_cast<int>(dirtyStatus_));
713     }
714     if (GetRenderProperties().IsDirty()) {
715         out += ", isPropertyDirty: true";
716     }
717     if (isSubTreeDirty_) {
718         out += ", isSubTreeDirty: true";
719     }
720     if (IsPureContainer()) {
721         out += ", IsPureContainer: true";
722     }
723     if (!oldDirty_.IsEmpty()) {
724         out += ", oldDirty: " + oldDirty_.ToString();
725     }
726     if (!localShadowRect_.IsEmpty()) {
727         out += ", localShadowRect: " + localShadowRect_.ToString();
728     }
729     if (!localOutlineRect_.IsEmpty()) {
730         out += ", localOutlineRect: " + localOutlineRect_.ToString();
731     }
732     if (!localPixelStretchRect_.IsEmpty()) {
733         out += ", localPixelStretchRect: " + localPixelStretchRect_.ToString();
734     }
735     if (!localForegroundEffectRect_.IsEmpty()) {
736         out += ", localForegroundEffectRect: " + localForegroundEffectRect_.ToString();
737     }
738     if (auto drawRegion = GetRenderProperties().GetDrawRegion()) {
739         if (!drawRegion->IsEmpty()) {
740             out += ", drawRegion: " + drawRegion->ToString();
741         }
742     }
743     if (drawableVecStatus_ != 0) {
744         out += ", drawableVecStatus: " + std::to_string(drawableVecStatus_);
745     }
746     DumpDrawCmdModifiers(out);
747     DumpModifiers(out);
748     animationManager_.DumpAnimations(out);
749 
750     auto sortedChildren = GetSortedChildren();
751     if (!isFullChildrenListValid_) {
752         out += ", Children list needs update, current count: " + std::to_string(fullChildrenList_->size()) +
753                " expected count: " + std::to_string(sortedChildren->size());
754     } else if (!sortedChildren->empty()) {
755         out += ", sortedChildren: " + std::to_string(sortedChildren->size());
756     }
757     if (!disappearingChildren_.empty()) {
758         out += ", disappearingChildren: " + std::to_string(disappearingChildren_.size());
759     }
760 
761     out += "\n";
762 
763     for (auto& child : children_) {
764         if (auto c = child.lock()) {
765             c->DumpTree(depth + 1, out);
766         }
767     }
768     for (auto& [child, pos] : disappearingChildren_) {
769         child->DumpTree(depth + 1, out);
770     }
771 }
772 
DumpNodeType(RSRenderNodeType nodeType,std::string & out)773 void RSRenderNode::DumpNodeType(RSRenderNodeType nodeType, std::string& out)
774 {
775     switch (nodeType) {
776         case RSRenderNodeType::DISPLAY_NODE: {
777             out += "DISPLAY_NODE";
778             break;
779         }
780         case RSRenderNodeType::RS_NODE: {
781             out += "RS_NODE";
782             break;
783         }
784         case RSRenderNodeType::SURFACE_NODE: {
785             out += "SURFACE_NODE";
786             break;
787         }
788         case RSRenderNodeType::CANVAS_NODE: {
789             out += "CANVAS_NODE";
790             break;
791         }
792         case RSRenderNodeType::ROOT_NODE: {
793             out += "ROOT_NODE";
794             break;
795         }
796         case RSRenderNodeType::PROXY_NODE: {
797             out += "PROXY_NODE";
798             break;
799         }
800         case RSRenderNodeType::CANVAS_DRAWING_NODE: {
801             out += "CANVAS_DRAWING_NODE";
802             break;
803         }
804         case RSRenderNodeType::EFFECT_NODE: {
805             out += "EFFECT_NODE";
806             break;
807         }
808         default: {
809             out += "UNKNOWN_NODE";
810             break;
811         }
812     }
813 }
814 
DumpSubClassNode(std::string & out) const815 void RSRenderNode::DumpSubClassNode(std::string& out) const
816 {
817     if (GetType() == RSRenderNodeType::SURFACE_NODE) {
818         auto surfaceNode = (static_cast<const RSSurfaceRenderNode*>(this));
819         auto p = parent_.lock();
820         out += ", Parent [" + (p != nullptr ? std::to_string(p->GetId()) : "null") + "]";
821         out += ", Name [" + surfaceNode->GetName() + "]";
822         out += ", hasConsumer: " + std::to_string(surfaceNode->GetRSSurfaceHandler()->HasConsumer());
823         std::string propertyAlpha = std::to_string(surfaceNode->GetRenderProperties().GetAlpha());
824         out += ", Alpha: " + propertyAlpha;
825         if (surfaceNode->contextAlpha_ < 1.0f) {
826             std::string contextAlpha = std::to_string(surfaceNode->contextAlpha_);
827             out += " (ContextAlpha: " + contextAlpha + ")";
828         }
829         out += ", Visible: " + std::to_string(surfaceNode->GetRenderProperties().GetVisible());
830         out += ", Visible" + surfaceNode->GetVisibleRegion().GetRegionInfo();
831         out += ", Opaque" + surfaceNode->GetOpaqueRegion().GetRegionInfo();
832         out += ", OcclusionBg: " + std::to_string(surfaceNode->GetAbilityBgAlpha());
833         out += ", SecurityLayer: " + std::to_string(surfaceNode->GetSecurityLayer());
834         out += ", skipLayer: " + std::to_string(surfaceNode->GetSkipLayer());
835         out += ", surfaceType: " + std::to_string((int)surfaceNode->GetSurfaceNodeType());
836     } else if (GetType() == RSRenderNodeType::ROOT_NODE) {
837         auto rootNode = static_cast<const RSRootRenderNode*>(this);
838         out += ", Visible: " + std::to_string(rootNode->GetRenderProperties().GetVisible());
839         out += ", Size: [" + std::to_string(rootNode->GetRenderProperties().GetFrameWidth()) + ", " +
840             std::to_string(rootNode->GetRenderProperties().GetFrameHeight()) + "]";
841         out += ", EnableRender: " + std::to_string(rootNode->GetEnableRender());
842     } else if (GetType() == RSRenderNodeType::DISPLAY_NODE) {
843         auto displayNode = static_cast<const RSDisplayRenderNode*>(this);
844         out += ", skipLayer: " + std::to_string(displayNode->GetSecurityDisplay());
845         out += ", securityExemption: " + std::to_string(displayNode->GetSecurityExemption());
846     }
847 }
848 
DumpDrawCmdModifiers(std::string & out) const849 void RSRenderNode::DumpDrawCmdModifiers(std::string& out) const
850 {
851     if (renderContent_->drawCmdModifiers_.empty()) {
852         return;
853     }
854     std::string splitStr = ", ";
855     std::string modifierDesc = ", DrawCmdModifiers:[";
856     for (auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
857         auto modifierTypeString = std::make_shared<RSModifierTypeString>();
858         std::string typeName = modifierTypeString->GetModifierTypeString(type);
859         modifierDesc += typeName + ":[";
860         std::string propertyDesc = "";
861         for (auto& modifier : modifiers) {
862             modifier->Dump(propertyDesc);
863             propertyDesc += splitStr;
864         }
865         modifierDesc += propertyDesc.substr(0, propertyDesc.length() - splitStr.length()) + "]" + splitStr;
866     }
867     out += modifierDesc.substr(0, modifierDesc.length() - splitStr.length()) + "]";
868 }
869 
DumpModifiers(std::string & out) const870 void RSRenderNode::DumpModifiers(std::string& out) const
871 {
872     if (modifiers_.empty()) {
873         return;
874     }
875     std::string splitStr = ", ";
876     out += ", OtherModifiers:[";
877     std::string propertyDesc = "";
878     for (auto& [type, modifier] : modifiers_) {
879         propertyDesc += modifier->GetModifierTypeString();
880         modifier->Dump(propertyDesc);
881         propertyDesc += splitStr;
882     }
883     out += propertyDesc.substr(0, propertyDesc.length() - splitStr.length()) + "]";
884 }
885 
ResetIsOnlyBasicGeoTransform()886 void RSRenderNode::ResetIsOnlyBasicGeoTransform()
887 {
888     isOnlyBasicGeoTransform_ = true;
889 }
890 
IsOnlyBasicGeoTransform() const891 bool RSRenderNode::IsOnlyBasicGeoTransform() const
892 {
893     return isOnlyBasicGeoTransform_;
894 }
895 
ForceMergeSubTreeDirtyRegion(RSDirtyRegionManager & dirtyManager,const RectI & clipRect)896 void RSRenderNode::ForceMergeSubTreeDirtyRegion(RSDirtyRegionManager& dirtyManager, const RectI& clipRect)
897 {
898     // prepare skip -> quick prepare, old dirty do not update
899     if (geoUpdateDelay_) {
900         if (auto& geoPtr = GetRenderProperties().GetBoundsGeometry()) {
901             auto absChildrenRect = geoPtr->MapRect(oldChildrenRect_.ConvertTo<float>(), oldAbsMatrix_);
902             subTreeDirtyRegion_ = absChildrenRect.IntersectRect(oldClipRect_);
903             dirtyManager.MergeDirtyRect(subTreeDirtyRegion_);
904         }
905     }
906     lastFrameSubTreeSkipped_ = false;
907 }
908 
SubTreeSkipPrepare(RSDirtyRegionManager & dirtyManager,bool isDirty,bool accumGeoDirty,const RectI & clipRect)909 void RSRenderNode::SubTreeSkipPrepare(
910     RSDirtyRegionManager& dirtyManager, bool isDirty, bool accumGeoDirty, const RectI& clipRect)
911 {
912     // [planning] Prev and current dirty rect need to be joined only when accumGeoDirty is true.
913     if ((isDirty || accumGeoDirty) && (HasChildrenOutOfRect() || lastFrameHasChildrenOutOfRect_)) {
914         auto& geoPtr = GetRenderProperties().GetBoundsGeometry();
915         if (geoPtr == nullptr) {
916             return;
917         }
918         auto oldDirtyRect = geoPtr->MapRect(oldChildrenRect_.ConvertTo<float>(), oldAbsMatrix_);
919         auto oldDirtyRectClip = oldDirtyRect.IntersectRect(oldClipRect_);
920         auto dirtyRect = geoPtr->MapAbsRect(childrenRect_.ConvertTo<float>());
921         auto dirtyRectClip = dirtyRect.IntersectRect(clipRect);
922         dirtyRectClip = dirtyRectClip.JoinRect(oldDirtyRectClip);
923         dirtyManager.MergeDirtyRect(dirtyRectClip);
924         UpdateSubTreeSkipDirtyForDFX(dirtyManager, dirtyRectClip);
925     }
926     if (isDirty && GetChildrenCount() == 0) {
927         ResetChildRelevantFlags();
928     }
929     SetGeoUpdateDelay(accumGeoDirty);
930     UpdateSubTreeInfo(clipRect);
931     lastFrameSubTreeSkipped_ = true;
932 }
933 
934 // attention: current all base node's dirty ops causing content dirty
SetContentDirty()935 void RSRenderNode::SetContentDirty()
936 {
937     isContentDirty_ = true;
938     isOnlyBasicGeoTransform_ = false;
939     SetDirty();
940 }
941 
SetDirty(bool forceAddToActiveList)942 void RSRenderNode::SetDirty(bool forceAddToActiveList)
943 {
944     bool dirtyEmpty = dirtyTypes_.none();
945     // TO avoid redundant add, only add if both: 1. on-tree node 2. newly dirty node (or forceAddToActiveList = true)
946     if (dirtyStatus_ == NodeDirty::CLEAN || dirtyEmpty || forceAddToActiveList) {
947         if (auto context = GetContext().lock()) {
948             context->AddActiveNode(shared_from_this());
949         }
950     }
951     SetParentSubTreeDirty();
952     dirtyStatus_ = NodeDirty::DIRTY;
953 }
954 
CollectSurface(const std::shared_ptr<RSRenderNode> & node,std::vector<RSRenderNode::SharedPtr> & vec,bool isUniRender,bool onlyFirstLevel)955 void RSRenderNode::CollectSurface(
956     const std::shared_ptr<RSRenderNode>& node, std::vector<RSRenderNode::SharedPtr>& vec, bool isUniRender,
957     bool onlyFirstLevel)
958 {
959     for (auto& child : *node->GetSortedChildren()) {
960         child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
961     }
962 }
963 
CollectSurfaceForUIFirstSwitch(uint32_t & leashWindowCount,uint32_t minNodeNum)964 void RSRenderNode::CollectSurfaceForUIFirstSwitch(uint32_t& leashWindowCount, uint32_t minNodeNum)
965 {
966     for (auto& child : *GetSortedChildren()) {
967         child->CollectSurfaceForUIFirstSwitch(leashWindowCount, minNodeNum);
968         if (leashWindowCount >= minNodeNum) {
969             return;
970         }
971     }
972 }
973 
Prepare(const std::shared_ptr<RSNodeVisitor> & visitor)974 void RSRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
975 {
976     if (!visitor) {
977         return;
978     }
979     ApplyModifiers();
980     visitor->PrepareChildren(*this);
981 }
982 
QuickPrepare(const std::shared_ptr<RSNodeVisitor> & visitor)983 void RSRenderNode::QuickPrepare(const std::shared_ptr<RSNodeVisitor>& visitor)
984 {
985     if (!visitor) {
986         return;
987     }
988     ApplyModifiers();
989     visitor->QuickPrepareChildren(*this);
990 
991     // fallback for global root node
992     UpdateRenderParams();
993     AddToPendingSyncList();
994 }
995 
IsSubTreeNeedPrepare(bool filterInGlobal,bool isOccluded)996 bool RSRenderNode::IsSubTreeNeedPrepare(bool filterInGlobal, bool isOccluded)
997 {
998     auto checkType = RSSystemProperties::GetSubTreePrepareCheckType();
999     if (checkType == SubTreePrepareCheckType::DISABLED) {
1000         return true;
1001     }
1002     // stop visit invisible or clean without filter subtree
1003     if (!shouldPaint_ || isOccluded) {
1004         // when subTreeOccluded, need to applyModifiers to node's children
1005         RS_OPTIONAL_TRACE_NAME_FMT("IsSubTreeNeedPrepare node[%llu] skip subtree ShouldPaint %d, isOccluded %d",
1006             GetId(), shouldPaint_, isOccluded);
1007         return false;
1008     }
1009     if (checkType == SubTreePrepareCheckType::DISABLE_SUBTREE_DIRTY_CHECK) {
1010         return true;
1011     }
1012     if (IsSubTreeDirty()) {
1013         // reset iff traverses dirty subtree
1014         SetSubTreeDirty(false);
1015         UpdateChildrenOutOfRectFlag(false); // collect again
1016         return true;
1017     }
1018     if (childHasSharedTransition_) {
1019         return true;
1020     }
1021     if (isAccumulatedClipFlagChanged_) {
1022         return true;
1023     }
1024     if (ChildHasVisibleFilter()) {
1025         RS_OPTIONAL_TRACE_NAME_FMT("IsSubTreeNeedPrepare node[%d] filterInGlobal_[%d]",
1026             GetId(), filterInGlobal);
1027     }
1028     // if clean without filter skip subtree
1029     return ChildHasVisibleFilter() ? filterInGlobal : false;
1030 }
1031 
PrepareChildrenForApplyModifiers()1032 void RSRenderNode::PrepareChildrenForApplyModifiers()
1033 {
1034     auto children = GetSortedChildren();
1035     std::for_each((*children).begin(), (*children).end(),
1036         [this](const std::shared_ptr<RSRenderNode>& node) {
1037         node->PrepareSelfNodeForApplyModifiers();
1038     });
1039 }
1040 
PrepareSelfNodeForApplyModifiers()1041 void RSRenderNode::PrepareSelfNodeForApplyModifiers()
1042 {
1043     ApplyModifiers();
1044     PrepareChildrenForApplyModifiers();
1045 
1046     stagingRenderParams_->SetAlpha(GetRenderProperties().GetAlpha());
1047 
1048     UpdateRenderParams();
1049     AddToPendingSyncList();
1050 }
1051 
IsUifirstArkTsCardNode()1052 bool RSRenderNode::IsUifirstArkTsCardNode()
1053 {
1054     if (nodeGroupType_ == NodeGroupType::NONE) {
1055         return false;
1056     }
1057     for (auto& child : *GetChildren()) {
1058         if (!child) {
1059             continue;
1060         }
1061         auto surfaceChild = child->ReinterpretCastTo<RSSurfaceRenderNode>();
1062         if (!surfaceChild) {
1063             continue;
1064         }
1065         if (surfaceChild->GetLastFrameUifirstFlag() == MultiThreadCacheType::ARKTS_CARD) {
1066             return true;
1067         }
1068     }
1069     return false;
1070 }
1071 
UpdateDrawingCacheInfoBeforeChildren(bool isScreenRotation)1072 void RSRenderNode::UpdateDrawingCacheInfoBeforeChildren(bool isScreenRotation)
1073 {
1074     if (!ShouldPaint() || isScreenRotation) {
1075         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
1076         return;
1077     }
1078     CheckDrawingCacheType();
1079     if (GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE) {
1080         RS_LOGD("RSRenderNode::UpdateDrawingCacheInfoBC drawingCacheType is %{public}d", GetDrawingCacheType());
1081         return;
1082     }
1083     RS_OPTIONAL_TRACE_NAME_FMT("DrawingCacheInfo id:%llu contentDirty:%d subTreeDirty:%d nodeGroupType:%d",
1084         GetId(), IsContentDirty(), IsSubTreeDirty(), nodeGroupType_);
1085     SetDrawingCacheChanged((IsContentDirty() || IsSubTreeDirty()));
1086     stagingRenderParams_->SetDrawingCacheIncludeProperty(nodeGroupIncludeProperty_);
1087 }
1088 
UpdateDrawingCacheInfoAfterChildren()1089 void RSRenderNode::UpdateDrawingCacheInfoAfterChildren()
1090 {
1091     RS_LOGI_IF(DEBUG_NODE, "RSRenderNode::UpdateDrawingCacheInfoAC uifirstArkTsCardNode:%{public}d"
1092         " startingWindowFlag_:%{public}d HasChildrenOutOfRect:%{public}d drawingCacheType:%{public}d",
1093         IsUifirstArkTsCardNode(), startingWindowFlag_, HasChildrenOutOfRect(), GetDrawingCacheType());
1094     if (IsUifirstArkTsCardNode() || startingWindowFlag_) {
1095         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
1096     }
1097     if (HasChildrenOutOfRect() && GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
1098         RS_OPTIONAL_TRACE_NAME_FMT("DrawingCacheInfoAfter ChildrenOutOfRect id:%llu", GetId());
1099         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
1100     }
1101     stagingRenderParams_->SetDrawingCacheType(GetDrawingCacheType());
1102     if (GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE) {
1103         RS_OPTIONAL_TRACE_NAME_FMT("DrawingCacheInfoAfter id:%llu cacheType:%d childHasVisibleFilter:%d " \
1104             "childHasVisibleEffect:%d",
1105             GetId(), GetDrawingCacheType(), childHasVisibleFilter_, childHasVisibleEffect_);
1106     }
1107     AddToPendingSyncList();
1108 }
1109 
Process(const std::shared_ptr<RSNodeVisitor> & visitor)1110 void RSRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
1111 {
1112     if (!visitor) {
1113         return;
1114     }
1115     visitor->ProcessChildren(*this);
1116 }
1117 
SendCommandFromRT(std::unique_ptr<RSCommand> & command,NodeId nodeId)1118 void RSRenderNode::SendCommandFromRT(std::unique_ptr<RSCommand>& command, NodeId nodeId)
1119 {
1120     auto transactionProxy = RSTransactionProxy::GetInstance();
1121     if (transactionProxy != nullptr) {
1122         transactionProxy->AddCommandFromRT(command, nodeId);
1123     }
1124 }
1125 
InternalRemoveSelfFromDisappearingChildren()1126 void RSRenderNode::InternalRemoveSelfFromDisappearingChildren()
1127 {
1128     // internal use only, force remove self from parent's disappearingChildren_
1129     auto parent = parent_.lock();
1130     if (parent == nullptr) {
1131         return;
1132     }
1133     auto it = std::find_if(parent->disappearingChildren_.begin(), parent->disappearingChildren_.end(),
1134         [childPtr = shared_from_this()](const auto& pair) -> bool { return pair.first == childPtr; });
1135     if (it == parent->disappearingChildren_.end()) {
1136         return;
1137     }
1138     parent->disappearingChildren_.erase(it);
1139     parent->isFullChildrenListValid_ = false;
1140     ResetParent();
1141 }
1142 
~RSRenderNode()1143 RSRenderNode::~RSRenderNode()
1144 {
1145     if (appPid_ != 0) {
1146         RSSingleFrameComposer::AddOrRemoveAppPidToMap(false, appPid_);
1147     }
1148     FallbackAnimationsToRoot();
1149     if (clearCacheSurfaceFunc_ && (cacheSurface_ || cacheCompletedSurface_)) {
1150         clearCacheSurfaceFunc_(std::move(cacheSurface_), std::move(cacheCompletedSurface_), cacheSurfaceThreadIndex_,
1151             completedSurfaceThreadIndex_);
1152     }
1153     DrawableV2::RSRenderNodeDrawableAdapter::RemoveDrawableFromCache(GetId());
1154     ClearCacheSurface();
1155     auto context = GetContext().lock();
1156     if (!context) {
1157         ROSEN_LOGD("RSRenderNode::~RSRenderNode: Invalid context");
1158         return;
1159     }
1160 }
1161 
FallbackAnimationsToRoot()1162 void RSRenderNode::FallbackAnimationsToRoot()
1163 {
1164     if (animationManager_.animations_.empty()) {
1165         return;
1166     }
1167 
1168     auto context = GetContext().lock();
1169     if (!context) {
1170         ROSEN_LOGE("RSRenderNode::FallbackAnimationsToRoot: Invalid context");
1171         return;
1172     }
1173     auto target = context->GetNodeMap().GetAnimationFallbackNode();
1174     if (!target) {
1175         ROSEN_LOGE("Failed to move animation to root, root render node is null!");
1176         return;
1177     }
1178     context->RegisterAnimatingRenderNode(target);
1179 
1180     for (auto& [unused, animation] : animationManager_.animations_) {
1181         animation->Detach(true);
1182         // avoid infinite loop for fallback animation
1183         animation->SetRepeatCount(1);
1184         target->animationManager_.AddAnimation(std::move(animation));
1185     }
1186     animationManager_.animations_.clear();
1187     // Check the next frame's VSync has been requested. If there is no request, add another VSync request
1188     if (!context->IsRequestedNextVsyncAnimate()) {
1189         context->RequestVsync();
1190         context->SetRequestedNextVsyncAnimate(true);
1191     }
1192 }
1193 
ActivateDisplaySync()1194 void RSRenderNode::ActivateDisplaySync()
1195 {
1196     if (!displaySync_) {
1197         displaySync_ = std::make_shared<RSRenderDisplaySync>(GetId());
1198     }
1199 }
1200 
UpdateDisplaySyncRange()1201 void RSRenderNode::UpdateDisplaySyncRange()
1202 {
1203     if (!displaySync_) {
1204         return;
1205     }
1206     auto animationRange = animationManager_.GetFrameRateRange();
1207     if (animationRange.IsValid()) {
1208         displaySync_->SetExpectedFrameRateRange(animationRange);
1209     }
1210 }
1211 
Animate(int64_t timestamp,int64_t period,bool isDisplaySyncEnabled)1212 std::tuple<bool, bool, bool> RSRenderNode::Animate(int64_t timestamp, int64_t period, bool isDisplaySyncEnabled)
1213 {
1214     if (displaySync_ && displaySync_->OnFrameSkip(timestamp, period, isDisplaySyncEnabled)) {
1215         return displaySync_->GetAnimateResult();
1216     }
1217     RSSurfaceNodeAbilityState abilityState = RSSurfaceNodeAbilityState::FOREGROUND;
1218 
1219     // Animation on surfaceNode is always on foreground ability state.
1220     // If instanceRootNode is surfaceNode, get its ability state. If not, regard it as foreground ability state.
1221     if (GetType() != RSRenderNodeType::SURFACE_NODE) {
1222         if (auto instanceRootNode = GetInstanceRootNode()) {
1223             abilityState = instanceRootNode->GetAbilityState();
1224             RS_OPTIONAL_TRACE_NAME("RSRenderNode:Animate node id: [" + std::to_string(GetId()) +
1225                 "], instanceRootNode id: [" + std::to_string(instanceRootNode->GetId()) +
1226                 "], abilityState: " +
1227                 std::string(abilityState == RSSurfaceNodeAbilityState::FOREGROUND ? "foreground" : "background"));
1228         }
1229     } else {
1230         RS_OPTIONAL_TRACE_NAME("RSRenderNode:Animate surfaceNode id: [" + std::to_string(GetId()) +
1231             "], abilityState: " +
1232             std::string(GetAbilityState() == RSSurfaceNodeAbilityState::FOREGROUND ? "foreground" : "background"));
1233     }
1234 
1235     RS_OPTIONAL_TRACE_BEGIN("RSRenderNode:Animate node id: [" + std::to_string(GetId()) + "]");
1236     auto animateResult = animationManager_.Animate(timestamp, IsOnTheTree(), abilityState);
1237     if (displaySync_) {
1238         displaySync_->SetAnimateResult(animateResult);
1239     }
1240     RS_OPTIONAL_TRACE_END();
1241     return animateResult;
1242 }
1243 
IsClipBound() const1244 bool RSRenderNode::IsClipBound() const
1245 {
1246     return GetRenderProperties().GetClipToBounds() || GetRenderProperties().GetClipToFrame();
1247 }
1248 
SetAccumulatedClipFlag(bool clipChange)1249 bool RSRenderNode::SetAccumulatedClipFlag(bool clipChange)
1250 {
1251     isAccumulatedClipFlagChanged_ = (hasAccumulatedClipFlag_ != IsClipBound()) || clipChange;
1252     if (isAccumulatedClipFlagChanged_) {
1253         hasAccumulatedClipFlag_ = IsClipBound();
1254     }
1255     return isAccumulatedClipFlagChanged_;
1256 }
1257 
GetStagingRenderParams()1258 std::unique_ptr<RSRenderParams>& RSRenderNode::GetStagingRenderParams()
1259 {
1260     return stagingRenderParams_;
1261 }
1262 
1263 // Deprecated! Do not use this interface.
1264 // This interface has crash risks and will be deleted in later versions.
GetRenderParams() const1265 const std::unique_ptr<RSRenderParams>& RSRenderNode::GetRenderParams() const
1266 {
1267     if (renderDrawable_ == nullptr) {
1268         DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(shared_from_this());
1269     }
1270     return renderDrawable_->renderParams_;
1271 }
1272 
CollectAndUpdateLocalShadowRect()1273 void RSRenderNode::CollectAndUpdateLocalShadowRect()
1274 {
1275     // update shadow if shadow changes
1276     if (dirtySlots_.find(RSDrawableSlot::SHADOW) != dirtySlots_.end()) {
1277         auto& properties = GetRenderProperties();
1278         if (properties.IsShadowValid()) {
1279             SetShadowValidLastFrame(true);
1280             if (IsInstanceOf<RSSurfaceRenderNode>()) {
1281                 RRect absClipRRect = RRect(properties.GetBoundsRect(), properties.GetCornerRadius());
1282                 RSPropertiesPainter::GetShadowDirtyRect(localShadowRect_, properties, &absClipRRect, false, true);
1283             } else {
1284                 RSPropertiesPainter::GetShadowDirtyRect(localShadowRect_, properties, nullptr, false, true);
1285             }
1286         }
1287     }
1288     selfDrawRect_ = selfDrawRect_.JoinRect(localShadowRect_.ConvertTo<float>());
1289 }
1290 
CollectAndUpdateLocalOutlineRect()1291 void RSRenderNode::CollectAndUpdateLocalOutlineRect()
1292 {
1293     // update outline if oueline changes
1294     if (dirtySlots_.find(RSDrawableSlot::OUTLINE) != dirtySlots_.end()) {
1295         RSPropertiesPainter::GetOutlineDirtyRect(localOutlineRect_, GetRenderProperties(), false);
1296     }
1297     selfDrawRect_ = selfDrawRect_.JoinRect(localOutlineRect_.ConvertTo<float>());
1298 }
1299 
CollectAndUpdateLocalPixelStretchRect()1300 void RSRenderNode::CollectAndUpdateLocalPixelStretchRect()
1301 {
1302     // update outline if oueline changes
1303     if (dirtySlots_.find(RSDrawableSlot::PIXEL_STRETCH) != dirtySlots_.end()) {
1304         RSPropertiesPainter::GetPixelStretchDirtyRect(localPixelStretchRect_, GetRenderProperties(), false);
1305     }
1306     selfDrawRect_ = selfDrawRect_.JoinRect(localPixelStretchRect_.ConvertTo<float>());
1307 }
1308 
CollectAndUpdateLocalForegroundEffectRect()1309 void RSRenderNode::CollectAndUpdateLocalForegroundEffectRect()
1310 {
1311     // update foreground effect's dirty region if it changes
1312     if (GetRenderProperties().GetForegroundEffectDirty()) {
1313         RSPropertiesPainter::GetForegroundEffectDirtyRect(localForegroundEffectRect_, GetRenderProperties(), false);
1314         GetMutableRenderProperties().SetForegroundEffectDirty(false);
1315     }
1316     selfDrawRect_ = selfDrawRect_.JoinRect(localForegroundEffectRect_.ConvertTo<float>());
1317 }
1318 
CollectAndUpdateLocalDistortionEffectRect()1319 void RSRenderNode::CollectAndUpdateLocalDistortionEffectRect()
1320 {
1321     // update distortion effect's dirty region if it changes
1322     if (GetRenderProperties().GetDistortionDirty()) {
1323         RSPropertiesPainter::GetDistortionEffectDirtyRect(localDistortionEffectRect_, GetRenderProperties());
1324         GetMutableRenderProperties().SetDistortionDirty(false);
1325     }
1326     selfDrawRect_ = selfDrawRect_.JoinRect(localDistortionEffectRect_.ConvertTo<float>());
1327 }
1328 
UpdateBufferDirtyRegion()1329 void RSRenderNode::UpdateBufferDirtyRegion()
1330 {
1331 #ifndef ROSEN_CROSS_PLATFORM
1332     isSelfDrawingNode_ = false;
1333     if (GetType() != RSRenderNodeType::SURFACE_NODE) {
1334         return;
1335     }
1336     auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
1337     if (surfaceNode == nullptr) {
1338         return;
1339     }
1340     auto buffer = surfaceNode->GetRSSurfaceHandler()->GetBuffer();
1341     if (buffer != nullptr) {
1342         isSelfDrawingNode_ = true;
1343         // Use the matrix from buffer to relative coordinate and the absolute matrix
1344         // to calculate the buffer damageRegion's absolute rect
1345         auto rect = surfaceNode->GetRSSurfaceHandler()->GetDamageRegion();
1346         auto matrix = surfaceNode->GetBufferRelMatrix();
1347         auto bufferDirtyRect = GetRenderProperties().GetBoundsGeometry()->MapRect(
1348             RectF(rect.x, rect.y, rect.w, rect.h), matrix).ConvertTo<float>();
1349         // The buffer's dirtyRect should not be out of the scope of the node's dirtyRect
1350         selfDrawingNodeDirtyRect_ = bufferDirtyRect.IntersectRect(selfDrawRect_);
1351         RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode id: %" PRIu64 ", buffer size [%d,%d], "
1352             "buffer damageRegion [%d,%d,%d,%d], dirtyRect %s", GetId(),
1353             buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(),
1354             rect.x, rect.y, rect.w, rect.h, selfDrawingNodeDirtyRect_.ToString().c_str());
1355     }
1356 #endif
1357 }
1358 
UpdateSelfDrawRect()1359 bool RSRenderNode::UpdateSelfDrawRect()
1360 {
1361     auto prevSelfDrawRect = selfDrawRect_;
1362     // empty rect would not join and doesn't need to check
1363     auto& properties = GetRenderProperties();
1364     selfDrawRect_ = properties.GetLocalBoundsAndFramesRect();
1365     UpdateBufferDirtyRegion();
1366     if (auto drawRegion = properties.GetDrawRegion()) {
1367         selfDrawRect_ = selfDrawRect_.JoinRect(*drawRegion);
1368     }
1369     CollectAndUpdateLocalShadowRect();
1370     CollectAndUpdateLocalOutlineRect();
1371     CollectAndUpdateLocalPixelStretchRect();
1372     CollectAndUpdateLocalForegroundEffectRect();
1373     CollectAndUpdateLocalDistortionEffectRect();
1374     return !selfDrawRect_.IsNearEqual(prevSelfDrawRect);
1375 }
1376 
GetSelfDrawRect() const1377 const RectF& RSRenderNode::GetSelfDrawRect() const
1378 {
1379     return selfDrawRect_;
1380 }
1381 
GetAbsDrawRect() const1382 const RectI& RSRenderNode::GetAbsDrawRect() const
1383 {
1384     return absDrawRect_;
1385 }
1386 
CheckAndUpdateGeoTrans(std::shared_ptr<RSObjAbsGeometry> & geoPtr)1387 bool RSRenderNode::CheckAndUpdateGeoTrans(std::shared_ptr<RSObjAbsGeometry>& geoPtr)
1388 {
1389     if (!renderContent_->drawCmdModifiers_.count(RSModifierType::GEOMETRYTRANS)) {
1390         return false;
1391     }
1392     RSModifierContext context = { GetMutableRenderProperties() };
1393     for (auto& modifier : renderContent_->drawCmdModifiers_[RSModifierType::GEOMETRYTRANS]) {
1394         // todo Concat matrix directly
1395         modifier->Apply(context);
1396     }
1397     return true;
1398 }
1399 
UpdateAbsDirtyRegion(RSDirtyRegionManager & dirtyManager,const RectI & clipRect)1400 void RSRenderNode::UpdateAbsDirtyRegion(RSDirtyRegionManager& dirtyManager, const RectI& clipRect)
1401 {
1402     dirtyManager.MergeDirtyRect(oldDirty_);
1403     if (absDrawRect_ != oldAbsDrawRect_) {
1404         if (isSelfDrawingNode_) {
1405             // merge self drawing node last frame size and join current frame size to absDrawRect_ when changed
1406             dirtyManager.MergeDirtyRect(oldAbsDrawRect_.IntersectRect(clipRect));
1407             selfDrawingNodeAbsDirtyRect_.JoinRect(absDrawRect_);
1408         }
1409         oldAbsDrawRect_ = absDrawRect_;
1410     }
1411     // easily merge oldDirty if switch to invisible
1412     if (!shouldPaint_ && isLastVisible_) {
1413         return;
1414     }
1415     auto dirtyRect = isSelfDrawingNode_ ? selfDrawingNodeAbsDirtyRect_ : absDrawRect_;
1416     dirtyRect = dirtyRect.IntersectRect(clipRect);
1417     oldDirty_ = dirtyRect;
1418     oldDirtyInSurface_ = oldDirty_.IntersectRect(dirtyManager.GetSurfaceRect());
1419     if (!dirtyRect.IsEmpty()) {
1420         dirtyManager.MergeDirtyRect(dirtyRect);
1421         isDirtyRegionUpdated_ = true;
1422     }
1423 }
1424 
UpdateDrawRectAndDirtyRegion(RSDirtyRegionManager & dirtyManager,bool accumGeoDirty,const RectI & clipRect,const Drawing::Matrix & parentSurfaceMatrix)1425 bool RSRenderNode::UpdateDrawRectAndDirtyRegion(RSDirtyRegionManager& dirtyManager, bool accumGeoDirty,
1426     const RectI& clipRect, const Drawing::Matrix& parentSurfaceMatrix)
1427 {
1428     bool selfDrawRectChanged = false;
1429     // 1. update self drawrect if dirty
1430     if (IsDirty()) {
1431         selfDrawRectChanged = UpdateSelfDrawRect();
1432     }
1433     // 2. update geoMatrix by parent for dirty collection
1434     // update geoMatrix and accumGeoDirty if needed
1435     auto parent = GetParent().lock();
1436     if (parent && parent->GetGeoUpdateDelay()) {
1437         accumGeoDirty = true;
1438         // Set geometry update delay flag recursively to update node's old dirty in subTree
1439         SetGeoUpdateDelay(true);
1440     }
1441     auto& properties = GetMutableRenderProperties();
1442     if (accumGeoDirty || properties.NeedClip() || properties.geoDirty_ || (dirtyStatus_ != NodeDirty::CLEAN)) {
1443         UpdateDrawRect(accumGeoDirty, clipRect, parentSurfaceMatrix);
1444         // planning: double check if it would be covered by updateself without geo update
1445         // currently CheckAndUpdateGeoTrans without dirty check
1446         auto& geoPtr = properties.boundsGeo_;
1447         // selfdrawing node's geo may not dirty when its dirty region changes
1448         if (geoPtr && (CheckAndUpdateGeoTrans(geoPtr) || accumGeoDirty || properties.geoDirty_ ||
1449             isSelfDrawingNode_ || selfDrawRectChanged)) {
1450             absDrawRect_ = geoPtr->MapAbsRect(selfDrawRect_);
1451             if (isSelfDrawingNode_) {
1452                 selfDrawingNodeAbsDirtyRect_ = geoPtr->MapAbsRect(selfDrawingNodeDirtyRect_);
1453             }
1454             UpdateSrcOrClipedAbsDrawRectChangeState(clipRect);
1455         }
1456     }
1457     // 3. update dirtyRegion if needed
1458     if (properties.GetBackgroundFilter()) {
1459         UpdateFilterCacheWithBelowDirty(dirtyManager);
1460     }
1461     ValidateLightResources();
1462     isDirtyRegionUpdated_ = false; // todo make sure why windowDirty use it
1463     // Only when satisfy following conditions, absDirtyRegion should update:
1464     // 1.The node is dirty; 2.The clip absDrawRect change; 3.Parent clip property change or has GeoUpdateDelay dirty;
1465     if ((IsDirty() || srcOrClipedAbsDrawRectChangeFlag_ || (parent && (parent->GetAccumulatedClipFlagChange() ||
1466         parent->GetGeoUpdateDelay()))) && (shouldPaint_ || isLastVisible_)) {
1467         // update ForegroundFilterCache
1468         UpdateAbsDirtyRegion(dirtyManager, clipRect);
1469         UpdateDirtyRegionInfoForDFX(dirtyManager);
1470     }
1471     // 4. reset dirty status
1472     RecordCurDirtyStatus();
1473     SetClean();
1474     properties.ResetDirty();
1475     isLastVisible_ = shouldPaint_;
1476     return accumGeoDirty;
1477 }
1478 
UpdateDrawRect(bool & accumGeoDirty,const RectI & clipRect,const Drawing::Matrix & parentSurfaceMatrix)1479 void RSRenderNode::UpdateDrawRect(
1480     bool& accumGeoDirty, const RectI& clipRect, const Drawing::Matrix& parentSurfaceMatrix)
1481 {
1482     auto parent = GetParent().lock();
1483     auto& properties = GetMutableRenderProperties();
1484     if (auto sandbox = properties.GetSandBox(); sandbox.has_value() && sharedTransitionParam_) {
1485         // case a. use parent sur_face matrix with sandbox
1486         auto translateMatrix = Drawing::Matrix();
1487         translateMatrix.Translate(sandbox->x_, sandbox->y_);
1488         properties.GetBoundsGeometry()->SetContextMatrix(translateMatrix);
1489         accumGeoDirty = properties.UpdateGeometryByParent(&parentSurfaceMatrix, std::nullopt) || accumGeoDirty;
1490         properties.GetBoundsGeometry()->SetContextMatrix(std::nullopt);
1491     } else if (parent != nullptr) {
1492         // case b. use parent matrix
1493         auto parentMatrix = &(parent->GetRenderProperties().GetBoundsGeometry()->GetAbsMatrix());
1494         auto offset = !IsInstanceOf<RSSurfaceRenderNode>()
1495                           ? std::make_optional<Drawing::Point>(parent->GetRenderProperties().GetFrameOffsetX(),
1496                                 parent->GetRenderProperties().GetFrameOffsetY())
1497                           : std::nullopt;
1498         accumGeoDirty = properties.UpdateGeometryByParent(parentMatrix, offset) || accumGeoDirty;
1499     } else {
1500         // case c. no parent
1501         accumGeoDirty = properties.UpdateGeometryByParent(nullptr, std::nullopt) || accumGeoDirty;
1502     }
1503 }
1504 
UpdateDirtyRegionInfoForDFX(RSDirtyRegionManager & dirtyManager)1505 void RSRenderNode::UpdateDirtyRegionInfoForDFX(RSDirtyRegionManager& dirtyManager)
1506 {
1507     if (RSSystemProperties::GetDirtyRegionDebugType() == DirtyRegionDebugType::DISABLED) {
1508         return;
1509     }
1510     // update OVERLAY_RECT
1511     auto& properties = GetRenderProperties();
1512     if (auto drawRegion = properties.GetDrawRegion()) {
1513         if (auto& geoPtr = properties.GetBoundsGeometry()) {
1514             dirtyManager.UpdateDirtyRegionInfoForDfx(
1515                 GetId(), GetType(), DirtyRegionType::OVERLAY_RECT, geoPtr->MapAbsRect(*drawRegion));
1516         }
1517     } else {
1518         dirtyManager.UpdateDirtyRegionInfoForDfx(
1519             GetId(), GetType(), DirtyRegionType::OVERLAY_RECT, RectI());
1520     }
1521     // update UPDATE_DIRTY_REGION
1522     dirtyManager.UpdateDirtyRegionInfoForDfx(
1523         GetId(), GetType(), DirtyRegionType::UPDATE_DIRTY_REGION, oldDirtyInSurface_);
1524     DirtyRegionInfoForDFX dirtyRegionInfo;
1525     dirtyRegionInfo.oldDirty = oldDirty_;
1526     dirtyRegionInfo.oldDirtyInSurface = oldDirtyInSurface_;
1527     stagingRenderParams_->SetDirtyRegionInfoForDFX(dirtyRegionInfo);
1528 }
1529 
UpdateSubTreeSkipDirtyForDFX(RSDirtyRegionManager & dirtyManager,const RectI & rect)1530 void RSRenderNode::UpdateSubTreeSkipDirtyForDFX(RSDirtyRegionManager& dirtyManager, const RectI& rect)
1531 {
1532     if (RSSystemProperties::GetDirtyRegionDebugType() == DirtyRegionDebugType::DISABLED) {
1533         return;
1534     }
1535     dirtyManager.UpdateDirtyRegionInfoForDfx(
1536         GetId(), GetType(), DirtyRegionType::SUBTREE_SKIP_OUT_OF_PARENT_RECT, rect);
1537 }
1538 
Update(RSDirtyRegionManager & dirtyManager,const std::shared_ptr<RSRenderNode> & parent,bool parentDirty,std::optional<RectI> clipRect)1539 bool RSRenderNode::Update(RSDirtyRegionManager& dirtyManager, const std::shared_ptr<RSRenderNode>& parent,
1540     bool parentDirty, std::optional<RectI> clipRect)
1541 {
1542     // no need to update invisible nodes
1543     if (!ShouldPaint() && !isLastVisible_) {
1544         SetClean();
1545         GetMutableRenderProperties().ResetDirty();
1546         return false;
1547     }
1548     // [planning] surfaceNode use frame instead
1549     std::optional<Drawing::Point> offset;
1550     if (parent != nullptr && !IsInstanceOf<RSSurfaceRenderNode>()) {
1551         auto& properties = parent->GetRenderProperties();
1552         offset = Drawing::Point { properties.GetFrameOffsetX(), properties.GetFrameOffsetY() };
1553     }
1554     // in some case geodirty_ is not marked in drawCmdModifiers_, we should update node geometry
1555     // [planing] using drawcmdModifierDirty from dirtyType_
1556     parentDirty = parentDirty || (dirtyStatus_ != NodeDirty::CLEAN);
1557     auto parentProperties = parent ? &parent->GetRenderProperties() : nullptr;
1558     bool dirty = GetMutableRenderProperties().UpdateGeometry(parentProperties, parentDirty, offset);
1559     if ((IsDirty() || dirty) && renderContent_->drawCmdModifiers_.count(RSModifierType::GEOMETRYTRANS)) {
1560         RSModifierContext context = { GetMutableRenderProperties() };
1561         for (auto& modifier : renderContent_->drawCmdModifiers_[RSModifierType::GEOMETRYTRANS]) {
1562             modifier->Apply(context);
1563         }
1564     }
1565     isDirtyRegionUpdated_ = false;
1566     isLastVisible_ = ShouldPaint();
1567     GetMutableRenderProperties().ResetDirty();
1568 
1569     // Note:
1570     // 1. cache manager will use dirty region to update cache validity, background filter cache manager should use
1571     // 'dirty region of all the nodes drawn before this node', and foreground filter cache manager should use 'dirty
1572     // region of all the nodes drawn before this node, this node, and the children of this node'
1573     // 2. Filter must be valid when filter cache manager is valid, we make sure that in RSRenderNode::ApplyModifiers().
1574     if (GetRenderProperties().GetBackgroundFilter()) {
1575         UpdateFilterCacheWithBelowDirty(dirtyManager);
1576     }
1577     UpdateDirtyRegion(dirtyManager, dirty, clipRect);
1578     return dirty;
1579 }
1580 
GetMutableRenderProperties()1581 RSProperties& RSRenderNode::GetMutableRenderProperties()
1582 {
1583     return renderContent_->GetMutableRenderProperties();
1584 }
1585 
UpdateBufferDirtyRegion(RectI & dirtyRect,const RectI & drawRegion)1586 bool RSRenderNode::UpdateBufferDirtyRegion(RectI& dirtyRect, const RectI& drawRegion)
1587 {
1588 #ifndef ROSEN_CROSS_PLATFORM
1589     if (GetType() != RSRenderNodeType::SURFACE_NODE) {
1590         return false;
1591     }
1592     auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
1593     if (surfaceNode == nullptr) {
1594         return false;
1595     }
1596     auto surfaceHandler = surfaceNode->GetRSSurfaceHandler();
1597     auto buffer = surfaceHandler->GetBuffer();
1598     if (buffer != nullptr) {
1599         // Use the matrix from buffer to relative coordinate and the absolute matrix
1600         // to calculate the buffer damageRegion's absolute rect
1601         auto rect = surfaceHandler->GetDamageRegion();
1602         auto matrix = surfaceNode->GetBufferRelMatrix();
1603         matrix.PostConcat(GetRenderProperties().GetBoundsGeometry()->GetAbsMatrix());
1604         auto bufferDirtyRect = GetRenderProperties().GetBoundsGeometry()->MapRect(
1605             RectF(rect.x, rect.y, rect.w, rect.h), matrix);
1606         bufferDirtyRect.JoinRect(drawRegion);
1607         // The buffer's dirtyRect should not be out of the scope of the node's dirtyRect
1608         dirtyRect = bufferDirtyRect.IntersectRect(dirtyRect);
1609         RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode id: %" PRIu64 ", buffer size [%d,%d], "
1610             "buffer damageRegion [%d,%d,%d,%d], dirtyRect %s", GetId(),
1611             buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(),
1612             rect.x, rect.y, rect.w, rect.h, dirtyRect.ToString().c_str());
1613         return true;
1614     }
1615 #endif
1616     return false;
1617 }
1618 
UpdateDirtyRegion(RSDirtyRegionManager & dirtyManager,bool geoDirty,const std::optional<RectI> & clipRect)1619 void RSRenderNode::UpdateDirtyRegion(
1620     RSDirtyRegionManager& dirtyManager, bool geoDirty, const std::optional<RectI>& clipRect)
1621 {
1622     if (!IsDirty() && !geoDirty) {
1623         return;
1624     }
1625     if (RSSystemProperties::GetSkipGeometryNotChangeEnabled()) {
1626         // while node absRect not change and other content not change, return directly for not generate dirty region
1627         if (!IsSelfDrawingNode() && !geometryChangeNotPerceived_ && !geoDirty) {
1628             return;
1629         }
1630         geometryChangeNotPerceived_ = false;
1631     }
1632     if (!oldDirty_.IsEmpty()) {
1633         dirtyManager.MergeDirtyRect(oldDirty_);
1634     }
1635     // merge old dirty if switch to invisible
1636     if (!ShouldPaint() && isLastVisible_) {
1637         ROSEN_LOGD("RSRenderNode:: id %{public}" PRIu64 " UpdateDirtyRegion visible->invisible", GetId());
1638     } else {
1639         RectI drawRegion;
1640         RectI shadowRect;
1641         auto& properties = GetRenderProperties();
1642         auto dirtyRect = properties.GetDirtyRect(drawRegion);
1643         auto rectFromRenderProperties = dirtyRect;
1644         // When surface node with buffer has damageRegion, use this instead of the node size
1645         if (UpdateBufferDirtyRegion(dirtyRect, drawRegion)) {
1646             // Add node's last and current frame absRect when the node size change
1647             if (rectFromRenderProperties != oldRectFromRenderProperties_) {
1648                 dirtyManager.MergeDirtyRect(oldRectFromRenderProperties_);
1649                 dirtyRect.JoinRect(rectFromRenderProperties);
1650                 oldRectFromRenderProperties_ = rectFromRenderProperties;
1651             }
1652         }
1653 
1654         // Add node's shadow region to dirtyRect
1655         if (properties.IsShadowValid()) {
1656             SetShadowValidLastFrame(true);
1657             if (IsInstanceOf<RSSurfaceRenderNode>()) {
1658                 const RectF absBounds = {0, 0, properties.GetBoundsWidth(),
1659                     properties.GetBoundsHeight()};
1660                 RRect absClipRRect = RRect(absBounds, properties.GetCornerRadius());
1661                 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, properties, &absClipRRect);
1662             } else {
1663                 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, properties);
1664             }
1665             if (!shadowRect.IsEmpty()) {
1666                 // Avoid deviation caused by converting float to int
1667                 shadowRect = shadowRect.MakeOutset({1, 1, 1, 1});
1668                 dirtyRect = dirtyRect.JoinRect(shadowRect);
1669             }
1670         }
1671 
1672         // Add node's outline region to dirtyRect
1673         auto& outline = properties.GetOutline();
1674         RectI outlineRect;
1675         if (outline && outline->HasBorder()) {
1676             RSPropertiesPainter::GetOutlineDirtyRect(outlineRect, properties);
1677             if (!outlineRect.IsEmpty()) {
1678                 dirtyRect = dirtyRect.JoinRect(outlineRect);
1679             }
1680         }
1681 
1682         // Add node's pixelStretch region to dirtyRect
1683         if (properties.pixelStretch_) {
1684             auto stretchDirtyRect = properties.GetPixelStretchDirtyRect();
1685             dirtyRect = dirtyRect.JoinRect(stretchDirtyRect);
1686         }
1687 
1688         // Add node's foregroundEffect region to dirtyRect
1689         std::shared_ptr<RSFilter> foregroundFilter = nullptr;
1690         if (RSProperties::IS_UNI_RENDER) {
1691             foregroundFilter = properties.GetForegroundFilterCache();
1692         } else {
1693             foregroundFilter = properties.GetForegroundFilter();
1694         }
1695         if (foregroundFilter && foregroundFilter->GetFilterType() == RSFilter::FOREGROUND_EFFECT) {
1696             float dirtyExtension =
1697                 std::static_pointer_cast<RSForegroundEffectFilter>(foregroundFilter)->GetDirtyExtension();
1698             dirtyRect = dirtyRect.MakeOutset(Vector4<int>(dirtyExtension));
1699         }
1700 
1701         if (clipRect.has_value()) {
1702             dirtyRect = dirtyRect.IntersectRect(*clipRect);
1703         }
1704         oldDirty_ = dirtyRect;
1705         oldDirtyInSurface_ = oldDirty_.IntersectRect(dirtyManager.GetSurfaceRect());
1706         // filter invalid dirtyrect
1707         if (!dirtyRect.IsEmpty()) {
1708             dirtyManager.MergeDirtyRect(dirtyRect);
1709             isDirtyRegionUpdated_ = true;
1710             // save types of dirty region of target dirty manager for dfx
1711             if (dirtyManager.IsTargetForDfx() &&
1712                 (GetType() == RSRenderNodeType::CANVAS_NODE || GetType() == RSRenderNodeType::SURFACE_NODE)) {
1713                 dirtyManager.UpdateDirtyRegionInfoForDfx(
1714                     GetId(), GetType(), DirtyRegionType::UPDATE_DIRTY_REGION, oldDirtyInSurface_);
1715                 dirtyManager.UpdateDirtyRegionInfoForDfx(
1716                     GetId(), GetType(), DirtyRegionType::OVERLAY_RECT, drawRegion);
1717                 dirtyManager.UpdateDirtyRegionInfoForDfx(
1718                     GetId(), GetType(), DirtyRegionType::SHADOW_RECT, shadowRect);
1719                 dirtyManager.UpdateDirtyRegionInfoForDfx(
1720                     GetId(), GetType(), DirtyRegionType::PREPARE_CLIP_RECT, clipRect.value_or(RectI()));
1721                 dirtyManager.UpdateDirtyRegionInfoForDfx(
1722                     GetId(), GetType(), DirtyRegionType::RENDER_PROPERTIES_RECT, rectFromRenderProperties);
1723                 dirtyManager.UpdateDirtyRegionInfoForDfx(
1724                     GetId(), GetType(), DirtyRegionType::OUTLINE_RECT, outlineRect);
1725             }
1726         }
1727     }
1728 
1729     SetClean();
1730 }
1731 
IsSelfDrawingNode() const1732 bool RSRenderNode::IsSelfDrawingNode() const
1733 {
1734     return GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE || GetType() == RSRenderNodeType::SURFACE_NODE;
1735 }
1736 
IsDirty() const1737 bool RSRenderNode::IsDirty() const
1738 {
1739     return dirtyStatus_ != NodeDirty::CLEAN || GetRenderProperties().IsDirty();
1740 }
1741 
IsSubTreeDirty() const1742 bool RSRenderNode::IsSubTreeDirty() const
1743 {
1744     return isSubTreeDirty_;
1745 }
1746 
SetSubTreeDirty(bool val)1747 void RSRenderNode::SetSubTreeDirty(bool val)
1748 {
1749     isSubTreeDirty_ = val;
1750 }
1751 
SetParentSubTreeDirty()1752 void RSRenderNode::SetParentSubTreeDirty()
1753 {
1754     auto parentNode = parent_.lock();
1755     if (parentNode && !parentNode->IsSubTreeDirty()) {
1756         parentNode->SetSubTreeDirty(true);
1757         parentNode->SetParentSubTreeDirty();
1758     }
1759 }
1760 
IsContentDirty() const1761 bool RSRenderNode::IsContentDirty() const
1762 {
1763     // Considering renderNode, it should consider both basenode's case and its properties
1764     return isContentDirty_ || GetRenderProperties().IsContentDirty();
1765 }
1766 
UpdateRenderStatus(RectI & dirtyRegion,bool isPartialRenderEnabled)1767 void RSRenderNode::UpdateRenderStatus(RectI& dirtyRegion, bool isPartialRenderEnabled)
1768 {
1769     auto dirtyRect = GetRenderProperties().GetDirtyRect();
1770     // should judge if there's any child out of parent
1771     if (!isPartialRenderEnabled || HasChildrenOutOfRect()) {
1772         isRenderUpdateIgnored_ = false;
1773     } else if (dirtyRegion.IsEmpty() || dirtyRect.IsEmpty()) {
1774         isRenderUpdateIgnored_ = true;
1775     } else {
1776         RectI intersectRect = dirtyRegion.IntersectRect(dirtyRect);
1777         isRenderUpdateIgnored_ = intersectRect.IsEmpty();
1778     }
1779 }
1780 
MapAndUpdateChildrenRect()1781 void RSRenderNode::MapAndUpdateChildrenRect()
1782 {
1783     auto geoPtr = GetRenderProperties().GetBoundsGeometry();
1784     if (!shouldPaint_ || geoPtr == nullptr) {
1785         return;
1786     }
1787     auto childRect = selfDrawRect_;
1788     // all child must map to its direct parent
1789     if (!childrenRect_.IsEmpty()) {
1790         // clean subtree means childrenRect maps to parent already
1791         childRect = childRect.JoinRect(childrenRect_.ConvertTo<float>());
1792     }
1793     // map before update parent, if parent has clip property, use clipped children rect instead.
1794     // node with sharedTransitionParam should recalculate childRelativeToParentMatrix from absMatrix due to sandbox.
1795     if (auto parentNode = parent_.lock()) {
1796         const auto& parentProperties = parentNode->GetRenderProperties();
1797         const auto& sandbox = GetRenderProperties().GetSandBox();
1798         RectI childRectMapped;
1799         if (LIKELY(!sandbox.has_value())) {
1800             childRectMapped = geoPtr->MapRect(childRect, geoPtr->GetMatrix());
1801         } else {
1802             Drawing::Matrix invertAbsParentMatrix;
1803             const auto& parentGeoPtr = parentProperties.GetBoundsGeometry();
1804             if (parentGeoPtr && parentGeoPtr->GetAbsMatrix().Invert(invertAbsParentMatrix)) {
1805                 auto childRelativeToParentMatrix = geoPtr->GetAbsMatrix();
1806                 childRelativeToParentMatrix.PostConcat(invertAbsParentMatrix);
1807                 childRectMapped = geoPtr->MapRect(childRect, childRelativeToParentMatrix);
1808             } else {
1809                 childRectMapped = geoPtr->MapRect(childRect, geoPtr->GetMatrix());
1810             }
1811         }
1812         if (parentProperties.GetClipToBounds() || parentProperties.GetClipToFrame()) {
1813             childRectMapped = parentNode->GetSelfDrawRect().ConvertTo<int>().IntersectRect(childRectMapped);
1814         }
1815         parentNode->UpdateChildrenRect(childRectMapped);
1816         // check each child is inside of parent
1817         childRect = childRectMapped.ConvertTo<float>();
1818         if (!childRect.IsInsideOf(parentNode->GetSelfDrawRect())) {
1819             parentNode->UpdateChildrenOutOfRectFlag(true);
1820         }
1821     }
1822 }
1823 
UpdateParentChildrenRect(std::shared_ptr<RSRenderNode> parentNode) const1824 void RSRenderNode::UpdateParentChildrenRect(std::shared_ptr<RSRenderNode> parentNode) const
1825 {
1826     if (!shouldPaint_ || (oldDirty_.IsEmpty() && GetChildrenRect().IsEmpty())) {
1827         return;
1828     }
1829     if (parentNode) {
1830         // accumulate current node's all children region(including itself)
1831         // apply oldDirty_ as node's real region(including overlay and shadow)
1832         RectI accumulatedRect = GetChildrenRect().JoinRect(oldDirty_);
1833         parentNode->UpdateChildrenRect(accumulatedRect);
1834         // check each child is inside of parent
1835         if (!accumulatedRect.IsInsideOf(parentNode->GetOldDirty())) {
1836             parentNode->UpdateChildrenOutOfRectFlag(true);
1837         }
1838     }
1839 }
1840 
IsFilterCacheValid() const1841 bool RSRenderNode::IsFilterCacheValid() const
1842 {
1843     if (!RSSystemProperties::GetBlurEnabled() || !RSProperties::FilterCacheEnabled) {
1844         ROSEN_LOGD("IsBackgroundFilterCacheValid::blur is disabled or filter cache is disabled.");
1845         return false;
1846     }
1847     auto filterDrawable = GetRenderProperties().GetFilter() != nullptr ?
1848         GetFilterDrawable(true) : GetFilterDrawable(false);
1849     if (filterDrawable == nullptr) {
1850         return false;
1851     }
1852     return filterDrawable->IsFilterCacheValid();
1853 }
1854 
IsAIBarFilterCacheValid() const1855 bool RSRenderNode::IsAIBarFilterCacheValid() const
1856 {
1857     if (!RSSystemProperties::GetBlurEnabled() || !RSProperties::FilterCacheEnabled) {
1858         ROSEN_LOGD("IsBackgroundFilterCacheValid::blur is disabled or filter cache is disabled.");
1859         return false;
1860     }
1861     auto filterDrawable = GetRenderProperties().GetFilter() != nullptr ?
1862         GetFilterDrawable(true) : GetFilterDrawable(false);
1863     if (filterDrawable == nullptr) {
1864         return false;
1865     }
1866     return filterDrawable->IsAIBarCacheValid();
1867 }
1868 
GetFilterCachedRegion() const1869 const RectI RSRenderNode::GetFilterCachedRegion() const
1870 {
1871     return lastFilterRegion_;
1872 }
1873 
HasBlurFilter() const1874 bool RSRenderNode::HasBlurFilter() const
1875 {
1876     return GetRenderProperties().GetBackgroundFilter() || GetRenderProperties().GetFilter();
1877 }
1878 
UpdateLastFilterCacheRegion()1879 void RSRenderNode::UpdateLastFilterCacheRegion()
1880 {
1881     lastFilterRegion_ = filterRegion_;
1882 }
1883 
GetAbsMatrixReverse(const RSRenderNode & rootNode,Drawing::Matrix & absMatrix)1884 bool RSRenderNode::GetAbsMatrixReverse(const RSRenderNode& rootNode, Drawing::Matrix& absMatrix)
1885 {
1886     auto& rootProperties = rootNode.GetRenderProperties();
1887     auto rootGeo = rootProperties.GetBoundsGeometry();
1888     auto selfGeo = GetRenderProperties().GetBoundsGeometry();
1889     if (!rootGeo || !selfGeo) {
1890         return false;
1891     }
1892     Drawing::Matrix selfMatrix = selfGeo->GetMatrix();
1893     auto directParent = GetParent().lock();
1894     while (directParent && directParent->GetId() != rootNode.GetId()) {
1895         if (auto parentGeo = directParent->GetRenderProperties().GetBoundsGeometry()) {
1896             selfMatrix.PostConcat(parentGeo->GetMatrix());
1897         }
1898         directParent = directParent->GetParent().lock();
1899     }
1900     if (!directParent) {
1901         return false;
1902     }
1903     selfMatrix.PostConcat(rootGeo->GetAbsMatrix());
1904     absMatrix = selfMatrix;
1905     return true;
1906 }
1907 
Rect2DrawingRect(const RectF & r)1908 inline static Drawing::Rect Rect2DrawingRect(const RectF& r)
1909 {
1910     return Drawing::Rect(r.left_, r.top_, r.left_ + r.width_, r.top_ + r.height_);
1911 }
1912 
UpdateFilterRegionInSkippedSubTree(RSDirtyRegionManager & dirtyManager,const RSRenderNode & subTreeRoot,RectI & filterRect,const RectI & clipRect)1913 void RSRenderNode::UpdateFilterRegionInSkippedSubTree(RSDirtyRegionManager& dirtyManager,
1914     const RSRenderNode& subTreeRoot, RectI& filterRect, const RectI& clipRect)
1915 {
1916     Drawing::Matrix absMatrix;
1917     if (!GetAbsMatrixReverse(subTreeRoot, absMatrix)) {
1918         return;
1919     }
1920     Drawing::RectF absDrawRect;
1921     absMatrix.MapRect(absDrawRect, Rect2DrawingRect(selfDrawRect_));
1922     oldDirtyInSurface_ = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
1923         absDrawRect.GetWidth(), absDrawRect.GetHeight()).IntersectRect(clipRect);
1924     Drawing::RectF absRect;
1925     absMatrix.MapRect(absRect, Rect2DrawingRect(GetRenderProperties().GetBoundsRect()));
1926     filterRect = RectI(absRect.GetLeft(), absRect.GetTop(), absRect.GetWidth(), absRect.GetHeight());
1927     filterRect = filterRect.IntersectRect(clipRect);
1928     filterRegion_ = filterRect;
1929     if (filterRect == lastFilterRegion_) {
1930         return;
1931     }
1932     dirtyManager.MergeDirtyRect(filterRect);
1933     isDirtyRegionUpdated_ = true;
1934 }
1935 
CheckBlurFilterCacheNeedForceClearOrSave(bool rotationChanged,bool rotationStatusChanged)1936 void RSRenderNode::CheckBlurFilterCacheNeedForceClearOrSave(bool rotationChanged, bool rotationStatusChanged)
1937 {
1938     bool rotationClear = false;
1939     if (!IsInstanceOf<RSEffectRenderNode>() && rotationChanged) {
1940         rotationClear = true;
1941     }
1942     const auto& properties = GetRenderProperties();
1943     if (properties.GetBackgroundFilter()) {
1944         auto filterDrawable = GetFilterDrawable(false);
1945         if (filterDrawable != nullptr) {
1946             auto bgDirty = dirtySlots_.count(RSDrawableSlot::BACKGROUND_COLOR) ||
1947                 dirtySlots_.count(RSDrawableSlot::BACKGROUND_SHADER) ||
1948                 dirtySlots_.count(RSDrawableSlot::BACKGROUND_IMAGE);
1949             if (!(filterDrawable->IsForceClearFilterCache()) && (rotationClear || bgDirty)) {
1950                 RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode[%llu] background color or shader or image is dirty", GetId());
1951                 filterDrawable->MarkFilterForceClearCache();
1952             }
1953         }
1954     }
1955     if (IsInstanceOf<RSEffectRenderNode>()) {
1956         rotationStatusChanged = false;
1957     }
1958     if (properties.GetFilter()) {
1959         auto filterDrawable = GetFilterDrawable(true);
1960         if (filterDrawable != nullptr) {
1961             if (!(filterDrawable->IsForceClearFilterCache()) && (rotationStatusChanged || !dirtySlots_.empty())) {
1962                 RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode[%llu] foreground is dirty", GetId());
1963                 filterDrawable->MarkFilterForceClearCache();
1964             }
1965         }
1966     }
1967 }
1968 
IsForceClearOrUseFilterCache(std::shared_ptr<DrawableV2::RSFilterDrawable> & filterDrawable)1969 bool RSRenderNode::IsForceClearOrUseFilterCache(std::shared_ptr<DrawableV2::RSFilterDrawable>& filterDrawable)
1970 {
1971     return filterDrawable->IsForceUseFilterCache() || filterDrawable->IsForceClearFilterCache();
1972 }
1973 
MarkFilterStatusChanged(bool isForeground,bool isFilterRegionChanged)1974 void RSRenderNode::MarkFilterStatusChanged(bool isForeground, bool isFilterRegionChanged)
1975 {
1976     auto filterDrawable = GetFilterDrawable(isForeground);
1977     if (filterDrawable == nullptr || IsForceClearOrUseFilterCache(filterDrawable)) {
1978         return;
1979     }
1980     auto& flag = isForeground ?
1981         (isFilterRegionChanged ? foregroundFilterRegionChanged_ : foregroundFilterInteractWithDirty_) :
1982         (isFilterRegionChanged ? backgroundFilterRegionChanged_ : backgroundFilterInteractWithDirty_);
1983     flag = true;
1984     isFilterRegionChanged ?
1985         filterDrawable->MarkFilterRegionChanged() : filterDrawable->MarkFilterRegionInteractWithDirty();
1986 }
1987 
GetFilterDrawable(bool isForeground) const1988 std::shared_ptr<DrawableV2::RSFilterDrawable> RSRenderNode::GetFilterDrawable(bool isForeground) const
1989 {
1990     auto slot = isForeground ? RSDrawableSlot::COMPOSITING_FILTER : RSDrawableSlot::BACKGROUND_FILTER;
1991     if (auto& drawable = drawableVec_[static_cast<uint32_t>(slot)]) {
1992         if (auto filterDrawable = std::static_pointer_cast<DrawableV2::RSFilterDrawable>(drawable)) {
1993             return filterDrawable;
1994         }
1995     }
1996     return nullptr;
1997 }
1998 
UpdateFilterCacheWithBackgroundDirty()1999 void RSRenderNode::UpdateFilterCacheWithBackgroundDirty()
2000 {
2001 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2002     if (!RSProperties::FilterCacheEnabled) {
2003         return;
2004     }
2005     auto filterDrawable = GetFilterDrawable(false);
2006     if (filterDrawable == nullptr || IsForceClearOrUseFilterCache(filterDrawable)) {
2007         return;
2008     }
2009     auto hasBackground = drawableVec_[static_cast<int32_t>(RSDrawableSlot::BACKGROUND_COLOR)] ||
2010                          drawableVec_[static_cast<int32_t>(RSDrawableSlot::BACKGROUND_SHADER)] ||
2011                          drawableVec_[static_cast<int32_t>(RSDrawableSlot::BACKGROUND_IMAGE)];
2012     auto alphaDirty = dirtyTypes_.test(static_cast<size_t>(RSModifierType::ALPHA));
2013     if (alphaDirty && hasBackground) {
2014         RS_OPTIONAL_TRACE_NAME_FMT(
2015             "RSRenderNode[%llu] background color or shader or image is dirty due to changes in alpha", GetId());
2016         filterDrawable->MarkFilterForceClearCache();
2017     }
2018 #endif
2019 }
2020 
UpdateFilterCacheWithBelowDirty(RSDirtyRegionManager & dirtyManager,bool isForeground)2021 void RSRenderNode::UpdateFilterCacheWithBelowDirty(RSDirtyRegionManager& dirtyManager, bool isForeground)
2022 {
2023 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2024     if (!RSProperties::FilterCacheEnabled) {
2025         ROSEN_LOGE("RSRenderNode::UpdateFilterCacheWithBelowDirty filter cache is disabled.");
2026         return;
2027     }
2028     auto filterDrawable = GetFilterDrawable(isForeground);
2029     if (filterDrawable == nullptr || IsForceClearOrUseFilterCache(filterDrawable)) {
2030         return;
2031     }
2032     auto dirtyRegion = dirtyManager.GetCurrentFrameDirtyRegion();
2033     RS_OPTIONAL_TRACE_NAME_FMT("UpdateFilterCacheWithBelowDirty:node[%llu] foreground:%d, lastRect:%s, dirtyRegion:%s",
2034         GetId(), isForeground, lastFilterRegion_.ToString().c_str(), dirtyRegion.ToString().c_str());
2035     if (!dirtyRegion.Intersect(lastFilterRegion_)) {
2036         return;
2037     }
2038     MarkFilterStatusChanged(isForeground, false);
2039 #endif
2040 }
2041 
UpdateFilterCacheWithSelfDirty()2042 void RSRenderNode::UpdateFilterCacheWithSelfDirty()
2043 {
2044 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2045     if (!RSProperties::FilterCacheEnabled) {
2046         ROSEN_LOGE("RSRenderNode::UpdateFilterCacheWithSelfDirty filter cache is disabled.");
2047         return;
2048     }
2049     RS_OPTIONAL_TRACE_NAME_FMT("node[%llu] UpdateFilterCacheWithSelfDirty lastRect:%s, currRegion:%s",
2050         GetId(), lastFilterRegion_.ToString().c_str(), filterRegion_.ToString().c_str());
2051     const auto& properties = GetRenderProperties();
2052     if ((properties.GetBackgroundFilter() || properties.GetNeedDrawBehindWindow()) &&
2053         !filterRegion_.IsInsideOf(lastFilterRegion_)) {
2054         auto filterDrawable = GetFilterDrawable(false);
2055         if (filterDrawable != nullptr) {
2056             if (!IsForceClearOrUseFilterCache(filterDrawable)) {
2057                 MarkFilterStatusChanged(false, true);
2058             }
2059         }
2060     }
2061     if (properties.GetFilter() && filterRegion_ != lastFilterRegion_) {
2062         auto filterDrawable = GetFilterDrawable(true);
2063         if (filterDrawable != nullptr) {
2064             if (!IsForceClearOrUseFilterCache(filterDrawable)) {
2065                 MarkFilterStatusChanged(true, true);
2066             }
2067         }
2068     }
2069 #endif
2070 }
2071 
IsBackgroundInAppOrNodeSelfDirty() const2072 bool RSRenderNode::IsBackgroundInAppOrNodeSelfDirty() const
2073 {
2074     return backgroundFilterInteractWithDirty_ || backgroundFilterRegionChanged_;
2075 }
2076 
UpdateDirtySlotsAndPendingNodes(RSDrawableSlot slot)2077 void RSRenderNode::UpdateDirtySlotsAndPendingNodes(RSDrawableSlot slot)
2078 {
2079     dirtySlots_.emplace(slot);
2080     AddToPendingSyncList();
2081 }
2082 
IsLargeArea(int width,int height)2083 inline static bool IsLargeArea(int width, int height)
2084 {
2085     static const auto threshold = RSSystemProperties::GetFilterCacheSizeThreshold();
2086     return width > threshold && height > threshold;
2087 }
2088 
PostPrepareForBlurFilterNode(RSDirtyRegionManager & dirtyManager,bool needRequestNextVsync)2089 void RSRenderNode::PostPrepareForBlurFilterNode(RSDirtyRegionManager& dirtyManager, bool needRequestNextVsync)
2090 {
2091     MarkFilterHasEffectChildren();
2092     if (!RSProperties::FilterCacheEnabled) {
2093         ROSEN_LOGE("RSRenderNode::PostPrepareForBlurFilterNode filter cache is disabled.");
2094         return;
2095     }
2096     const auto& properties = GetRenderProperties();
2097     if (properties.GetBackgroundFilter() || properties.GetNeedDrawBehindWindow()) {
2098         auto filterDrawable = GetFilterDrawable(false);
2099         if (filterDrawable != nullptr) {
2100             MarkFilterCacheFlags(filterDrawable, dirtyManager, needRequestNextVsync);
2101             CheckFilterCacheAndUpdateDirtySlots(filterDrawable, RSDrawableSlot::BACKGROUND_FILTER);
2102         }
2103     }
2104     if (properties.GetFilter()) {
2105         auto filterDrawable = GetFilterDrawable(true);
2106         if (filterDrawable != nullptr) {
2107             MarkFilterCacheFlags(filterDrawable, dirtyManager, needRequestNextVsync);
2108             CheckFilterCacheAndUpdateDirtySlots(filterDrawable, RSDrawableSlot::COMPOSITING_FILTER);
2109         }
2110     }
2111     OnFilterCacheStateChanged();
2112     UpdateLastFilterCacheRegion();
2113 }
2114 
MarkFilterCacheFlags(std::shared_ptr<DrawableV2::RSFilterDrawable> & filterDrawable,RSDirtyRegionManager & dirtyManager,bool needRequestNextVsync)2115 void RSRenderNode::MarkFilterCacheFlags(std::shared_ptr<DrawableV2::RSFilterDrawable>& filterDrawable,
2116     RSDirtyRegionManager& dirtyManager, bool needRequestNextVsync)
2117 {
2118     if (IsForceClearOrUseFilterCache(filterDrawable)) {
2119         return;
2120     }
2121 
2122     RS_OPTIONAL_TRACE_NAME_FMT("MarkFilterCacheFlags:node[%llu], NeedPendingPurge:%d, forceClearWithoutNextVsync:%d",
2123         GetId(), filterDrawable->NeedPendingPurge(), (!needRequestNextVsync && filterDrawable->IsSkippingFrame()));
2124     // force update if last frame use cache because skip-frame and current frame background is not dirty
2125     if (filterDrawable->NeedPendingPurge()) {
2126         dirtyManager.MergeDirtyRect(filterRegion_);
2127         isDirtyRegionUpdated_ = true;
2128         return;
2129     }
2130     // force update if no next vsync when skip-frame enabled
2131     if (!needRequestNextVsync && filterDrawable->IsSkippingFrame()) {
2132         filterDrawable->MarkForceClearCacheWithLastFrame();
2133         return;
2134     }
2135 
2136     // when background changed, skip-frame will enabled if filter region > 400 and blur radius > 25
2137     if (IsLargeArea(oldDirty_.GetWidth(), oldDirty_.GetHeight())) {
2138         filterDrawable->MarkFilterRegionIsLargeArea();
2139     }
2140 }
2141 
CheckFilterCacheAndUpdateDirtySlots(std::shared_ptr<DrawableV2::RSFilterDrawable> & filterDrawable,RSDrawableSlot slot)2142 void RSRenderNode::CheckFilterCacheAndUpdateDirtySlots(
2143     std::shared_ptr<DrawableV2::RSFilterDrawable>& filterDrawable, RSDrawableSlot slot)
2144 {
2145     if (filterDrawable == nullptr) {
2146         return;
2147     }
2148     filterDrawable->MarkNeedClearFilterCache();
2149     UpdateDirtySlotsAndPendingNodes(slot);
2150 }
2151 
MarkForceClearFilterCacheWithInvisible()2152 void RSRenderNode::MarkForceClearFilterCacheWithInvisible()
2153 {
2154     if (GetRenderProperties().GetBackgroundFilter()) {
2155         auto filterDrawable = GetFilterDrawable(false);
2156         if (filterDrawable != nullptr) {
2157             filterDrawable->MarkFilterForceClearCache();
2158             CheckFilterCacheAndUpdateDirtySlots(filterDrawable, RSDrawableSlot::BACKGROUND_FILTER);
2159         }
2160     }
2161     if (GetRenderProperties().GetFilter()) {
2162         auto filterDrawable = GetFilterDrawable(true);
2163         if (filterDrawable != nullptr) {
2164             filterDrawable->MarkFilterForceClearCache();
2165             CheckFilterCacheAndUpdateDirtySlots(filterDrawable, RSDrawableSlot::BACKGROUND_FILTER);
2166         }
2167     }
2168 }
2169 
SetOccludedStatus(bool occluded)2170 void RSRenderNode::SetOccludedStatus(bool occluded)
2171 {
2172     if (GetRenderProperties().GetBackgroundFilter()) {
2173         auto filterDrawable = GetFilterDrawable(false);
2174         if (filterDrawable != nullptr) {
2175             filterDrawable->MarkNodeIsOccluded(occluded);
2176         }
2177     }
2178     if (GetRenderProperties().GetFilter()) {
2179         auto filterDrawable = GetFilterDrawable(true);
2180         if (filterDrawable != nullptr) {
2181             filterDrawable->MarkNodeIsOccluded(occluded);
2182         }
2183     }
2184     isOccluded_ = occluded;
2185 }
2186 
RenderTraceDebug() const2187 void RSRenderNode::RenderTraceDebug() const
2188 {
2189     if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
2190         RSPropertyTrace::GetInstance().PropertiesDisplayByTrace(GetId(),
2191             std::static_pointer_cast<RSObjAbsGeometry>(GetRenderProperties().GetBoundsGeometry()));
2192         RSPropertyTrace::GetInstance().TracePropertiesByNodeName(GetId(), GetNodeName(), GetRenderProperties());
2193     }
2194 }
2195 
ApplyBoundsGeometry(RSPaintFilterCanvas & canvas)2196 void RSRenderNode::ApplyBoundsGeometry(RSPaintFilterCanvas& canvas)
2197 {
2198     DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::BOUNDS_MATRIX, canvas);
2199 }
2200 
ApplyAlpha(RSPaintFilterCanvas & canvas)2201 void RSRenderNode::ApplyAlpha(RSPaintFilterCanvas& canvas)
2202 {
2203     DrawPropertyDrawable(RSPropertyDrawableSlot::ALPHA, canvas);
2204 }
2205 
ProcessTransitionBeforeChildren(RSPaintFilterCanvas & canvas)2206 void RSRenderNode::ProcessTransitionBeforeChildren(RSPaintFilterCanvas& canvas)
2207 {
2208     DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::MASK, canvas);
2209 }
2210 
ProcessRenderBeforeChildren(RSPaintFilterCanvas & canvas)2211 void RSRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
2212 {
2213     RSRenderNode::ProcessTransitionBeforeChildren(canvas);
2214 }
2215 
ProcessTransitionAfterChildren(RSPaintFilterCanvas & canvas)2216 void RSRenderNode::ProcessTransitionAfterChildren(RSPaintFilterCanvas& canvas)
2217 {
2218     DrawPropertyDrawable(RSPropertyDrawableSlot::RESTORE_ALL, canvas);
2219 }
2220 
ProcessRenderAfterChildren(RSPaintFilterCanvas & canvas)2221 void RSRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
2222 {
2223     DrawPropertyDrawable(RSPropertyDrawableSlot::RESTORE_ALL, canvas);
2224 }
2225 
SetUifirstSyncFlag(bool needSync)2226 void RSRenderNode::SetUifirstSyncFlag(bool needSync)
2227 {
2228     uifirstNeedSync_ = needSync;
2229 }
2230 
AddModifier(const std::shared_ptr<RSRenderModifier> & modifier,bool isSingleFrameComposer)2231 void RSRenderNode::AddModifier(const std::shared_ptr<RSRenderModifier>& modifier, bool isSingleFrameComposer)
2232 {
2233     if (!modifier) {
2234         ROSEN_LOGW("RSRenderNode: null modifier add failed.");
2235         return;
2236     }
2237     SetDirty();
2238     if (RSSystemProperties::GetSingleFrameComposerEnabled() &&
2239         GetNodeIsSingleFrameComposer() && isSingleFrameComposer) {
2240         if (singleFrameComposer_ == nullptr) {
2241             singleFrameComposer_ = std::make_shared<RSSingleFrameComposer>();
2242         }
2243         singleFrameComposer_->SingleFrameAddModifier(modifier);
2244         ROSEN_LOGI_IF(DEBUG_MODIFIER, "RSRenderNode:add modifier for single frame, node id: %{public}" PRIu64 ","
2245             "type: %{public}s, cmdList: %{public}s",
2246             GetId(), modifier->GetModifierTypeString().c_str(), std::to_string(modifier->GetDrawCmdListId()).c_str());
2247         return;
2248     }
2249     if (modifier->GetType() == RSModifierType::BOUNDS || modifier->GetType() == RSModifierType::FRAME) {
2250         AddGeometryModifier(modifier);
2251     } else if (modifier->GetType() < RSModifierType::CUSTOM) {
2252         modifiers_.emplace(modifier->GetPropertyId(), modifier);
2253     } else {
2254         modifier->SetSingleFrameModifier(false);
2255         renderContent_->drawCmdModifiers_[modifier->GetType()].emplace_back(modifier);
2256     }
2257     modifier->GetProperty()->Attach(shared_from_this());
2258     ROSEN_LOGI_IF(DEBUG_MODIFIER, "RSRenderNode:add modifier, node id: %{public}" PRIu64 ", type: %{public}s",
2259         GetId(), modifier->GetModifierTypeString().c_str());
2260 }
2261 
AddGeometryModifier(const std::shared_ptr<RSRenderModifier> & modifier)2262 void RSRenderNode::AddGeometryModifier(const std::shared_ptr<RSRenderModifier>& modifier)
2263 {
2264     // bounds and frame modifiers must be unique
2265     if (modifier->GetType() == RSModifierType::BOUNDS) {
2266         if (boundsModifier_ == nullptr) {
2267             boundsModifier_ = modifier;
2268         } else {
2269             boundsModifier_->Update(modifier->GetProperty(), false);
2270         }
2271         modifiers_.emplace(modifier->GetPropertyId(), boundsModifier_);
2272     }
2273 
2274     if (modifier->GetType() == RSModifierType::FRAME) {
2275         if (frameModifier_ == nullptr) {
2276             frameModifier_ = modifier;
2277         } else {
2278             frameModifier_->Update(modifier->GetProperty(), false);
2279         }
2280         modifiers_.emplace(modifier->GetPropertyId(), frameModifier_);
2281     }
2282 }
2283 
RemoveModifier(const PropertyId & id)2284 void RSRenderNode::RemoveModifier(const PropertyId& id)
2285 {
2286     SetDirty();
2287     auto it = modifiers_.find(id);
2288     if (it != modifiers_.end()) {
2289         if (it->second) {
2290             AddDirtyType(it->second->GetType());
2291         }
2292         ROSEN_LOGI_IF(DEBUG_MODIFIER, "RSRenderNode::remove modifier, node id: %{public}" PRIu64 ", type: %{public}s",
2293             GetId(), (it->second) ? it->second->GetModifierTypeString().c_str() : "UNKNOWN");
2294         modifiers_.erase(it);
2295         return;
2296     }
2297     for (auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
2298         bool found = EraseIf(modifiers,
2299             [id](const auto& modifier) -> bool { return modifier == nullptr || modifier->GetPropertyId() == id; });
2300         if (found) {
2301             AddDirtyType(type);
2302         }
2303     }
2304 }
2305 
RemoveAllModifiers()2306 void RSRenderNode::RemoveAllModifiers()
2307 {
2308     modifiers_.clear();
2309     renderContent_->drawCmdModifiers_.clear();
2310 }
2311 
AccmulateDirtyInOcclusion(bool isOccluded)2312 void RSRenderNode::AccmulateDirtyInOcclusion(bool isOccluded)
2313 {
2314     if (isOccluded) {
2315         // accmulate dirtytypes for modifiers
2316         AccmulateDirtyTypes();
2317         // accmulate dirtystatus in rendernode
2318         AccmulateDirtyStatus();
2319         // accmulate dirtystatus in render properties(isDirty, geoDirty, contentDirty)
2320         GetMutableRenderProperties().AccmulateDirtyStatus();
2321         return;
2322     }
2323     ResetAccmulateDirtyTypes();
2324     ResetAccmulateDirtyStatus();
2325 }
2326 
RecordCurDirtyStatus()2327 void RSRenderNode::RecordCurDirtyStatus()
2328 {
2329     curDirtyStatus_ = dirtyStatus_;
2330     GetMutableRenderProperties().RecordCurDirtyStatus();
2331 }
2332 
AccmulateDirtyStatus()2333 void RSRenderNode::AccmulateDirtyStatus()
2334 {
2335     GetMutableRenderProperties().AccmulateDirtyStatus();
2336     if (curDirtyStatus_ == NodeDirty::CLEAN) {
2337         return;
2338     }
2339     SetDirty();
2340 }
2341 
ResetAccmulateDirtyStatus()2342 void RSRenderNode::ResetAccmulateDirtyStatus()
2343 {
2344     dirtyStatus_ = NodeDirty::CLEAN;
2345     GetMutableRenderProperties().ResetDirty();
2346 }
2347 
RecordCurDirtyTypes()2348 void RSRenderNode::RecordCurDirtyTypes()
2349 {
2350     for (int i = 0; i < (int)RSModifierType::MAX_RS_MODIFIER_TYPE; i++) {
2351         if (dirtyTypes_.test(static_cast<size_t>(i))) {
2352             continue;
2353         }
2354         curDirtyTypes_.set(static_cast<int>(i), true);
2355     }
2356 }
2357 
AccmulateDirtyTypes()2358 void RSRenderNode::AccmulateDirtyTypes()
2359 {
2360     for (int i = 0; i < (int)RSModifierType::MAX_RS_MODIFIER_TYPE; i++) {
2361         if (curDirtyTypes_.test(static_cast<size_t>(i))) {
2362             continue;
2363         }
2364         dirtyTypes_.set(static_cast<int>(i), true);
2365     }
2366 }
2367 
ResetAccmulateDirtyTypes()2368 void RSRenderNode::ResetAccmulateDirtyTypes()
2369 {
2370     dirtyTypes_.reset();
2371 }
2372 
ApplyPositionZModifier()2373 void RSRenderNode::ApplyPositionZModifier()
2374 {
2375     constexpr auto positionZModifierType = static_cast<size_t>(RSModifierType::POSITION_Z);
2376     if (!dirtyTypes_.test(positionZModifierType)) {
2377         return;
2378     }
2379 
2380     GetMutableRenderProperties().SetPositionZ(0.0f);
2381     RSModifierContext context = { GetMutableRenderProperties() };
2382     for (auto& [id, modifier] : modifiers_) {
2383         if (modifier->GetType() == RSModifierType::POSITION_Z) {
2384             modifier->Apply(context);
2385         }
2386     }
2387 
2388     dirtyTypes_.reset(positionZModifierType);
2389 }
2390 
SetChildHasSharedTransition(bool val)2391 void RSRenderNode::SetChildHasSharedTransition(bool val)
2392 {
2393     childHasSharedTransition_ = val;
2394 }
2395 
ChildHasSharedTransition() const2396 bool RSRenderNode::ChildHasSharedTransition() const
2397 {
2398     return childHasSharedTransition_;
2399 }
2400 
MarkForegroundFilterCache()2401 void RSRenderNode::MarkForegroundFilterCache()
2402 {
2403     if (GetRenderProperties().GetForegroundFilterCache() != nullptr) {
2404         MarkNodeGroup(NodeGroupType::GROUPED_BY_FOREGROUND_FILTER, true, true);
2405     } else if (nodeGroupType_ & NodeGroupType::GROUPED_BY_FOREGROUND_FILTER) { // clear foreground filter cache
2406         MarkNodeGroup(NodeGroupType::GROUPED_BY_FOREGROUND_FILTER, false, false);
2407     }
2408 }
2409 
ApplyModifier(RSModifierContext & context,std::shared_ptr<RSRenderModifier> modifier)2410 void RSRenderNode::ApplyModifier(RSModifierContext& context, std::shared_ptr<RSRenderModifier> modifier)
2411 {
2412     auto modifierType = modifier->GetType();
2413     if (!dirtyTypes_.test(static_cast<size_t>(modifierType))) {
2414         return;
2415     }
2416     modifier->Apply(context);
2417     isOnlyBasicGeoTransform_ = isOnlyBasicGeoTransform_ && BASIC_GEOTRANSFORM_ANIMATION_TYPE.count(modifierType);
2418 }
2419 
ApplyModifiers()2420 void RSRenderNode::ApplyModifiers()
2421 {
2422     RS_LOGI_IF(DEBUG_NODE, "RSRenderNode::apply modifiers isFullChildrenListValid_:%{public}d"
2423         " isChildrenSorted_:%{public}d childrenHasSharedTransition_:%{public}d",
2424         isFullChildrenListValid_, isChildrenSorted_, childrenHasSharedTransition_);
2425     if (UNLIKELY(!isFullChildrenListValid_)) {
2426         GenerateFullChildrenList();
2427         AddDirtyType(RSModifierType::CHILDREN);
2428     } else if (UNLIKELY(!isChildrenSorted_)) {
2429         ResortChildren();
2430         AddDirtyType(RSModifierType::CHILDREN);
2431     } else if (UNLIKELY(childrenHasSharedTransition_)) {
2432         // if children has shared transition, force regenerate RSChildrenDrawable
2433         AddDirtyType(RSModifierType::CHILDREN);
2434     } else if (!RSRenderNode::IsDirty() || dirtyTypes_.none()) {
2435         RS_LOGD("RSRenderNode::apply modifiers RSRenderNode's dirty is false or dirtyTypes_ is none");
2436         // clean node, skip apply
2437         return;
2438     }
2439     RecordCurDirtyTypes();
2440     // Reset and re-apply all modifiers
2441     RSModifierContext context = { GetMutableRenderProperties() };
2442 
2443     // Reset before apply modifiers
2444     GetMutableRenderProperties().ResetProperty(dirtyTypes_);
2445 
2446     // Apply modifiers
2447     auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(shared_from_this());
2448     if (displayNode && displayNode->GetCurrentScbPid() != -1) {
2449         RS_LOGD("RSRenderNode::apply modifiers displayNode's currentScbPid:%{public}d",
2450             displayNode->GetCurrentScbPid());
2451         for (auto& [id, modifier] : modifiers_) {
2452             if (ExtractPid(id) == displayNode->GetCurrentScbPid()) {
2453                 ApplyModifier(context, modifier);
2454             }
2455         }
2456     } else {
2457         RS_LOGD("RSRenderNode::apply modifiers displayNode is nullptr or displayNode's currentScbPid is -1");
2458         for (auto& [id, modifier] : modifiers_) {
2459             ApplyModifier(context, modifier);
2460         }
2461     }
2462     // execute hooks
2463     GetMutableRenderProperties().OnApplyModifiers();
2464     OnApplyModifiers();
2465     MarkForegroundFilterCache();
2466     UpdateShouldPaint();
2467 
2468     if (dirtyTypes_.test(static_cast<size_t>(RSModifierType::USE_EFFECT)) ||
2469         dirtyTypes_.test(static_cast<size_t>(RSModifierType::USE_EFFECT_TYPE))) {
2470         ProcessBehindWindowAfterApplyModifiers();
2471     }
2472 
2473     RS_LOGI_IF(DEBUG_NODE,
2474         "RSRenderNode::apply modifiers RenderProperties's sandBox's hasValue is %{public}d"
2475         " isTextureExportNode_:%{public}d", GetRenderProperties().GetSandBox().has_value(),
2476         isTextureExportNode_);
2477     if (dirtyTypes_.test(static_cast<size_t>(RSModifierType::SANDBOX)) &&
2478         !GetRenderProperties().GetSandBox().has_value() && sharedTransitionParam_) {
2479         auto paramCopy = sharedTransitionParam_;
2480         paramCopy->InternalUnregisterSelf();
2481     }
2482     if (dirtyTypes_.test(static_cast<size_t>(RSModifierType::FOREGROUND_EFFECT_RADIUS))) {
2483         GetMutableRenderProperties().SetForegroundEffectDirty(true);
2484     }
2485 
2486     // Temporary code, copy matrix into render params
2487     if (LIKELY(RSUniRenderJudgement::IsUniRender() && !isTextureExportNode_)) {
2488         UpdateDrawableVecV2();
2489     } else {
2490         UpdateDrawableVec();
2491     }
2492 
2493     UpdateFilterCacheWithBackgroundDirty();
2494 
2495     //Clear node some resource
2496     ClearResource();
2497     // update state
2498     dirtyTypes_.reset();
2499     AddToPendingSyncList();
2500 
2501     // update rate decider scale reference size.
2502     animationManager_.SetRateDeciderScaleSize(GetRenderProperties().GetBoundsWidth(),
2503         GetRenderProperties().GetBoundsHeight());
2504 }
2505 
MarkParentNeedRegenerateChildren() const2506 void RSRenderNode::MarkParentNeedRegenerateChildren() const
2507 {
2508     auto parent = GetParent().lock();
2509     if (parent == nullptr) {
2510         return;
2511     }
2512     parent->isChildrenSorted_ = false;
2513 }
2514 
UpdateDrawableVec()2515 void RSRenderNode::UpdateDrawableVec()
2516 {
2517     // Collect dirty slots
2518     auto dirtySlots = RSPropertyDrawable::GenerateDirtySlots(GetRenderProperties(), dirtyTypes_);
2519     if (!GetIsUsedBySubThread()) {
2520         UpdateDrawableVecInternal(dirtySlots);
2521     } else if (auto context = context_.lock()) {
2522         context->PostTask([weakPtr = weak_from_this(), dirtySlots]() {
2523             if (auto node = weakPtr.lock()) {
2524                 node->UpdateDrawableVecInternal(dirtySlots);
2525             }
2526         });
2527     }
2528 }
2529 
UpdateDrawableVecV2()2530 void RSRenderNode::UpdateDrawableVecV2()
2531 {
2532     // Step 1: Collect dirty slots
2533     auto dirtySlots = RSDrawable::CalculateDirtySlots(dirtyTypes_, drawableVec_);
2534     if (dirtySlots.empty()) {
2535         RS_LOGD("RSRenderNode::update drawable VecV2 dirtySlots is empty");
2536         return;
2537     }
2538     // Step 2: Update or regenerate drawable if needed
2539     bool drawableChanged = RSDrawable::UpdateDirtySlots(*this, drawableVec_, dirtySlots);
2540     // Step 2.1 (optional): fuze some drawables
2541     RSDrawable::FuzeDrawableSlots(*this, drawableVec_);
2542     // If any drawable has changed, or the CLIP_TO_BOUNDS slot has changed, then we need to recalculate
2543     // save/clip/restore.
2544     RS_LOGI_IF(DEBUG_NODE,
2545         "RSRenderNode::update drawable VecV2 drawableChanged:%{public}d", drawableChanged);
2546     if (drawableChanged || dirtySlots.count(RSDrawableSlot::CLIP_TO_BOUNDS)) {
2547         // Step 3: Recalculate save/clip/restore on demands
2548         RSDrawable::UpdateSaveRestore(*this, drawableVec_, drawableVecStatus_);
2549         // if shadow changed, update shadow rect
2550         UpdateShadowRect();
2551         UpdateDirtySlotsAndPendingNodes(RSDrawableSlot::SHADOW);
2552         std::unordered_set<RSDrawableSlot> dirtySlotShadow;
2553         dirtySlotShadow.emplace(RSDrawableSlot::SHADOW);
2554         RSDrawable::UpdateDirtySlots(*this, drawableVec_, dirtySlotShadow);
2555         // Step 4: Generate drawCmdList from drawables
2556         UpdateDisplayList();
2557     }
2558     // Merge dirty slots
2559     if (dirtySlots_.empty()) {
2560         dirtySlots_ = std::move(dirtySlots);
2561     } else {
2562         dirtySlots_.insert(dirtySlots.begin(), dirtySlots.end());
2563     }
2564 }
2565 
UpdateDrawableVecInternal(std::unordered_set<RSPropertyDrawableSlot> dirtySlots)2566 void RSRenderNode::UpdateDrawableVecInternal(std::unordered_set<RSPropertyDrawableSlot> dirtySlots)
2567 {
2568      // initialize necessary save/clip/restore
2569     if (drawableVecStatusV1_ == 0) {
2570         RSPropertyDrawable::InitializeSaveRestore(*renderContent_, renderContent_->propertyDrawablesVec_);
2571     }
2572     // Update or regenerate drawable
2573     bool drawableChanged =
2574         RSPropertyDrawable::UpdateDrawableVec(*renderContent_, renderContent_->propertyDrawablesVec_, dirtySlots);
2575     // if 1. first initialized or 2. any drawables changed, update save/clip/restore
2576     if (drawableChanged || drawableVecStatusV1_ == 0) {
2577         RSPropertyDrawable::UpdateSaveRestore(
2578             *renderContent_, renderContent_->propertyDrawablesVec_, drawableVecStatusV1_);
2579     }
2580 }
2581 
UpdateShadowRect()2582 void RSRenderNode::UpdateShadowRect()
2583 {
2584     if (drawableVec_[static_cast<int8_t>(RSDrawableSlot::SHADOW)] != nullptr &&
2585         GetRenderProperties().GetShadowColorStrategy() != SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE) {
2586         RectI shadowRect;
2587         auto rRect = GetRenderProperties().GetRRect();
2588         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &rRect, false, false);
2589         stagingRenderParams_->SetShadowRect(Drawing::Rect(
2590             static_cast<float>(shadowRect.GetLeft()),
2591             static_cast<float>(shadowRect.GetTop()),
2592             static_cast<float>(shadowRect.GetRight()),
2593             static_cast<float>(shadowRect.GetBottom())));
2594         RS_OPTIONAL_TRACE_NAME_FMT("UpdateShadowRect id:%llu shadowRect:%s",
2595             GetId(), shadowRect.ToString().c_str());
2596     } else {
2597         stagingRenderParams_->SetShadowRect(Drawing::Rect());
2598     }
2599 }
2600 
UpdateDisplayList()2601 void RSRenderNode::UpdateDisplayList()
2602 {
2603 #ifndef ROSEN_ARKUI_X
2604     // Planning: use the mask from DrawableVecStatus in rs_drawable.cpp
2605     constexpr uint8_t FRAME_NOT_EMPTY = 1 << 4;
2606     constexpr uint8_t NODE_NOT_EMPTY = 1 << 5;
2607 
2608     stagingDrawCmdList_.clear();
2609     drawCmdListNeedSync_ = true;
2610 
2611     if (UNLIKELY((drawableVecStatus_ & NODE_NOT_EMPTY) == 0)) {
2612         // NODE_NOT_EMPTY is not set, so nothing to draw, just skip
2613         stagingRenderParams_->SetContentEmpty(IsInstanceOf<RSCanvasRenderNode>());
2614         return;
2615     }
2616 
2617     int8_t index = 0;
2618     // Process all drawables in [index, end], end is included.
2619     // Note: After this loop, index will be end+1
2620     auto AppendDrawFunc = [&](RSDrawableSlot end) -> int8_t {
2621         auto endIndex = static_cast<int8_t>(end);
2622         for (; index <= endIndex; ++index) {
2623             if (const auto& drawable = drawableVec_[index]) {
2624                 stagingDrawCmdList_.emplace_back(drawable->CreateDrawFunc());
2625             }
2626         }
2627         // If the end drawable exist, return its index, otherwise return -1
2628         return drawableVec_[endIndex] != nullptr ? stagingDrawCmdList_.size() - 1 : -1;
2629     };
2630     // Update index of ENV_FOREGROUND_COLOR
2631     stagingDrawCmdIndex_.envForeGroundColorIndex_ = AppendDrawFunc(RSDrawableSlot::ENV_FOREGROUND_COLOR);
2632 
2633     // Update index of SHADOW
2634     stagingDrawCmdIndex_.shadowIndex_ = AppendDrawFunc(RSDrawableSlot::SHADOW);
2635 
2636     AppendDrawFunc(RSDrawableSlot::OUTLINE);
2637     stagingDrawCmdIndex_.renderGroupBeginIndex_ = stagingDrawCmdList_.size();
2638     stagingDrawCmdIndex_.foregroundFilterBeginIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
2639 
2640     // Update index of BACKGROUND_COLOR
2641     stagingDrawCmdIndex_.backgroundColorIndex_ = AppendDrawFunc(RSDrawableSlot::BACKGROUND_COLOR);
2642 
2643     // Update index of BACKGROUND_IMAGE
2644     stagingDrawCmdIndex_.backgroundImageIndex_ = AppendDrawFunc(RSDrawableSlot::BACKGROUND_IMAGE);
2645 
2646     // Update index of BACKGROUND_FILTER
2647     stagingDrawCmdIndex_.backgroundFilterIndex_ = AppendDrawFunc(RSDrawableSlot::BACKGROUND_FILTER);
2648 
2649     // Update index of USE_EFFECT
2650     stagingDrawCmdIndex_.useEffectIndex_ = AppendDrawFunc(RSDrawableSlot::USE_EFFECT);
2651 
2652     AppendDrawFunc(RSDrawableSlot::BG_RESTORE_BOUNDS);
2653 
2654     if (drawableVecStatus_ & FRAME_NOT_EMPTY) {
2655         // Update index of CONTENT_STYLE
2656         stagingDrawCmdIndex_.contentIndex_ = AppendDrawFunc(RSDrawableSlot::CONTENT_STYLE);
2657 
2658         // Update index of BACKGROUND_END
2659         stagingDrawCmdIndex_.backgroundEndIndex_ = stagingDrawCmdIndex_.contentIndex_ == -1
2660             ? static_cast<int8_t>(stagingDrawCmdList_.size()) : stagingDrawCmdIndex_.contentIndex_;
2661 
2662         // Update index of CHILDREN
2663         stagingDrawCmdIndex_.childrenIndex_ = AppendDrawFunc(RSDrawableSlot::CHILDREN);
2664         stagingDrawCmdIndex_.foregroundBeginIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
2665 
2666         AppendDrawFunc(RSDrawableSlot::RESTORE_FRAME);
2667     } else {
2668         // Nothing inside frame, skip useless slots and update indexes
2669         stagingDrawCmdIndex_.contentIndex_ = -1;
2670         stagingDrawCmdIndex_.childrenIndex_ = -1;
2671         stagingDrawCmdIndex_.backgroundEndIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
2672         stagingDrawCmdIndex_.foregroundBeginIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
2673         index = static_cast<int8_t>(RSDrawableSlot::FG_SAVE_BOUNDS);
2674     }
2675     stagingDrawCmdIndex_.renderGroupEndIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
2676 
2677     AppendDrawFunc(RSDrawableSlot::RESTORE_BLENDER);
2678     stagingDrawCmdIndex_.foregroundFilterEndIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
2679     AppendDrawFunc(RSDrawableSlot::RESTORE_ALL);
2680     stagingDrawCmdIndex_.endIndex_ = static_cast<int8_t>(stagingDrawCmdList_.size());
2681     stagingRenderParams_->SetContentEmpty(false);
2682 #endif
2683 }
2684 
UpdateEffectRegion(std::optional<Drawing::RectI> & region,bool isForced)2685 void RSRenderNode::UpdateEffectRegion(std::optional<Drawing::RectI>& region, bool isForced)
2686 {
2687     if (!region.has_value()) {
2688         return;
2689     }
2690     const auto& property = GetRenderProperties();
2691     if (!isForced && !property.GetUseEffect()) {
2692         return;
2693     }
2694 
2695     auto absRect = property.GetBoundsGeometry()->GetAbsRect();
2696     region->Join(Drawing::RectI(absRect.GetLeft(), absRect.GetTop(), absRect.GetRight(), absRect.GetBottom()));
2697 }
2698 
GetModifier(const PropertyId & id)2699 std::shared_ptr<RSRenderModifier> RSRenderNode::GetModifier(const PropertyId& id)
2700 {
2701     if (modifiers_.count(id)) {
2702         return modifiers_[id];
2703     }
2704     for (const auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
2705         auto it = std::find_if(modifiers.begin(), modifiers.end(),
2706             [id](const auto& modifier) -> bool { return modifier->GetPropertyId() == id; });
2707         if (it != modifiers.end()) {
2708             return *it;
2709         }
2710     }
2711     return nullptr;
2712 }
2713 
FilterModifiersByPid(pid_t pid)2714 void RSRenderNode::FilterModifiersByPid(pid_t pid)
2715 {
2716     // remove all modifiers added by given pid (by matching higher 32 bits of node id)
2717     EraseIf(modifiers_, [pid](const auto& pair) -> bool { return ExtractPid(pair.first) == pid; });
2718 
2719     // remove all modifiers added by given pid (by matching higher 32 bits of node id)
2720     for (auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
2721         modifiers.remove_if([pid](const auto& it) -> bool { return ExtractPid(it->GetPropertyId()) == pid; });
2722     }
2723 }
2724 
UpdateShouldPaint()2725 void RSRenderNode::UpdateShouldPaint()
2726 {
2727     // node should be painted if either it is visible or it has disappearing transition animation,
2728     // but only when its alpha is not zero.
2729     // Besides, if one node has sharedTransitionParam, it should be painted no matter what alpha it has.
2730     shouldPaint_ = ((ROSEN_GNE(GetRenderProperties().GetAlpha(), 0.0f)) &&
2731                    (GetRenderProperties().GetVisible() || HasDisappearingTransition(false))) ||
2732                    sharedTransitionParam_;
2733     if (!shouldPaint_ && HasBlurFilter()) { // force clear blur cache
2734         RS_OPTIONAL_TRACE_NAME_FMT("node[%llu] is invisible", GetId());
2735         MarkForceClearFilterCacheWithInvisible();
2736     }
2737 }
2738 
SetSharedTransitionParam(const std::shared_ptr<SharedTransitionParam> & sharedTransitionParam)2739 void RSRenderNode::SetSharedTransitionParam(const std::shared_ptr<SharedTransitionParam>& sharedTransitionParam)
2740 {
2741     if (!sharedTransitionParam_ && !sharedTransitionParam) {
2742         // both are empty, do nothing
2743         return;
2744     }
2745     sharedTransitionParam_ = sharedTransitionParam;
2746     SetDirty();
2747     // tell parent to regenerate children drawable
2748     if (auto parent = parent_.lock()) {
2749         parent->AddDirtyType(RSModifierType::CHILDREN);
2750         parent->SetDirty();
2751     }
2752 }
2753 
GetSharedTransitionParam() const2754 const std::shared_ptr<SharedTransitionParam>& RSRenderNode::GetSharedTransitionParam() const
2755 {
2756     return sharedTransitionParam_;
2757 }
2758 
SetGlobalAlpha(float alpha)2759 void RSRenderNode::SetGlobalAlpha(float alpha)
2760 {
2761     if (globalAlpha_ == alpha) {
2762         return;
2763     }
2764     if ((ROSEN_EQ(globalAlpha_, 1.0f) && !ROSEN_EQ(alpha, 1.0f)) ||
2765         (ROSEN_EQ(alpha, 1.0f) && !ROSEN_EQ(globalAlpha_, 1.0f))) {
2766         OnAlphaChanged();
2767     }
2768     globalAlpha_ = alpha;
2769     stagingRenderParams_->SetGlobalAlpha(alpha);
2770 }
2771 
GetGlobalAlpha() const2772 float RSRenderNode::GetGlobalAlpha() const
2773 {
2774     return globalAlpha_;
2775 }
2776 
SetBootAnimation(bool isBootAnimation)2777 void RSRenderNode::SetBootAnimation(bool isBootAnimation)
2778 {
2779     ROSEN_LOGD("SetBootAnimation:: id:%{public}" PRIu64 "isBootAnimation %{public}d",
2780         GetId(), isBootAnimation);
2781     isBootAnimation_ = isBootAnimation;
2782 }
2783 
GetBootAnimation() const2784 bool RSRenderNode::GetBootAnimation() const
2785 {
2786     return isBootAnimation_;
2787 }
2788 
NeedInitCacheSurface() const2789 bool RSRenderNode::NeedInitCacheSurface() const
2790 {
2791     auto cacheType = GetCacheType();
2792     int width = 0;
2793     int height = 0;
2794     if (cacheType == CacheType::ANIMATE_PROPERTY && GetRenderProperties().IsShadowValid() &&
2795         !GetRenderProperties().IsSpherizeValid() && !GetRenderProperties().IsAttractionValid()) {
2796         const RectF boundsRect = GetRenderProperties().GetBoundsRect();
2797         RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
2798         RectI shadowRect;
2799         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &rrect, false);
2800         width = shadowRect.GetWidth();
2801         height = shadowRect.GetHeight();
2802     } else {
2803         Vector2f size = GetOptionalBufferSize();
2804         width =  size.x_;
2805         height = size.y_;
2806     }
2807     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2808     if (cacheSurface_ == nullptr) {
2809         return true;
2810     }
2811     auto cacheCanvas = cacheSurface_->GetCanvas();
2812     if (cacheCanvas == nullptr) {
2813         return true;
2814     }
2815     return cacheCanvas->GetWidth() != width || cacheCanvas->GetHeight() != height;
2816 }
2817 
NeedInitCacheCompletedSurface() const2818 bool RSRenderNode::NeedInitCacheCompletedSurface() const
2819 {
2820     Vector2f size = GetOptionalBufferSize();
2821     int width = static_cast<int>(size.x_);
2822     int height = static_cast<int>(size.y_);
2823     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2824     if (cacheCompletedSurface_ == nullptr) {
2825         return true;
2826     }
2827     auto cacheCanvas = cacheCompletedSurface_->GetCanvas();
2828     if (cacheCanvas == nullptr) {
2829         return true;
2830     }
2831     return cacheCanvas->GetWidth() != width || cacheCanvas->GetHeight() != height;
2832 }
2833 
InitCacheSurface(Drawing::GPUContext * gpuContext,ClearCacheSurfaceFunc func,uint32_t threadIndex)2834 void RSRenderNode::InitCacheSurface(Drawing::GPUContext* gpuContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
2835 {
2836     RS_TRACE_NAME_FMT("InitCacheSurface");
2837     if (func) {
2838         cacheSurfaceThreadIndex_ = threadIndex;
2839         if (!clearCacheSurfaceFunc_) {
2840             clearCacheSurfaceFunc_ = func;
2841         }
2842         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2843         if (cacheSurface_) {
2844             func(std::move(cacheSurface_), nullptr,
2845                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
2846             cacheSurface_ = nullptr;
2847         }
2848     } else {
2849         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2850         cacheSurface_ = nullptr;
2851     }
2852 #ifdef RS_ENABLE_VK
2853     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
2854         OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
2855         cacheCleanupHelper_ = nullptr;
2856     }
2857 #endif
2858     auto cacheType = GetCacheType();
2859     float width = 0.0f, height = 0.0f;
2860     Vector2f size = GetOptionalBufferSize();
2861     boundsWidth_ = size.x_;
2862     boundsHeight_ = size.y_;
2863     if (cacheType == CacheType::ANIMATE_PROPERTY && GetRenderProperties().IsShadowValid() &&
2864         !GetRenderProperties().IsSpherizeValid() && !GetRenderProperties().IsAttractionValid()) {
2865         const RectF boundsRect = GetRenderProperties().GetBoundsRect();
2866         RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
2867         RectI shadowRect;
2868         RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &rrect, false);
2869         width = shadowRect.GetWidth();
2870         height = shadowRect.GetHeight();
2871         shadowRectOffsetX_ = -shadowRect.GetLeft();
2872         shadowRectOffsetY_ = -shadowRect.GetTop();
2873     } else {
2874         width = boundsWidth_;
2875         height = boundsHeight_;
2876     }
2877 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
2878     if (gpuContext == nullptr) {
2879         if (func) {
2880             std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2881             func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
2882                 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
2883             ClearCacheSurface();
2884         }
2885         return;
2886     }
2887 #ifdef RS_ENABLE_GL
2888     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
2889         OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
2890         Drawing::ImageInfo info = Drawing::ImageInfo::MakeN32Premul(width, height);
2891         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2892         cacheSurface_ = Drawing::Surface::MakeRenderTarget(gpuContext, true, info);
2893     }
2894 #endif
2895 #ifdef RS_ENABLE_VK
2896     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
2897         OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
2898         auto initCacheBackendTexture = MakeBackendTexture(width, height);
2899         auto vkTextureInfo = initCacheBackendTexture.GetTextureInfo().GetVKTextureInfo();
2900         if (!initCacheBackendTexture.IsValid() || !vkTextureInfo) {
2901             if (func) {
2902                 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2903                 func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
2904                     cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
2905                 ClearCacheSurface();
2906             }
2907             return;
2908         }
2909         auto initCacheCleanupHelper = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
2910             vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory, vkTextureInfo->vkAlloc.statName);
2911         auto initCacheSurface = Drawing::Surface::MakeFromBackendTexture(
2912             gpuContext, initCacheBackendTexture.GetTextureInfo(), Drawing::TextureOrigin::BOTTOM_LEFT,
2913             1, Drawing::ColorType::COLORTYPE_RGBA_8888, nullptr,
2914             NativeBufferUtils::DeleteVkImage, initCacheCleanupHelper);
2915         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2916         cacheBackendTexture_ = initCacheBackendTexture;
2917         cacheCleanupHelper_ = initCacheCleanupHelper;
2918         cacheSurface_ = initCacheSurface;
2919     }
2920 #endif
2921 #else
2922     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2923     cacheSurface_ = Drawing::Surface::MakeRasterN32Premul(width, height);
2924 #endif
2925 }
2926 
IsCacheSurfaceValid() const2927 bool RSRenderNode::IsCacheSurfaceValid() const
2928 {
2929     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2930     return  (cacheSurface_ != nullptr);
2931 }
2932 
IsCacheCompletedSurfaceValid() const2933 bool RSRenderNode::IsCacheCompletedSurfaceValid() const
2934 {
2935     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2936     return  (cacheCompletedSurface_ != nullptr);
2937 }
2938 
GetOptionalBufferSize() const2939 Vector2f RSRenderNode::GetOptionalBufferSize() const
2940 {
2941     const auto& modifier = boundsModifier_ ? boundsModifier_ : frameModifier_;
2942     if (!modifier) {
2943         return {0.0f, 0.0f};
2944     }
2945     auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(modifier->GetProperty());
2946     auto vector4f = renderProperty->Get();
2947     // bounds vector4f: x y z w -> left top width height
2948     return { vector4f.z_, vector4f.w_ };
2949 }
2950 
DrawCacheSurface(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)2951 void RSRenderNode::DrawCacheSurface(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
2952 {
2953     if (ROSEN_EQ(boundsWidth_, 0.f) || ROSEN_EQ(boundsHeight_, 0.f)) {
2954         return;
2955     }
2956     auto cacheType = GetCacheType();
2957     canvas.Save();
2958     Vector2f size = GetOptionalBufferSize();
2959     float scaleX = size.x_ / boundsWidth_;
2960     float scaleY = size.y_ / boundsHeight_;
2961     canvas.Scale(scaleX, scaleY);
2962     auto cacheImage = GetCompletedImage(canvas, threadIndex, isUIFirst);
2963     if (cacheImage == nullptr) {
2964         canvas.Restore();
2965         return;
2966     }
2967     if (RSSystemProperties::GetRecordingEnabled()) {
2968         if (cacheImage->IsTextureBacked()) {
2969             RS_LOGI("RSRenderNode::DrawCacheSurface convert cacheImage from texture to raster image");
2970             cacheImage = cacheImage->MakeRasterImage();
2971             if (!cacheImage) {
2972                 RS_LOGE("RSRenderNode::DrawCacheSurface: MakeRasterImage failed");
2973                 canvas.Restore();
2974                 return;
2975             }
2976         }
2977     }
2978     Drawing::Brush brush;
2979     canvas.AttachBrush(brush);
2980     auto samplingOptions = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
2981     if ((cacheType == CacheType::ANIMATE_PROPERTY && GetRenderProperties().IsShadowValid()) || isUIFirst) {
2982         auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
2983         Vector2f gravityTranslate = surfaceNode ?
2984             surfaceNode->GetGravityTranslate(cacheImage->GetWidth(), cacheImage->GetHeight()) : Vector2f(0.0f, 0.0f);
2985         canvas.DrawImage(*cacheImage, -shadowRectOffsetX_ * scaleX + gravityTranslate.x_,
2986             -shadowRectOffsetY_ * scaleY + gravityTranslate.y_, samplingOptions);
2987     } else {
2988         if (canvas.GetTotalMatrix().HasPerspective()) {
2989             // In case of perspective transformation, make dstRect 1px outset to anti-alias
2990             Drawing::Rect dst(0, 0, cacheImage->GetWidth(), cacheImage->GetHeight());
2991             dst.MakeOutset(1, 1);
2992             canvas.DrawImageRect(*cacheImage, dst, samplingOptions);
2993         } else {
2994             canvas.DrawImage(*cacheImage, 0.0, 0.0, samplingOptions);
2995         }
2996     }
2997     canvas.DetachBrush();
2998     canvas.Restore();
2999 }
3000 
GetCompletedImage(RSPaintFilterCanvas & canvas,uint32_t threadIndex,bool isUIFirst)3001 std::shared_ptr<Drawing::Image> RSRenderNode::GetCompletedImage(
3002     RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
3003 {
3004     if (isUIFirst) {
3005 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3006         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3007         if (!cacheCompletedBackendTexture_.IsValid()) {
3008             RS_LOGE("invalid grBackendTexture_");
3009             return nullptr;
3010         }
3011 #ifdef RS_ENABLE_VK
3012         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3013             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3014             if (!cacheCompletedSurface_ || !cacheCompletedCleanupHelper_) {
3015                 return nullptr;
3016             }
3017         }
3018 #endif
3019         if (canvas.GetGPUContext() == nullptr) {
3020             RS_LOGE("canvas GetGPUContext failed");
3021             return nullptr;
3022         }
3023         auto image = std::make_shared<Drawing::Image>();
3024         Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
3025         Drawing::BitmapFormat info = Drawing::BitmapFormat{ Drawing::COLORTYPE_RGBA_8888,
3026             Drawing::ALPHATYPE_PREMUL };
3027 #ifdef RS_ENABLE_GL
3028         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
3029             OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
3030             image->BuildFromTexture(*canvas.GetGPUContext(), cacheCompletedBackendTexture_.GetTextureInfo(),
3031                 origin, info, nullptr);
3032         }
3033 #endif
3034 
3035 #ifdef RS_ENABLE_VK
3036         if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3037             OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3038             image->BuildFromTexture(*canvas.GetGPUContext(), cacheCompletedBackendTexture_.GetTextureInfo(),
3039                 origin, info, nullptr,
3040                 NativeBufferUtils::DeleteVkImage, cacheCompletedCleanupHelper_->Ref());
3041         }
3042 #endif
3043         return image;
3044 #endif
3045     }
3046 
3047     if (!cacheCompletedSurface_) {
3048         RS_LOGE("DrawCacheSurface invalid cacheCompletedSurface");
3049         return nullptr;
3050     }
3051     auto completeImage = cacheCompletedSurface_->GetImageSnapshot();
3052     if (!completeImage) {
3053         RS_LOGE("Get complete image failed");
3054         return nullptr;
3055     }
3056     if (threadIndex == completedSurfaceThreadIndex_) {
3057         return completeImage;
3058     }
3059 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3060     Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
3061     auto backendTexture = completeImage->GetBackendTexture(false, &origin);
3062     if (!backendTexture.IsValid()) {
3063         RS_LOGE("get backendTexture failed");
3064         return nullptr;
3065     }
3066     auto cacheImage = std::make_shared<Drawing::Image>();
3067     Drawing::BitmapFormat info =
3068         Drawing::BitmapFormat{ completeImage->GetColorType(), completeImage->GetAlphaType() };
3069     if (canvas.GetGPUContext() == nullptr) {
3070         RS_LOGE("canvas GetGPUContext failed");
3071         return nullptr;
3072     }
3073     bool ret = cacheImage->BuildFromTexture(*canvas.GetGPUContext(), backendTexture.GetTextureInfo(),
3074         origin, info, nullptr);
3075     if (!ret) {
3076         RS_LOGE("RSRenderNode::GetCompletedImage image BuildFromTexture failed");
3077         return nullptr;
3078     }
3079     return cacheImage;
3080 #else
3081     return completeImage;
3082 #endif
3083 }
3084 
3085 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
UpdateBackendTexture()3086 void RSRenderNode::UpdateBackendTexture()
3087 {
3088     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3089     if (cacheSurface_ == nullptr) {
3090         return;
3091     }
3092     cacheBackendTexture_ = cacheSurface_->GetBackendTexture();
3093 }
3094 #endif
3095 
GetCompletedCacheSurface(uint32_t threadIndex,bool needCheckThread,bool releaseAfterGet)3096 std::shared_ptr<Drawing::Surface> RSRenderNode::GetCompletedCacheSurface(uint32_t threadIndex, bool needCheckThread,
3097     bool releaseAfterGet)
3098 {
3099     {
3100         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3101         if (releaseAfterGet) {
3102 #ifdef RS_ENABLE_VK
3103             if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3104                 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3105                 cacheCompletedCleanupHelper_ = nullptr;
3106             }
3107 #endif
3108             return cacheCompletedSurface_;
3109         }
3110         if (!needCheckThread || completedSurfaceThreadIndex_ == threadIndex || !cacheCompletedSurface_) {
3111             return cacheCompletedSurface_;
3112         }
3113     }
3114 
3115     // freeze cache scene
3116     ClearCacheSurfaceInThread();
3117     return nullptr;
3118 }
3119 
ClearCacheSurfaceInThread()3120 void RSRenderNode::ClearCacheSurfaceInThread()
3121 {
3122     if (clearCacheSurfaceFunc_) {
3123         clearCacheSurfaceFunc_(std::move(cacheSurface_), std::move(cacheCompletedSurface_), cacheSurfaceThreadIndex_,
3124             completedSurfaceThreadIndex_);
3125     }
3126     ClearCacheSurface();
3127 }
3128 
GetCacheSurface(uint32_t threadIndex,bool needCheckThread,bool releaseAfterGet)3129 std::shared_ptr<Drawing::Surface> RSRenderNode::GetCacheSurface(uint32_t threadIndex, bool needCheckThread,
3130     bool releaseAfterGet)
3131 {
3132     {
3133         std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3134         if (releaseAfterGet) {
3135 #ifdef RS_ENABLE_VK
3136             if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
3137                 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
3138                 cacheCleanupHelper_ = nullptr;
3139             }
3140 #endif
3141             return std::move(cacheSurface_);
3142         }
3143         if (!needCheckThread || cacheSurfaceThreadIndex_ == threadIndex || !cacheSurface_) {
3144             return cacheSurface_;
3145         }
3146     }
3147 
3148     // freeze cache scene
3149     ClearCacheSurfaceInThread();
3150     return nullptr;
3151 }
3152 
CheckGroupableAnimation(const PropertyId & id,bool isAnimAdd)3153 void RSRenderNode::CheckGroupableAnimation(const PropertyId& id, bool isAnimAdd)
3154 {
3155     if (id <= 0 || GetType() != RSRenderNodeType::CANVAS_NODE) {
3156         return;
3157     }
3158     auto context = GetContext().lock();
3159     if (!RSSystemProperties::GetAnimationCacheEnabled() ||
3160         !context || !context->GetNodeMap().IsResidentProcessNode(GetId())) {
3161         return;
3162     }
3163     auto target = modifiers_.find(id);
3164     if (target == modifiers_.end() || !target->second) {
3165         return;
3166     }
3167     if (isAnimAdd) {
3168         if (GROUPABLE_ANIMATION_TYPE.count(target->second->GetType())) {
3169             MarkNodeGroup(NodeGroupType::GROUPED_BY_ANIM, true, false);
3170         } else if (CACHEABLE_ANIMATION_TYPE.count(target->second->GetType())) {
3171             hasCacheableAnim_ = true;
3172         }
3173         return;
3174     }
3175     bool hasGroupableAnim = false;
3176     hasCacheableAnim_ = false;
3177     for (auto& [_, animation] : animationManager_.animations_) {
3178         if (!animation || id == animation->GetPropertyId()) {
3179             continue;
3180         }
3181         auto itr = modifiers_.find(animation->GetPropertyId());
3182         if (itr == modifiers_.end() || !itr->second) {
3183             continue;
3184         }
3185         hasGroupableAnim = (hasGroupableAnim || (GROUPABLE_ANIMATION_TYPE.count(itr->second->GetType()) != 0));
3186         hasCacheableAnim_ = (hasCacheableAnim_ || (CACHEABLE_ANIMATION_TYPE.count(itr->second->GetType()) != 0));
3187     }
3188     MarkNodeGroup(NodeGroupType::GROUPED_BY_ANIM, hasGroupableAnim, false);
3189 }
3190 
IsForcedDrawInGroup() const3191 bool RSRenderNode::IsForcedDrawInGroup() const
3192 {
3193     return nodeGroupType_ & NodeGroupType::GROUPED_BY_USER;
3194 }
3195 
IsSuggestedDrawInGroup() const3196 bool RSRenderNode::IsSuggestedDrawInGroup() const
3197 {
3198     return nodeGroupType_ != NodeGroupType::NONE;
3199 }
3200 
MarkNodeGroup(NodeGroupType type,bool isNodeGroup,bool includeProperty)3201 void RSRenderNode::MarkNodeGroup(NodeGroupType type, bool isNodeGroup, bool includeProperty)
3202 {
3203     RS_OPTIONAL_TRACE_NAME_FMT("MarkNodeGroup type:%d isNodeGroup:%d id:%llu", type, isNodeGroup, GetId());
3204     RS_LOGI_IF(DEBUG_NODE, "RSRenderNode::MarkNodeGP type:%{public}d isNodeGroup:%{public}d id:%{public}" PRIu64,
3205         type, isNodeGroup, GetId());
3206     if (isNodeGroup && type == NodeGroupType::GROUPED_BY_UI) {
3207         auto context = GetContext().lock();
3208         if (context && context->GetNodeMap().IsResidentProcessNode(GetId())) {
3209             nodeGroupType_ |= type;
3210             SetDirty();
3211             stagingRenderParams_->SetDirtyType(RSRenderParamsDirtyType::DRAWING_CACHE_TYPE_DIRTY);
3212         }
3213     } else {
3214         if (isNodeGroup) {
3215             nodeGroupType_ |= type;
3216         } else {
3217             nodeGroupType_ &= ~type;
3218         }
3219         SetDirty();
3220         stagingRenderParams_->SetDirtyType(RSRenderParamsDirtyType::DRAWING_CACHE_TYPE_DIRTY);
3221     }
3222     if (nodeGroupType_ == static_cast<uint8_t>(NodeGroupType::NONE) && !isNodeGroup) {
3223         needClearSurface_ = true;
3224     }
3225     nodeGroupIncludeProperty_ = includeProperty;
3226 #ifdef ROSEN_PREVIEW
3227     if (type == NodeGroupType::GROUPED_BY_USER) {
3228         dirtyTypes_.set(static_cast<int>(RSModifierType::ALPHA), true);
3229         GetMutableRenderProperties().SetAlphaOffscreen(isNodeGroup);
3230     }
3231 #endif
3232     AddToPendingSyncList();
3233 }
3234 
IsNodeGroupIncludeProperty() const3235 bool RSRenderNode::IsNodeGroupIncludeProperty() const
3236 {
3237     return nodeGroupIncludeProperty_;
3238 }
3239 
MarkNodeSingleFrameComposer(bool isNodeSingleFrameComposer,pid_t pid)3240 void RSRenderNode::MarkNodeSingleFrameComposer(bool isNodeSingleFrameComposer, pid_t pid)
3241 {
3242     isNodeSingleFrameComposer_ = isNodeSingleFrameComposer;
3243     appPid_ = pid;
3244 }
3245 
GetNodeIsSingleFrameComposer() const3246 bool RSRenderNode::GetNodeIsSingleFrameComposer() const
3247 {
3248     return isNodeSingleFrameComposer_;
3249 }
3250 
CheckDrawingCacheType()3251 void RSRenderNode::CheckDrawingCacheType()
3252 {
3253     if (nodeGroupType_ == NodeGroupType::NONE) {
3254         SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
3255     } else if (nodeGroupType_ & NodeGroupType::GROUPED_BY_FOREGROUND_FILTER) {
3256         SetDrawingCacheType(RSDrawingCacheType::FOREGROUND_FILTER_CACHE);
3257     } else if (nodeGroupType_ & NodeGroupType::GROUPED_BY_USER) {
3258         SetDrawingCacheType(RSDrawingCacheType::FORCED_CACHE);
3259     } else {
3260         SetDrawingCacheType(RSDrawingCacheType::TARGETED_CACHE);
3261     }
3262 }
3263 
3264 #ifdef RS_ENABLE_STACK_CULLING
SetFullSurfaceOpaqueMarks(const std::shared_ptr<RSRenderNode> curSurfaceNodeParam)3265 void RSRenderNode::SetFullSurfaceOpaqueMarks(const std::shared_ptr<RSRenderNode> curSurfaceNodeParam)
3266 {
3267     if (!isFullSurfaceOpaquCanvasNode_) {
3268         int32_t tempValue = coldDownCounter_;
3269         coldDownCounter_ = (coldDownCounter_ + 1) % MAX_COLD_DOWN_NUM;
3270         if (tempValue != 0) {
3271             return;
3272         }
3273     } else {
3274         coldDownCounter_ = 0;
3275     }
3276 
3277     isFullSurfaceOpaquCanvasNode_ = false;
3278     if (!ROSEN_EQ(GetGlobalAlpha(), 1.0f) || HasFilter()) {
3279         return;
3280     }
3281 
3282     if (GetRenderProperties().GetBackgroundColor().GetAlpha() < 255) {
3283         return;
3284     }
3285 
3286     if (!curSurfaceNodeParam) {
3287         return;
3288     }
3289 
3290     auto curSurfaceNode = std::static_pointer_cast<RSSurfaceRenderNode>(curSurfaceNodeParam);
3291     auto surfaceNodeAbsRect = curSurfaceNode->GetOldDirty();
3292     auto absRect = GetFilterRect();
3293     if (surfaceNodeAbsRect.IsInsideOf(absRect)) {
3294         isFullSurfaceOpaquCanvasNode_ = true;
3295 
3296         auto rsParent = GetParent().lock();
3297         while (rsParent) {
3298             //skip when another child has set its parent or reach rootnode
3299             if (rsParent->hasChildFullSurfaceOpaquCanvasNode_) {
3300                 break;
3301             }
3302 
3303             rsParent->hasChildFullSurfaceOpaquCanvasNode_ = true;
3304             if (rsParent->IsInstanceOf<RSRootRenderNode>()) {
3305                 break;
3306             }
3307 
3308             rsParent = rsParent->GetParent().lock();
3309         }
3310     }
3311 }
3312 
SetSubNodesCovered()3313 void RSRenderNode::SetSubNodesCovered()
3314 {
3315     if (hasChildFullSurfaceOpaquCanvasNode_) {
3316         auto sortedChildren_ = GetSortedChildren();
3317         if (sortedChildren_->size() <= 1) {
3318             return;
3319         }
3320 
3321         bool found = false;
3322         for (auto child = sortedChildren_->rbegin(); child != sortedChildren_->rend(); child++) {
3323             if (!found && ((*child)->isFullSurfaceOpaquCanvasNode_ || (*child)->hasChildFullSurfaceOpaquCanvasNode_)) {
3324                 found = true;
3325                 continue;
3326             }
3327             if (found) {
3328                 (*child)->isCoveredByOtherNode_ = true;
3329             }
3330         }
3331     }
3332 }
ResetSubNodesCovered()3333 void RSRenderNode::ResetSubNodesCovered()
3334 {
3335     hasChildFullSurfaceOpaquCanvasNode_ = false;
3336 }
3337 #endif
3338 
ResetFilterRectsInCache(const std::unordered_set<NodeId> & curRects)3339 void RSRenderNode::ResetFilterRectsInCache(const std::unordered_set<NodeId>& curRects)
3340 {
3341     curCacheFilterRects_ = curRects;
3342 }
3343 
GetFilterRectsInCache(std::unordered_map<NodeId,std::unordered_set<NodeId>> & allRects) const3344 void RSRenderNode::GetFilterRectsInCache(std::unordered_map<NodeId, std::unordered_set<NodeId>>& allRects) const
3345 {
3346     if (!curCacheFilterRects_.empty()) {
3347         allRects.emplace(GetId(), curCacheFilterRects_);
3348     }
3349 }
3350 
IsFilterRectsInCache() const3351 bool RSRenderNode::IsFilterRectsInCache() const
3352 {
3353     return !curCacheFilterRects_.empty();
3354 }
3355 
GetFilterRect() const3356 RectI RSRenderNode::GetFilterRect() const
3357 {
3358     auto& properties = GetRenderProperties();
3359     auto& geoPtr = (properties.GetBoundsGeometry());
3360     if (!geoPtr) {
3361         return {};
3362     }
3363     if (properties.GetClipBounds() != nullptr) {
3364         auto filterRect = properties.GetClipBounds()->GetDrawingPath().GetBounds();
3365         Drawing::Rect absRect;
3366         geoPtr->GetAbsMatrix().MapRect(absRect, filterRect);
3367         return {absRect.GetLeft(), absRect.GetTop(), absRect.GetWidth(), absRect.GetHeight()};
3368     } else {
3369         return geoPtr->GetAbsRect();
3370     }
3371 }
3372 
CalVisibleFilterRect(const std::optional<RectI> & clipRect)3373 void RSRenderNode::CalVisibleFilterRect(const std::optional<RectI>& clipRect)
3374 {
3375     filterRegion_ = GetFilterRect();
3376     if (clipRect.has_value()) {
3377         filterRegion_ = filterRegion_.IntersectRect(*clipRect);
3378     }
3379 }
3380 
UpdateFullScreenFilterCacheRect(RSDirtyRegionManager & dirtyManager,bool isForeground) const3381 void RSRenderNode::UpdateFullScreenFilterCacheRect(
3382     RSDirtyRegionManager& dirtyManager, bool isForeground) const
3383 {
3384 }
3385 
OnTreeStateChanged()3386 void RSRenderNode::OnTreeStateChanged()
3387 {
3388     if (!isOnTheTree_) {
3389         startingWindowFlag_ = false;
3390     }
3391     if (isOnTheTree_) {
3392         // Set dirty and force add to active node list, re-generate children list if needed
3393         SetDirty(true);
3394         SetParentSubTreeDirty();
3395     } else if (sharedTransitionParam_) {
3396         // Mark shared transition unpaired, and mark paired node dirty
3397         sharedTransitionParam_->paired_ = false;
3398         if (auto pairedNode = sharedTransitionParam_->GetPairedNode(id_)) {
3399             pairedNode->SetDirty(true);
3400         }
3401     }
3402     if (!isOnTheTree_ && HasBlurFilter()) { // force clear blur cache
3403         RS_OPTIONAL_TRACE_NAME_FMT("node[%llu] off the tree", GetId());
3404         MarkForceClearFilterCacheWithInvisible();
3405     }
3406     // Clear fullChildrenList_ and RSChildrenDrawable of the parent node; otherwise, it may cause a memory leak.
3407     if (!isOnTheTree_) {
3408         isFullChildrenListValid_ = false;
3409         std::atomic_store_explicit(&fullChildrenList_, EmptyChildrenList, std::memory_order_release);
3410         drawableVec_[static_cast<int8_t>(RSDrawableSlot::CHILDREN)].reset();
3411         stagingDrawCmdList_.clear();
3412         drawCmdListNeedSync_ = true;
3413         uifirstNeedSync_ = true;
3414         AddToPendingSyncList();
3415     }
3416     auto& properties = GetMutableRenderProperties();
3417     bool useEffect = properties.GetUseEffect();
3418     UseEffectType useEffectType = static_cast<UseEffectType>(properties.GetUseEffectType());
3419     if (useEffect && useEffectType == UseEffectType::BEHIND_WINDOW) {
3420         ProcessBehindWindowOnTreeStateChanged();
3421     }
3422 }
3423 
HasDisappearingTransition(bool recursive) const3424 bool RSRenderNode::HasDisappearingTransition(bool recursive) const
3425 {
3426     if (!isOnTheTree_) {
3427         return false;
3428     }
3429     if (disappearingTransitionCount_ > 0) {
3430         return true;
3431     }
3432     if (recursive == false) {
3433         return false;
3434     }
3435     auto parent = GetParent().lock();
3436     if (parent == nullptr) {
3437         return false;
3438     }
3439     return parent->HasDisappearingTransition(true);
3440 }
3441 
GetChildren() const3442 RSRenderNode::ChildrenListSharedPtr RSRenderNode::GetChildren() const
3443 {
3444     return std::atomic_load_explicit(&fullChildrenList_, std::memory_order_acquire);
3445 }
3446 
GetSortedChildren() const3447 RSRenderNode::ChildrenListSharedPtr RSRenderNode::GetSortedChildren() const
3448 {
3449     return std::atomic_load_explicit(&fullChildrenList_, std::memory_order_acquire);
3450 }
3451 
GetFirstChild() const3452 std::shared_ptr<RSRenderNode> RSRenderNode::GetFirstChild() const
3453 {
3454     return children_.empty() ? nullptr : children_.front().lock();
3455 }
3456 
GenerateFullChildrenList()3457 void RSRenderNode::GenerateFullChildrenList()
3458 {
3459     // both children_ and disappearingChildren_ are empty, no need to generate fullChildrenList_
3460     if (children_.empty() && disappearingChildren_.empty()) {
3461         auto prevFullChildrenList = fullChildrenList_;
3462         isFullChildrenListValid_ = true;
3463         isChildrenSorted_ = true;
3464         std::atomic_store_explicit(&fullChildrenList_, EmptyChildrenList, std::memory_order_release);
3465         return;
3466     }
3467 
3468     // Step 0: Initialize
3469     auto fullChildrenList = std::make_shared<std::vector<std::shared_ptr<RSRenderNode>>>();
3470 
3471     // Step 1: Copy all children into sortedChildren while checking and removing expired children.
3472     children_.remove_if([&](const auto& child) -> bool {
3473         auto existingChild = child.lock();
3474         if (existingChild == nullptr) {
3475             ROSEN_LOGI("RSRenderNode::GenerateSortedChildren removing expired child, this is rare but possible.");
3476             return true;
3477         }
3478         if (isContainBootAnimation_ && !existingChild->GetBootAnimation()) {
3479             ROSEN_LOGD("RSRenderNode::GenerateSortedChildren %{public}" PRIu64 " skip"
3480             " move not bootAnimation displaynode"
3481             "child(id %{public}" PRIu64 ")"" into children_", GetId(), existingChild->GetId());
3482             return false;
3483         }
3484         fullChildrenList->emplace_back(std::move(existingChild));
3485         return false;
3486     });
3487 
3488     // Step 2: Insert disappearing children into sortedChildren at their original position.
3489     // Note:
3490     //     1. We don't need to check if the disappearing transition is finished; it's already handled in
3491     //     RSRenderTransition::OnDetach.
3492     //     2. We don't need to check if the disappearing child is expired; it's already been checked when moving from
3493     //     children_ to disappearingChildren_. We hold ownership of the shared_ptr of the child after that.
3494     std::for_each(disappearingChildren_.begin(), disappearingChildren_.end(), [&](const auto& pair) -> void {
3495         auto& disappearingChild = pair.first;
3496         if (isContainBootAnimation_ && !disappearingChild->GetBootAnimation()) {
3497             ROSEN_LOGD("RSRenderNode::GenerateSortedChildren %{public}" PRIu64 " skip"
3498             " move not bootAnimation displaynode"
3499             "child(id %{public}" PRIu64 ")"" into disappearingChild", GetId(), disappearingChild->GetId());
3500             return;
3501         }
3502         fullChildrenList->emplace_back(disappearingChild);
3503     });
3504 
3505     // temporary fix for wrong z-order
3506     for (auto& child : *fullChildrenList) {
3507         child->ApplyPositionZModifier();
3508     }
3509 
3510     // Step 3: Sort all children by z-order
3511     std::stable_sort(
3512         fullChildrenList->begin(), fullChildrenList->end(), [](const auto& first, const auto& second) -> bool {
3513         return first->GetRenderProperties().GetPositionZ() < second->GetRenderProperties().GetPositionZ();
3514     });
3515 
3516     // Keep a reference to fullChildrenList_ to prevent its deletion when swapping it
3517     auto prevFullChildrenList = fullChildrenList_;
3518 
3519     // Update the flag to indicate that children are now valid and sorted
3520     isFullChildrenListValid_ = true;
3521     isChildrenSorted_ = true;
3522 
3523     // Move the fullChildrenList to fullChildrenList_ atomically
3524     ChildrenListSharedPtr constFullChildrenList = std::move(fullChildrenList);
3525     std::atomic_store_explicit(&fullChildrenList_, constFullChildrenList, std::memory_order_release);
3526 }
3527 
ResortChildren()3528 void RSRenderNode::ResortChildren()
3529 {
3530     // Make a copy of the fullChildrenList for sorting
3531     auto fullChildrenList = std::make_shared<std::vector<std::shared_ptr<RSRenderNode>>>(*fullChildrenList_);
3532 
3533     // temporary fix for wrong z-order
3534     for (auto& child : *fullChildrenList) {
3535         child->ApplyPositionZModifier();
3536     }
3537 
3538     // Sort the children by their z-order
3539     std::stable_sort(
3540         fullChildrenList->begin(), fullChildrenList->end(), [](const auto& first, const auto& second) -> bool {
3541         return first->GetRenderProperties().GetPositionZ() < second->GetRenderProperties().GetPositionZ();
3542     });
3543 
3544     // Keep a reference to fullChildrenList_ to prevent its deletion when swapping it
3545     auto prevFullChildrenList = fullChildrenList_;
3546 
3547     // Update the flag to indicate that children are now sorted
3548     isChildrenSorted_ = true;
3549 
3550     // Move the fullChildrenList to fullChildrenList_ atomically
3551     ChildrenListSharedPtr constFullChildrenList = std::move(fullChildrenList);
3552     std::atomic_store_explicit(&fullChildrenList_, constFullChildrenList, std::memory_order_release);
3553 }
3554 
GetChildrenCount() const3555 uint32_t RSRenderNode::GetChildrenCount() const
3556 {
3557     return children_.size();
3558 }
3559 
SetTunnelHandleChange(bool change)3560 void RSRenderNode::SetTunnelHandleChange(bool change)
3561 {
3562     isTunnelHandleChange_ = change;
3563 }
GetTunnelHandleChange() const3564 bool RSRenderNode::GetTunnelHandleChange() const
3565 {
3566     return isTunnelHandleChange_;
3567 }
HasChildrenOutOfRect() const3568 bool RSRenderNode::HasChildrenOutOfRect() const
3569 {
3570     if (GetRenderProperties().GetClipToBounds() || GetRenderProperties().GetClipToFrame()) {
3571         return false;
3572     }
3573     return hasChildrenOutOfRect_;
3574 }
UpdateChildrenOutOfRectFlag(bool flag)3575 void RSRenderNode::UpdateChildrenOutOfRectFlag(bool flag)
3576 {
3577     hasChildrenOutOfRect_ = flag;
3578 }
ResetHasRemovedChild()3579 void RSRenderNode::ResetHasRemovedChild()
3580 {
3581     hasRemovedChild_ = false;
3582 }
HasRemovedChild() const3583 bool RSRenderNode::HasRemovedChild() const
3584 {
3585     return hasRemovedChild_;
3586 }
GetChildrenRect() const3587 RectI RSRenderNode::GetChildrenRect() const
3588 {
3589     return childrenRect_;
3590 }
ChildHasVisibleFilter() const3591 bool RSRenderNode::ChildHasVisibleFilter() const
3592 {
3593     return childHasVisibleFilter_;
3594 }
SetChildHasVisibleFilter(bool val)3595 void RSRenderNode::SetChildHasVisibleFilter(bool val)
3596 {
3597     childHasVisibleFilter_ = val;
3598     stagingRenderParams_->SetChildHasVisibleFilter(val);
3599 }
ChildHasVisibleEffect() const3600 bool RSRenderNode::ChildHasVisibleEffect() const
3601 {
3602     return childHasVisibleEffect_;
3603 }
SetChildHasVisibleEffect(bool val)3604 void RSRenderNode::SetChildHasVisibleEffect(bool val)
3605 {
3606     childHasVisibleEffect_ = val;
3607     stagingRenderParams_->SetChildHasVisibleEffect(val);
3608 }
GetVisibleFilterChild() const3609 const std::vector<NodeId>& RSRenderNode::GetVisibleFilterChild() const
3610 {
3611     return visibleFilterChild_;
3612 }
UpdateVisibleFilterChild(RSRenderNode & childNode)3613 void RSRenderNode::UpdateVisibleFilterChild(RSRenderNode& childNode)
3614 {
3615     if (childNode.GetRenderProperties().NeedFilter()) {
3616         visibleFilterChild_.emplace_back(childNode.GetId());
3617     }
3618     auto& childFilterNodes = childNode.GetVisibleFilterChild();
3619     visibleFilterChild_.insert(visibleFilterChild_.end(),
3620         childFilterNodes.begin(), childFilterNodes.end());
3621 }
GetVisibleEffectChild() const3622 const std::unordered_set<NodeId>& RSRenderNode::GetVisibleEffectChild() const
3623 {
3624     return visibleEffectChild_;
3625 }
UpdateVisibleEffectChild(RSRenderNode & childNode)3626 void RSRenderNode::UpdateVisibleEffectChild(RSRenderNode& childNode)
3627 {
3628     if (childNode.GetRenderProperties().GetUseEffect()) {
3629         visibleEffectChild_.emplace(childNode.GetId());
3630     }
3631     auto& childEffectNodes = childNode.GetVisibleEffectChild();
3632     visibleEffectChild_.insert(childEffectNodes.begin(), childEffectNodes.end());
3633 }
3634 
GetInstanceRootNode() const3635 const std::shared_ptr<RSRenderNode> RSRenderNode::GetInstanceRootNode() const
3636 {
3637     auto context = GetContext().lock();
3638     if (!context) {
3639         ROSEN_LOGD("RSRenderNode::GetInstanceRootNode: Invalid context");
3640         return nullptr;
3641     }
3642     return context->GetNodeMap().GetRenderNode(instanceRootNodeId_);
3643 }
3644 
UpdateTreeUifirstRootNodeId(NodeId id)3645 void RSRenderNode::UpdateTreeUifirstRootNodeId(NodeId id)
3646 {
3647     uifirstRootNodeId_ = id;
3648     if (stagingRenderParams_ && stagingRenderParams_->SetUiFirstRootNode(uifirstRootNodeId_)) {
3649         AddToPendingSyncList();
3650     }
3651     for (auto& child : *GetChildren()) {
3652         if (child) {
3653             child->UpdateTreeUifirstRootNodeId(id);
3654         }
3655     }
3656 }
3657 
GetFirstLevelNode() const3658 const std::shared_ptr<RSRenderNode> RSRenderNode::GetFirstLevelNode() const
3659 {
3660     auto context = GetContext().lock();
3661     if (!context) {
3662         ROSEN_LOGE("RSRenderNode::GetFirstLevelNode: Invalid context");
3663         return nullptr;
3664     }
3665     return context->GetNodeMap().GetRenderNode(firstLevelNodeId_);
3666 }
3667 
GetUifirstRootNode() const3668 const std::shared_ptr<RSRenderNode> RSRenderNode::GetUifirstRootNode() const
3669 {
3670     auto context = GetContext().lock();
3671     if (!context) {
3672         ROSEN_LOGE("RSRenderNode::GetUifirstRootNode: Invalid context");
3673         return nullptr;
3674     }
3675     return context->GetNodeMap().GetRenderNode(uifirstRootNodeId_);
3676 }
3677 
IsRenderUpdateIgnored() const3678 bool RSRenderNode::IsRenderUpdateIgnored() const
3679 {
3680     return isRenderUpdateIgnored_;
3681 }
GetAnimationManager()3682 RSAnimationManager& RSRenderNode::GetAnimationManager()
3683 {
3684     return animationManager_;
3685 }
GetOldDirty() const3686 RectI RSRenderNode::GetOldDirty() const
3687 {
3688     return oldDirty_;
3689 }
GetOldDirtyInSurface() const3690 RectI RSRenderNode::GetOldDirtyInSurface() const
3691 {
3692     return oldDirtyInSurface_;
3693 }
GetOldClipRect() const3694 RectI RSRenderNode::GetOldClipRect() const
3695 {
3696     return oldClipRect_;
3697 }
SetOldDirtyInSurface(RectI oldDirtyInSurface)3698 void RSRenderNode::SetOldDirtyInSurface(RectI oldDirtyInSurface)
3699 {
3700     oldDirtyInSurface_ = oldDirtyInSurface;
3701 }
IsDirtyRegionUpdated() const3702 bool RSRenderNode::IsDirtyRegionUpdated() const
3703 {
3704     return isDirtyRegionUpdated_;
3705 }
CleanDirtyRegionUpdated()3706 void RSRenderNode::CleanDirtyRegionUpdated()
3707 {
3708     isDirtyRegionUpdated_ = false;
3709 }
IsShadowValidLastFrame() const3710 bool RSRenderNode::IsShadowValidLastFrame() const
3711 {
3712     return isShadowValidLastFrame_;
3713 }
SetStaticCached(bool isStaticCached)3714 void RSRenderNode::SetStaticCached(bool isStaticCached)
3715 {
3716     isStaticCached_ = isStaticCached;
3717     // ensure defrost subtree would be updated
3718     stagingRenderParams_->SetRSFreezeFlag(isStaticCached);
3719     if (!isStaticCached_) {
3720         SetContentDirty();
3721     }
3722 }
IsStaticCached() const3723 bool RSRenderNode::IsStaticCached() const
3724 {
3725     return isStaticCached_;
3726 }
SetNodeName(const std::string & nodeName)3727 void RSRenderNode::SetNodeName(const std::string& nodeName)
3728 {
3729     nodeName_ = nodeName;
3730 }
GetNodeName() const3731 const std::string& RSRenderNode::GetNodeName() const
3732 {
3733     return nodeName_;
3734 }
UpdateCompletedCacheSurface()3735 void RSRenderNode::UpdateCompletedCacheSurface()
3736 {
3737     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3738     std::swap(cacheSurface_, cacheCompletedSurface_);
3739     std::swap(cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
3740 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
3741     std::swap(cacheBackendTexture_, cacheCompletedBackendTexture_);
3742 #ifdef RS_ENABLE_VK
3743     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
3744         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
3745         std::swap(cacheCleanupHelper_, cacheCompletedCleanupHelper_);
3746     }
3747 #endif
3748     SetTextureValidFlag(true);
3749 #endif
3750 }
SetTextureValidFlag(bool isValid)3751 void RSRenderNode::SetTextureValidFlag(bool isValid)
3752 {
3753 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
3754     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3755     isTextureValid_ = isValid;
3756 #endif
3757 }
ClearCacheSurface(bool isClearCompletedCacheSurface)3758 void RSRenderNode::ClearCacheSurface(bool isClearCompletedCacheSurface)
3759 {
3760     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3761     cacheSurface_ = nullptr;
3762 #ifdef RS_ENABLE_VK
3763     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
3764         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
3765         cacheCleanupHelper_ = nullptr;
3766     }
3767 #endif
3768     if (isClearCompletedCacheSurface) {
3769         cacheCompletedSurface_ = nullptr;
3770 #ifdef RS_ENABLE_VK
3771         if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
3772             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
3773             cacheCompletedCleanupHelper_ = nullptr;
3774         }
3775 #endif
3776 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
3777         isTextureValid_ = false;
3778 #endif
3779     }
3780 }
SetCacheType(CacheType cacheType)3781 void RSRenderNode::SetCacheType(CacheType cacheType)
3782 {
3783     cacheType_ = cacheType;
3784 }
GetCacheType() const3785 CacheType RSRenderNode::GetCacheType() const
3786 {
3787     return cacheType_;
3788 }
GetShadowRectOffsetX() const3789 int RSRenderNode::GetShadowRectOffsetX() const
3790 {
3791     return shadowRectOffsetX_;
3792 }
GetShadowRectOffsetY() const3793 int RSRenderNode::GetShadowRectOffsetY() const
3794 {
3795     return shadowRectOffsetY_;
3796 }
SetDrawingCacheType(RSDrawingCacheType cacheType)3797 void RSRenderNode::SetDrawingCacheType(RSDrawingCacheType cacheType)
3798 {
3799     drawingCacheType_ = cacheType;
3800 }
GetDrawingCacheType() const3801 RSDrawingCacheType RSRenderNode::GetDrawingCacheType() const
3802 {
3803     return drawingCacheType_;
3804 }
SetDrawingCacheChanged(bool cacheChanged)3805 void RSRenderNode::SetDrawingCacheChanged(bool cacheChanged)
3806 {
3807     stagingRenderParams_->SetDrawingCacheChanged(cacheChanged, lastFrameSynced_);
3808 }
GetDrawingCacheChanged() const3809 bool RSRenderNode::GetDrawingCacheChanged() const
3810 {
3811     return stagingRenderParams_->GetDrawingCacheChanged();
3812 }
ResetDrawingCacheNeedUpdate()3813 void RSRenderNode::ResetDrawingCacheNeedUpdate()
3814 {
3815     drawingCacheNeedUpdate_ = false;
3816 }
SetGeoUpdateDelay(bool val)3817 void RSRenderNode::SetGeoUpdateDelay(bool val)
3818 {
3819     geoUpdateDelay_ = geoUpdateDelay_ || val;
3820 }
ResetGeoUpdateDelay()3821 void RSRenderNode::ResetGeoUpdateDelay()
3822 {
3823     geoUpdateDelay_ = false;
3824 }
GetGeoUpdateDelay() const3825 bool RSRenderNode::GetGeoUpdateDelay() const
3826 {
3827     return geoUpdateDelay_;
3828 }
3829 
StoreMustRenewedInfo()3830 void RSRenderNode::StoreMustRenewedInfo()
3831 {
3832     mustRenewedInfo_ = hasHardwareNode_ || childHasVisibleFilter_ || childHasVisibleEffect_;
3833 }
3834 
HasMustRenewedInfo() const3835 bool RSRenderNode::HasMustRenewedInfo() const
3836 {
3837     return mustRenewedInfo_;
3838 }
3839 
SetVisitedCacheRootIds(const std::unordered_set<NodeId> & visitedNodes)3840 void RSRenderNode::SetVisitedCacheRootIds(const std::unordered_set<NodeId>& visitedNodes)
3841 {
3842     visitedCacheRoots_ = visitedNodes;
3843 }
GetVisitedCacheRootIds() const3844 const std::unordered_set<NodeId>& RSRenderNode::GetVisitedCacheRootIds() const
3845 {
3846     return visitedCacheRoots_;
3847 }
AddSubSurfaceUpdateInfo(SharedPtr curParent,SharedPtr preParent)3848 void RSRenderNode::AddSubSurfaceUpdateInfo(SharedPtr curParent, SharedPtr preParent)
3849 {
3850     if (!selfAddForSubSurfaceCnt_ && GetType() == RSRenderNodeType::SURFACE_NODE) {
3851         auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
3852         subSurfaceCnt_ = (surfaceNode && (surfaceNode->IsLeashWindow() || surfaceNode->IsAppWindow())) ?
3853             subSurfaceCnt_ + 1 : subSurfaceCnt_;
3854         selfAddForSubSurfaceCnt_ = true;
3855     }
3856     if (subSurfaceCnt_ == 0) {
3857         return;
3858     }
3859     if (auto context = context_.lock()) {
3860         context->AddSubSurfaceCntUpdateInfo({subSurfaceCnt_,
3861             preParent == nullptr ? INVALID_NODEID : preParent->GetId(),
3862             curParent == nullptr ? INVALID_NODEID : curParent->GetId()});
3863     }
3864 }
UpdateSubSurfaceCnt(int updateCnt)3865 void RSRenderNode::UpdateSubSurfaceCnt(int updateCnt)
3866 {
3867     // avoid loop
3868     if (visitedForSubSurfaceCnt_) {
3869         RS_LOGE("RSRenderNode::UpdateSubSurfaceCnt: %{public}" PRIu64" has loop tree", GetId());
3870         return;
3871     }
3872     visitedForSubSurfaceCnt_ = true;
3873     if (updateCnt == 0) {
3874         visitedForSubSurfaceCnt_ = false;
3875         return;
3876     }
3877     int cnt = subSurfaceCnt_ + updateCnt;
3878     subSurfaceCnt_ = cnt < 0 ? 0 : cnt;
3879     if (auto parent = GetParent().lock()) {
3880         parent->UpdateSubSurfaceCnt(updateCnt);
3881     }
3882     visitedForSubSurfaceCnt_ = false;
3883 }
HasSubSurface() const3884 bool RSRenderNode::HasSubSurface() const
3885 {
3886     return subSurfaceCnt_ > 0;
3887 }
SetDrawingCacheRootId(NodeId id)3888 void RSRenderNode::SetDrawingCacheRootId(NodeId id)
3889 {
3890     drawingCacheRootId_ = id;
3891 }
GetDrawingCacheRootId() const3892 NodeId RSRenderNode::GetDrawingCacheRootId() const
3893 {
3894     return drawingCacheRootId_;
3895 }
HasAnimation() const3896 bool RSRenderNode::HasAnimation() const
3897 {
3898     return !animationManager_.animations_.empty();
3899 }
HasFilter() const3900 bool RSRenderNode::HasFilter() const
3901 {
3902     return hasFilter_;
3903 }
SetHasFilter(bool hasFilter)3904 void RSRenderNode::SetHasFilter(bool hasFilter)
3905 {
3906     hasFilter_ = hasFilter;
3907 }
GetSurfaceMutex() const3908 std::recursive_mutex& RSRenderNode::GetSurfaceMutex() const
3909 {
3910     return surfaceMutex_;
3911 }
HasHardwareNode() const3912 bool RSRenderNode::HasHardwareNode() const
3913 {
3914     return hasHardwareNode_;
3915 }
SetHasHardwareNode(bool hasHardwareNode)3916 void RSRenderNode::SetHasHardwareNode(bool hasHardwareNode)
3917 {
3918     hasHardwareNode_ = hasHardwareNode;
3919 }
HasAbilityComponent() const3920 bool RSRenderNode::HasAbilityComponent() const
3921 {
3922     return hasAbilityComponent_;
3923 }
SetHasAbilityComponent(bool hasAbilityComponent)3924 void RSRenderNode::SetHasAbilityComponent(bool hasAbilityComponent)
3925 {
3926     hasAbilityComponent_ = hasAbilityComponent;
3927 }
GetCacheSurfaceThreadIndex() const3928 uint32_t RSRenderNode::GetCacheSurfaceThreadIndex() const
3929 {
3930     return cacheSurfaceThreadIndex_;
3931 }
GetCompletedSurfaceThreadIndex() const3932 uint32_t RSRenderNode::GetCompletedSurfaceThreadIndex() const
3933 {
3934     return completedSurfaceThreadIndex_;
3935 }
3936 
IsMainThreadNode() const3937 bool RSRenderNode::IsMainThreadNode() const
3938 {
3939     return isMainThreadNode_;
3940 }
SetIsMainThreadNode(bool isMainThreadNode)3941 void RSRenderNode::SetIsMainThreadNode(bool isMainThreadNode)
3942 {
3943     isMainThreadNode_ = isMainThreadNode;
3944 }
IsScale() const3945 bool RSRenderNode::IsScale() const
3946 {
3947     return isScale_;
3948 }
SetIsScale(bool isScale)3949 void RSRenderNode::SetIsScale(bool isScale)
3950 {
3951     isScale_ = isScale;
3952 }
IsScaleInPreFrame() const3953 bool RSRenderNode::IsScaleInPreFrame() const
3954 {
3955     return isScaleInPreFrame_;
3956 }
SetIsScaleInPreFrame(bool isScale)3957 void RSRenderNode::SetIsScaleInPreFrame(bool isScale)
3958 {
3959     isScaleInPreFrame_ = isScale;
3960 }
SetPriority(NodePriorityType priority)3961 void RSRenderNode::SetPriority(NodePriorityType priority)
3962 {
3963     priority_ = priority;
3964 }
GetPriority()3965 NodePriorityType RSRenderNode::GetPriority()
3966 {
3967     return priority_;
3968 }
IsAncestorDirty() const3969 bool RSRenderNode::IsAncestorDirty() const
3970 {
3971     return isAncestorDirty_;
3972 }
SetIsAncestorDirty(bool isAncestorDirty)3973 void RSRenderNode::SetIsAncestorDirty(bool isAncestorDirty)
3974 {
3975     isAncestorDirty_ = isAncestorDirty;
3976 }
IsParentLeashWindow() const3977 bool RSRenderNode::IsParentLeashWindow() const
3978 {
3979     return isParentLeashWindow_;
3980 }
SetParentLeashWindow()3981 void RSRenderNode::SetParentLeashWindow()
3982 {
3983     isParentLeashWindow_ = true;
3984 }
IsParentScbScreen() const3985 bool RSRenderNode::IsParentScbScreen() const
3986 {
3987     return isParentScbScreen_;
3988 }
SetParentScbScreen()3989 void RSRenderNode::SetParentScbScreen()
3990 {
3991     isParentScbScreen_ = true;
3992 }
HasCachedTexture() const3993 bool RSRenderNode::HasCachedTexture() const
3994 {
3995 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
3996     std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
3997     return isTextureValid_;
3998 #else
3999     return true;
4000 #endif
4001 }
SetDrawRegion(const std::shared_ptr<RectF> & rect)4002 void RSRenderNode::SetDrawRegion(const std::shared_ptr<RectF>& rect)
4003 {
4004     if (rect && (rect->GetHeight() >= std::numeric_limits<uint16_t>::max() ||
4005         rect->GetWidth() >= std::numeric_limits<uint16_t>::max())) {
4006         RS_LOGW("node %{public}" PRIu64" set large draw region from arkui: %{public}s",
4007             GetId(), rect->ToString().c_str());
4008         RS_OPTIONAL_TRACE_NAME_FMT("node %" PRIu64" set large draw region from arkui: %s",
4009             GetId(), rect->ToString().c_str());
4010     }
4011     drawRegion_ = rect;
4012     GetMutableRenderProperties().SetDrawRegion(rect);
4013 }
GetDrawRegion() const4014 const std::shared_ptr<RectF>& RSRenderNode::GetDrawRegion() const
4015 {
4016     return drawRegion_;
4017 }
SetOutOfParent(OutOfParentType outOfParent)4018 void RSRenderNode::SetOutOfParent(OutOfParentType outOfParent)
4019 {
4020     outOfParent_ = outOfParent;
4021 }
GetOutOfParent() const4022 OutOfParentType RSRenderNode::GetOutOfParent() const
4023 {
4024     return outOfParent_;
4025 }
GetNodeGroupType()4026 RSRenderNode::NodeGroupType RSRenderNode::GetNodeGroupType()
4027 {
4028     uint8_t type = NodeGroupType::GROUP_TYPE_BUTT;
4029     while (type != NodeGroupType::NONE) {
4030         if (nodeGroupType_ & type) {
4031             return static_cast<NodeGroupType>(type);
4032         } else {
4033             type = type >> 1;
4034         }
4035     }
4036     return NodeGroupType::NONE;
4037 }
4038 
MarkNonGeometryChanged()4039 void RSRenderNode::MarkNonGeometryChanged()
4040 {
4041     geometryChangeNotPerceived_ = true;
4042 }
4043 
GetIsUsedBySubThread() const4044 bool RSRenderNode::GetIsUsedBySubThread() const
4045 {
4046     return isUsedBySubThread_.load();
4047 }
SetIsUsedBySubThread(bool isUsedBySubThread)4048 void RSRenderNode::SetIsUsedBySubThread(bool isUsedBySubThread)
4049 {
4050     isUsedBySubThread_.store(isUsedBySubThread);
4051 }
4052 
GetLastIsNeedAssignToSubThread() const4053 bool RSRenderNode::GetLastIsNeedAssignToSubThread() const
4054 {
4055     return lastIsNeedAssignToSubThread_;
4056 }
SetLastIsNeedAssignToSubThread(bool lastIsNeedAssignToSubThread)4057 void RSRenderNode::SetLastIsNeedAssignToSubThread(bool lastIsNeedAssignToSubThread)
4058 {
4059     lastIsNeedAssignToSubThread_ = lastIsNeedAssignToSubThread;
4060 }
4061 
InitRenderParams()4062 void RSRenderNode::InitRenderParams()
4063 {
4064     stagingRenderParams_ = std::make_unique<RSRenderParams>(GetId());
4065     DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(shared_from_this());
4066     if (renderDrawable_ == nullptr) {
4067         RS_LOGE("RSRenderNode::InitRenderParams failed");
4068         return;
4069     }
4070 }
4071 
UpdateRenderParams()4072 void RSRenderNode::UpdateRenderParams()
4073 {
4074     auto& boundGeo = GetRenderProperties().GetBoundsGeometry();
4075     if (!boundGeo) {
4076         return;
4077     }
4078     bool hasSandbox = sharedTransitionParam_ && GetRenderProperties().GetSandBox();
4079     stagingRenderParams_->SetHasSandBox(hasSandbox);
4080     stagingRenderParams_->SetMatrix(boundGeo->GetMatrix());
4081     stagingRenderParams_->SetFrameGravity(GetRenderProperties().GetFrameGravity());
4082     stagingRenderParams_->SetBoundsRect({ 0, 0, boundGeo->GetWidth(), boundGeo->GetHeight() });
4083     stagingRenderParams_->SetFrameRect({ 0, 0, GetRenderProperties().GetFrameWidth(),
4084         GetRenderProperties().GetFrameHeight() });
4085     stagingRenderParams_->SetShouldPaint(shouldPaint_);
4086     stagingRenderParams_->SetCacheSize(GetOptionalBufferSize());
4087     stagingRenderParams_->SetAlphaOffScreen(GetRenderProperties().GetAlphaOffscreen());
4088     stagingRenderParams_->SetForegroundFilterCache(GetRenderProperties().GetForegroundFilterCache());
4089     stagingRenderParams_->SetNeedFilter(GetRenderProperties().NeedFilter());
4090     stagingRenderParams_->SetHasBlurFilter(HasBlurFilter());
4091     stagingRenderParams_->SetNodeType(GetType());
4092     stagingRenderParams_->SetEffectNodeShouldPaint(EffectNodeShouldPaint());
4093     stagingRenderParams_->SetHasGlobalCorner(!globalCornerRadius_.IsZero());
4094     stagingRenderParams_->SetAbsRotation(absRotation_);
4095 }
4096 
UpdateLocalDrawRect()4097 bool RSRenderNode::UpdateLocalDrawRect()
4098 {
4099     auto drawRect = selfDrawRect_.JoinRect(childrenRect_.ConvertTo<float>());
4100     return stagingRenderParams_->SetLocalDrawRect(drawRect);
4101 }
4102 
UpdateAbsDrawRect()4103 void RSRenderNode::UpdateAbsDrawRect()
4104 {
4105     auto absRect = GetAbsDrawRect();
4106     stagingRenderParams_->SetAbsDrawRect(absRect);
4107 }
4108 
UpdateCurCornerRadius(Vector4f & curCornerRadius)4109 void RSRenderNode::UpdateCurCornerRadius(Vector4f& curCornerRadius)
4110 {
4111     Vector4f::Max(GetRenderProperties().GetCornerRadius(), curCornerRadius, curCornerRadius);
4112     globalCornerRadius_ = curCornerRadius;
4113 }
4114 
ResetChangeState()4115 void RSRenderNode::ResetChangeState()
4116 {
4117     srcOrClipedAbsDrawRectChangeFlag_ = false;
4118     geometryChangeNotPerceived_ = false;
4119 }
4120 
UpdateSrcOrClipedAbsDrawRectChangeState(const RectI & clipRect)4121 void RSRenderNode::UpdateSrcOrClipedAbsDrawRectChangeState(const RectI& clipRect)
4122 {
4123     if (RSSystemProperties::GetSkipGeometryNotChangeEnabled()) {
4124         if (geometryChangeNotPerceived_) {
4125             srcOrClipedAbsDrawRectChangeFlag_ = false;
4126             return;
4127         }
4128     }
4129     auto clipedAbsDrawRect = absDrawRect_.IntersectRect(clipRect);
4130     // The old dirty In surface is equivalent to the old clipped absolute draw rectangle
4131     srcOrClipedAbsDrawRectChangeFlag_ = (absDrawRect_ != oldAbsDrawRect_ || clipedAbsDrawRect != oldDirtyInSurface_);
4132 }
4133 
OnSync()4134 void RSRenderNode::OnSync()
4135 {
4136     addedToPendingSyncList_ = false;
4137     bool isLeashWindowPartialSkip = false;
4138 
4139     if (renderDrawable_ == nullptr) {
4140         return;
4141     }
4142     // uifirstSkipPartialSync means don't need to trylock whether drawable is onDraw or not
4143     DrawableV2::RSRenderNodeSingleDrawableLocker
4144         singleLocker(uifirstSkipPartialSync_ ? nullptr : renderDrawable_.get());
4145     if (!uifirstSkipPartialSync_ && UNLIKELY(!singleLocker.IsLocked())) {
4146         singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
4147         RS_LOGE("Drawable try to Sync when node %{public}" PRIu64 " onDraw!!!", GetId());
4148         return;
4149     }
4150 
4151     if (drawCmdListNeedSync_) {
4152         std::swap(stagingDrawCmdList_, renderDrawable_->drawCmdList_);
4153         stagingDrawCmdList_.clear();
4154         renderDrawable_->drawCmdIndex_ = stagingDrawCmdIndex_;
4155         SyncPurgeFunc();
4156         drawCmdListNeedSync_ = false;
4157     }
4158 
4159     renderDrawable_->backgroundFilterDrawable_ = GetFilterDrawable(false);
4160     renderDrawable_->compositingFilterDrawable_ = GetFilterDrawable(true);
4161 
4162     if (stagingRenderParams_->NeedSync()) {
4163         stagingRenderParams_->OnSync(renderDrawable_->renderParams_);
4164     }
4165 
4166     if (!uifirstSkipPartialSync_) {
4167         if (!dirtySlots_.empty()) {
4168             for (const auto& slot : dirtySlots_) {
4169                 if (auto& drawable = drawableVec_[static_cast<uint32_t>(slot)]) {
4170                     drawable->OnSync();
4171                 }
4172             }
4173             dirtySlots_.clear();
4174         }
4175 
4176         // copy newest for uifirst root node, now force sync done nodes
4177         if (uifirstNeedSync_) {
4178             RS_TRACE_NAME_FMT("uifirst_sync %lld", GetId());
4179             renderDrawable_->uifirstDrawCmdList_.assign(renderDrawable_->drawCmdList_.begin(),
4180                                                         renderDrawable_->drawCmdList_.end());
4181             renderDrawable_->uifirstDrawCmdIndex_ = renderDrawable_->drawCmdIndex_;
4182             renderDrawable_->renderParams_->OnSync(renderDrawable_->uifirstRenderParams_);
4183             uifirstNeedSync_ = false;
4184         }
4185     } else {
4186         RS_TRACE_NAME_FMT("partial_sync %lld", GetId());
4187         std::vector<RSDrawableSlot> todele;
4188         if (!dirtySlots_.empty()) {
4189             for (const auto& slot : dirtySlots_) {
4190                 if (slot != RSDrawableSlot::CONTENT_STYLE && slot != RSDrawableSlot::CHILDREN) { // SAVE_FRAME
4191                     if (auto& drawable = drawableVec_[static_cast<uint32_t>(slot)]) {
4192                         drawable->OnSync();
4193                     }
4194                     todele.push_back(slot);
4195                 }
4196             }
4197             for (const auto& slot : todele) {
4198                 dirtySlots_.erase(slot);
4199             }
4200         }
4201         uifirstSkipPartialSync_ = false;
4202         isLeashWindowPartialSkip = true;
4203     }
4204     if (ShouldClearSurface()) {
4205         renderDrawable_->TryClearSurfaceOnSync();
4206         needClearSurface_ = false;
4207     }
4208     // Reset FilterCache Flags
4209     backgroundFilterRegionChanged_ = false;
4210     backgroundFilterInteractWithDirty_ = false;
4211     foregroundFilterRegionChanged_ = false;
4212     foregroundFilterInteractWithDirty_ = false;
4213 
4214     lastFrameSynced_ = !isLeashWindowPartialSkip;
4215 }
4216 
ShouldClearSurface()4217 bool RSRenderNode::ShouldClearSurface()
4218 {
4219     bool renderGroupFlag = GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE || isOpincRootFlag_;
4220     bool freezeFlag = stagingRenderParams_->GetRSFreezeFlag();
4221     return (renderGroupFlag || freezeFlag || nodeGroupType_ == static_cast<uint8_t>(NodeGroupType::NONE)) &&
4222         needClearSurface_;
4223 }
4224 
ValidateLightResources()4225 void RSRenderNode::ValidateLightResources()
4226 {
4227     auto& properties = GetMutableRenderProperties();
4228     if (properties.lightSourcePtr_ && properties.lightSourcePtr_->IsLightSourceValid()) {
4229         properties.CalculateAbsLightPosition();
4230         RSPointLightManager::Instance()->AddDirtyLightSource(weak_from_this());
4231     }
4232     if (properties.illuminatedPtr_ && properties.illuminatedPtr_->IsIlluminatedValid()) {
4233         RSPointLightManager::Instance()->AddDirtyIlluminated(weak_from_this());
4234     }
4235 }
4236 
MarkBlurIntersectWithDRM(bool intersectWithDRM,bool isDark)4237 void RSRenderNode::MarkBlurIntersectWithDRM(bool intersectWithDRM, bool isDark)
4238 {
4239     const auto& properties = GetRenderProperties();
4240     if (properties.GetBackgroundFilter()) {
4241         if (auto filterDrawable = GetFilterDrawable(false)) {
4242             filterDrawable->MarkBlurIntersectWithDRM(intersectWithDRM, isDark);
4243         }
4244     }
4245 }
4246 
GetUifirstSupportFlag()4247 bool RSRenderNode::GetUifirstSupportFlag()
4248 {
4249     if (sharedTransitionParam_ && !sharedTransitionParam_->IsInAppTranSition()) {
4250         return false;
4251     }
4252     return isChildSupportUifirst_ && isUifirstNode_;
4253 }
4254 
UpdatePointLightDirtySlot()4255 void RSRenderNode::UpdatePointLightDirtySlot()
4256 {
4257     UpdateDirtySlotsAndPendingNodes(RSDrawableSlot::POINT_LIGHT);
4258 }
4259 
AddToPendingSyncList()4260 void RSRenderNode::AddToPendingSyncList()
4261 {
4262     if (addedToPendingSyncList_) {
4263         return;
4264     }
4265 
4266     if (auto context = GetContext().lock()) {
4267         context->AddPendingSyncNode(shared_from_this());
4268         addedToPendingSyncList_ = true;
4269     } else {
4270         ROSEN_LOGE("RSRenderNode::AddToPendingSyncList context is null");
4271         OnSync();
4272     }
4273 }
4274 
SetStartingWindowFlag(bool startingFlag)4275 void RSRenderNode::SetStartingWindowFlag(bool startingFlag)
4276 {
4277     if (startingFlag) {
4278         UpdateDrawingCacheInfoAfterChildren();
4279     }
4280     if (startingWindowFlag_ == startingFlag) {
4281         return;
4282     }
4283     startingWindowFlag_ = startingFlag;
4284     auto stagingParams = stagingRenderParams_.get();
4285     if (stagingParams) {
4286         stagingParams->SetStartingWindowFlag(startingFlag);
4287         AddToPendingSyncList();
4288     }
4289 }
4290 
MarkUifirstNode(bool isUifirstNode)4291 void RSRenderNode::MarkUifirstNode(bool isUifirstNode)
4292 {
4293     RS_OPTIONAL_TRACE_NAME_FMT("MarkUifirstNode id:%lld, isUifirstNode:%d", GetId(), isUifirstNode);
4294     isUifirstNode_ = isUifirstNode;
4295     isUifirstDelay_ = 0;
4296 }
4297 
4298 
MarkUifirstNode(bool isForceFlag,bool isUifirstEnable)4299 void RSRenderNode::MarkUifirstNode(bool isForceFlag, bool isUifirstEnable)
4300 {
4301     RS_TRACE_NAME_FMT("MarkUifirstNode id:%lld, isForceFlag:%d, isUifirstEnable:%d",
4302         GetId(), isForceFlag, isUifirstEnable);
4303     ROSEN_LOGI("MarkUifirstNode id:%{public}" PRIu64 " isForceFlag:%{public}d, isUifirstEnable:%{public}d",
4304         GetId(), isForceFlag, isUifirstEnable);
4305     isForceFlag_ = isForceFlag;
4306     isUifirstEnable_ = isUifirstEnable;
4307 }
4308 
GetUifirstNodeForceFlag() const4309 bool RSRenderNode::GetUifirstNodeForceFlag() const
4310 {
4311     return isForceFlag_;
4312 }
4313 
SetChildrenHasSharedTransition(bool hasSharedTransition)4314 void RSRenderNode::SetChildrenHasSharedTransition(bool hasSharedTransition)
4315 {
4316     childrenHasSharedTransition_ = hasSharedTransition;
4317 }
4318 
RemoveChildFromFulllist(NodeId id)4319 void RSRenderNode::RemoveChildFromFulllist(NodeId id)
4320 {
4321     // Make a copy of the fullChildrenList
4322     if (!fullChildrenList_) {
4323         return;
4324     }
4325     auto fullChildrenList = std::make_shared<std::vector<std::shared_ptr<RSRenderNode>>>(*fullChildrenList_);
4326 
4327     fullChildrenList->erase(std::remove_if(fullChildrenList->begin(),
4328         fullChildrenList->end(), [id](const auto& node) { return id == node->GetId(); }), fullChildrenList->end());
4329 
4330     // Move the fullChildrenList to fullChildrenList_ atomically
4331     ChildrenListSharedPtr constFullChildrenList = std::move(fullChildrenList);
4332     std::atomic_store_explicit(&fullChildrenList_, constFullChildrenList, std::memory_order_release);
4333 }
4334 
SetPurgeStatus(bool flag)4335 void RSRenderNode::SetPurgeStatus(bool flag)
4336 {
4337     if (!isPurgeable_) {
4338         return;
4339     }
4340     if (auto context = GetContext().lock()) {
4341         if (flag) {
4342             context->GetMutableNodeMap().RemoveOffTreeNode(id_);
4343         } else {
4344             context->GetMutableNodeMap().AddOffTreeNode(id_);
4345         }
4346     }
4347 }
4348 
SyncPurgeFunc()4349 void RSRenderNode::SyncPurgeFunc()
4350 {
4351     if (!isPurgeable_) {
4352         return;
4353     }
4354     std::shared_ptr<RSDrawable> drawable = drawableVec_[static_cast<int32_t>(RSDrawableSlot::CONTENT_STYLE)];
4355     if (!drawable) {
4356         return;
4357     }
4358     std::weak_ptr<RSDrawable> drawableWeakPtr = drawable;
4359     renderDrawable_->purgeFunc_ = [drawableWeakPtr]() {
4360         auto drawable = drawableWeakPtr.lock();
4361         if (drawable) {
4362             drawable->OnPurge();
4363         }
4364     };
4365 }
4366 
4367 std::map<NodeId, std::weak_ptr<SharedTransitionParam>> SharedTransitionParam::unpairedShareTransitions_;
4368 
SharedTransitionParam(RSRenderNode::SharedPtr inNode,RSRenderNode::SharedPtr outNode)4369 SharedTransitionParam::SharedTransitionParam(RSRenderNode::SharedPtr inNode, RSRenderNode::SharedPtr outNode)
4370     : inNode_(inNode), outNode_(outNode), inNodeId_(inNode->GetId()), outNodeId_(outNode->GetId()),
4371       crossApplication_(inNode->GetInstanceRootNodeId() != outNode->GetInstanceRootNodeId())
4372 {}
4373 
GetPairedNode(const NodeId nodeId) const4374 RSRenderNode::SharedPtr SharedTransitionParam::GetPairedNode(const NodeId nodeId) const
4375 {
4376     if (inNodeId_ == nodeId) {
4377         return outNode_.lock();
4378     }
4379     if (outNodeId_ == nodeId) {
4380         return inNode_.lock();
4381     }
4382     return nullptr;
4383 }
4384 
SetChildrenHasUIExtension(bool childrenHasUIExtension)4385 void RSRenderNode::SetChildrenHasUIExtension(bool childrenHasUIExtension)
4386 {
4387     childrenHasUIExtension_ = childrenHasUIExtension;
4388     auto parent = GetParent().lock();
4389     if (parent && parent->ChildrenHasUIExtension() != childrenHasUIExtension) {
4390         parent->SetChildrenHasUIExtension(childrenHasUIExtension);
4391     }
4392 }
4393 
UpdateHierarchyAndReturnIsLower(const NodeId nodeId)4394 bool SharedTransitionParam::UpdateHierarchyAndReturnIsLower(const NodeId nodeId)
4395 {
4396     // We already know which node is the lower one.
4397     if (relation_ != NodeHierarchyRelation::UNKNOWN) {
4398         return relation_ == NodeHierarchyRelation::IN_NODE_BELOW_OUT_NODE ? inNodeId_ == nodeId : outNodeId_ == nodeId;
4399     }
4400 
4401     bool visitingInNode = (nodeId == inNodeId_);
4402     if (!visitingInNode && nodeId != outNodeId_) {
4403         return false;
4404     }
4405     // Nodes in the same application will be traversed by order (first visited node has lower hierarchy), while
4406     // applications will be traversed by reverse order. If visitingInNode matches crossApplication_, inNode is above
4407     // outNode. Otherwise, inNode is below outNode.
4408     relation_ = (visitingInNode == crossApplication_) ? NodeHierarchyRelation::IN_NODE_ABOVE_OUT_NODE
4409                                                       : NodeHierarchyRelation::IN_NODE_BELOW_OUT_NODE;
4410     // If crossApplication_ is true, first visited node (this node) has higher hierarchy. and vice versa.
4411     return !crossApplication_;
4412 }
4413 
Dump() const4414 std::string SharedTransitionParam::Dump() const
4415 {
4416     return ", SharedTransitionParam: [" + std::to_string(inNodeId_) + " -> " + std::to_string(outNodeId_) + "]";
4417 }
4418 
ResetRelation()4419 void SharedTransitionParam::ResetRelation()
4420 {
4421     relation_ = NodeHierarchyRelation::UNKNOWN;
4422 }
4423 
InternalUnregisterSelf()4424 void SharedTransitionParam::InternalUnregisterSelf()
4425 {
4426     if (auto inNode = inNode_.lock()) {
4427         inNode->SetSharedTransitionParam(nullptr);
4428         if (auto parent = inNode->GetParent().lock()) {
4429             parent->ApplyModifiers();
4430         }
4431     }
4432     if (auto outNode = outNode_.lock()) {
4433         outNode->SetSharedTransitionParam(nullptr);
4434         if (auto parent = outNode->GetParent().lock()) {
4435             parent->ApplyModifiers();
4436         }
4437     }
4438 }
4439 
ProcessBehindWindowOnTreeStateChanged()4440 void RSRenderNode::ProcessBehindWindowOnTreeStateChanged()
4441 {
4442     auto rootNode = GetInstanceRootNode();
4443     if (!rootNode) {
4444         return;
4445     }
4446     RS_LOGD("RSSurfaceRenderNode::ProcessBehindWindowOnTreeStateChanged nodeId = %{public}" PRIu64
4447         ", isOnTheTree_ = %{public}d", GetId(), isOnTheTree_);
4448     if (isOnTheTree_) {
4449         rootNode->AddChildBlurBehindWindow(GetId());
4450     } else {
4451         rootNode->RemoveChildBlurBehindWindow(GetId());
4452     }
4453 }
4454 
ProcessBehindWindowAfterApplyModifiers()4455 void RSRenderNode::ProcessBehindWindowAfterApplyModifiers()
4456 {
4457     auto rootNode = GetInstanceRootNode();
4458     if (!rootNode) {
4459         return;
4460     }
4461     auto& properties = GetMutableRenderProperties();
4462     bool useEffect = properties.GetUseEffect();
4463     UseEffectType useEffectType = static_cast<UseEffectType>(properties.GetUseEffectType());
4464     RS_LOGD("RSSurfaceRenderNode::ProcessBehindWindowAfterApplyModifiers nodeId = %{public}" PRIu64
4465         ", isOnTheTree_ = %{public}d, useEffect = %{public}d, useEffectType = %{public}hd",
4466         GetId(), isOnTheTree_, useEffect, useEffectType);
4467     if (useEffect && useEffectType == UseEffectType::BEHIND_WINDOW) {
4468         rootNode->AddChildBlurBehindWindow(GetId());
4469     } else {
4470         rootNode->RemoveChildBlurBehindWindow(GetId());
4471     }
4472 }
4473 } // namespace Rosen
4474 } // namespace OHOS
4475