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