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