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