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