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