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