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
24 #include "rs_trace.h"
25 #include "animation/rs_render_animation.h"
26 #include "common/rs_obj_abs_geometry.h"
27 #include "benchmarks/file_utils.h"
28 #include "common/rs_optional_trace.h"
29 #include "modifier/rs_modifier_type.h"
30 #include "pipeline/rs_context.h"
31 #include "pipeline/rs_display_render_node.h"
32 #include "pipeline/rs_effect_render_node.h"
33 #include "pipeline/rs_paint_filter_canvas.h"
34 #include "pipeline/rs_root_render_node.h"
35 #include "pipeline/rs_surface_render_node.h"
36 #include "platform/common/rs_log.h"
37 #include "platform/common/rs_system_properties.h"
38 #include "property/rs_properties_painter.h"
39 #include "property/rs_property_drawable.h"
40 #include "property/rs_property_trace.h"
41 #include "transaction/rs_transaction_proxy.h"
42 #include "visitor/rs_node_visitor.h"
43
44 #ifdef RS_ENABLE_VK
45 #include "include/gpu/GrBackendSurface.h"
46 #include "platform/ohos/backend/native_buffer_utils.h"
47 #include "platform/ohos/backend/rs_vulkan_context.h"
48 #endif
49
50 #ifdef RS_ENABLE_VK
51 namespace {
findMemoryType(uint32_t typeFilter,VkMemoryPropertyFlags properties)52 uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
53 {
54 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
55 OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
56 return UINT32_MAX;
57 }
58 auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton();
59 VkPhysicalDevice physicalDevice = vkContext.GetPhysicalDevice();
60
61 VkPhysicalDeviceMemoryProperties memProperties;
62 vkContext.vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
63
64 for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
65 if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
66 return i;
67 }
68 }
69
70 return UINT32_MAX;
71 }
72
73 #ifndef USE_ROSEN_DRAWING
SetVkImageInfo(GrVkImageInfo & skImageInfo,const VkImageCreateInfo & imageInfo)74 void SetVkImageInfo(GrVkImageInfo& skImageInfo, const VkImageCreateInfo& imageInfo)
75 {
76 skImageInfo.fImageTiling = imageInfo.tiling;
77 skImageInfo.fImageLayout = imageInfo.initialLayout;
78 skImageInfo.fFormat = imageInfo.format;
79 skImageInfo.fImageUsageFlags = imageInfo.usage;
80 skImageInfo.fLevelCount = imageInfo.mipLevels;
81 skImageInfo.fCurrentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL;
82 skImageInfo.fYcbcrConversionInfo = {};
83 skImageInfo.fSharingMode = imageInfo.sharingMode;
84 }
85 #else
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 #endif
99
100 #ifndef USE_ROSEN_DRAWING
MakeBackendTexture(uint32_t width,uint32_t height,VkFormat format=VK_FORMAT_R8G8B8A8_UNORM)101 GrBackendTexture MakeBackendTexture(uint32_t width, uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_UNORM)
102 #else
103 OHOS::Rosen::Drawing::BackendTexture MakeBackendTexture(uint32_t width, uint32_t height,
104 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM)
105 #endif
106 {
107 VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
108 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
109 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
110 VkImageCreateInfo imageInfo {
111 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
112 .pNext = nullptr,
113 .flags = 0,
114 .imageType = VK_IMAGE_TYPE_2D,
115 .format = format,
116 .extent = {width, height, 1},
117 .mipLevels = 1,
118 .arrayLayers = 1,
119 .samples = VK_SAMPLE_COUNT_1_BIT,
120 .tiling = tiling,
121 .usage = usage,
122 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
123 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
124 };
125
126 auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton();
127 VkDevice device = vkContext.GetDevice();
128 VkImage image = VK_NULL_HANDLE;
129 VkDeviceMemory memory = VK_NULL_HANDLE;
130
131 if (vkContext.vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
132 return {};
133 }
134
135 VkMemoryRequirements memRequirements;
136 vkContext.vkGetImageMemoryRequirements(device, image, &memRequirements);
137
138 VkMemoryAllocateInfo allocInfo{};
139 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
140 allocInfo.allocationSize = memRequirements.size;
141 allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
142 if (allocInfo.memoryTypeIndex == UINT32_MAX) {
143 return {};
144 }
145
146 if (vkContext.vkAllocateMemory(device, &allocInfo, nullptr, &memory) != VK_SUCCESS) {
147 return {};
148 }
149
150 vkContext.vkBindImageMemory(device, image, memory, 0);
151
152 #ifndef USE_ROSEN_DRAWING
153 GrVkAlloc alloc;
154 alloc.fMemory = memory;
155 alloc.fOffset = memRequirements.size;
156
157 GrVkImageInfo skImageInfo;
158 skImageInfo.fImage = image;
159 skImageInfo.fAlloc = alloc;
160 SetVkImageInfo(skImageInfo, imageInfo);
161
162 return GrBackendTexture(width, height, skImageInfo);
163 #else
164 OHOS::Rosen::Drawing::BackendTexture backendTexture(true);
165 OHOS::Rosen::Drawing::TextureInfo textureInfo;
166 textureInfo.SetWidth(width);
167 textureInfo.SetHeight(height);
168
169 std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo =
170 std::make_shared<OHOS::Rosen::Drawing::VKTextureInfo>();
171 vkImageInfo->vkImage = image;
172 vkImageInfo->vkAlloc.memory = memory;
173 vkImageInfo->vkAlloc.size = memRequirements.size;
174
175 SetVkImageInfo(vkImageInfo, imageInfo);
176 textureInfo.SetVKTextureInfo(vkImageInfo);
177 backendTexture.SetTextureInfo(textureInfo);
178 return backendTexture;
179 #endif
180 }
181 } // un-named
182 #endif
183
184 namespace OHOS {
185 namespace Rosen {
OnRegister(const std::weak_ptr<RSContext> & context)186 void RSRenderNode::OnRegister(const std::weak_ptr<RSContext>& context)
187 {
188 context_ = context;
189 renderContent_->type_ = GetType();
190 renderContent_->renderProperties_.backref_ = weak_from_this();
191 SetDirty(true);
192 }
193
IsPureContainer() const194 bool RSRenderNode::IsPureContainer() const
195 {
196 auto& drawCmdModifiers_ = renderContent_->drawCmdModifiers_;
197 return (drawCmdModifiers_.empty() && !GetRenderProperties().isDrawn_ && !GetRenderProperties().alphaNeedApply_);
198 }
199
IsContentNode() const200 bool RSRenderNode::IsContentNode() const
201 {
202 auto& drawCmdModifiers_ = renderContent_->drawCmdModifiers_;
203 return ((drawCmdModifiers_.size() == 1 && drawCmdModifiers_.count(RSModifierType::CONTENT_STYLE)) ||
204 drawCmdModifiers_.empty()) &&
205 !GetRenderProperties().isDrawn_;
206 }
207
208 namespace {
209 const std::set<RSModifierType> GROUPABLE_ANIMATION_TYPE = {
210 RSModifierType::ALPHA,
211 RSModifierType::ROTATION,
212 RSModifierType::SCALE,
213 };
214 const std::set<RSModifierType> CACHEABLE_ANIMATION_TYPE = {
215 RSModifierType::BOUNDS,
216 RSModifierType::FRAME,
217 };
218 const std::set<RSModifierType> BASIC_GEOTRANSFORM_ANIMATION_TYPE = {
219 RSModifierType::TRANSLATE,
220 RSModifierType::SCALE,
221 };
222 }
223
RSRenderNode(NodeId id,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)224 RSRenderNode::RSRenderNode(NodeId id, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
225 : id_(id), context_(context), isTextureExportNode_(isTextureExportNode)
226 {}
227
RSRenderNode(NodeId id,bool isOnTheTree,const std::weak_ptr<RSContext> & context,bool isTextureExportNode)228 RSRenderNode::RSRenderNode(
229 NodeId id, bool isOnTheTree, const std::weak_ptr<RSContext>& context, bool isTextureExportNode)
230 : isOnTheTree_(isOnTheTree), id_(id), context_(context), isTextureExportNode_(isTextureExportNode)
231 {}
232
GetIsTextureExportNode() const233 bool RSRenderNode::GetIsTextureExportNode() const
234 {
235 return isTextureExportNode_;
236 }
237
AddChild(SharedPtr child,int index)238 void RSRenderNode::AddChild(SharedPtr child, int index)
239 {
240 // sanity check, avoid loop
241 if (child == nullptr || child->GetId() == GetId()) {
242 return;
243 }
244 // if child already has a parent, remove it from its previous parent
245 if (auto prevParent = child->GetParent().lock()) {
246 prevParent->RemoveChild(child);
247 }
248
249 // Set parent-child relationship
250 child->SetParent(weak_from_this());
251 if (index < 0 || index >= static_cast<int>(children_.size())) {
252 children_.emplace_back(child);
253 } else {
254 children_.emplace(std::next(children_.begin(), index), child);
255 }
256
257 disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
258 // A child is not on the tree until its parent is on the tree
259 if (isOnTheTree_) {
260 child->SetIsOnTheTree(true, instanceRootNodeId_, firstLevelNodeId_, drawingCacheRootId_);
261 }
262 SetContentDirty();
263 isFullChildrenListValid_ = false;
264 }
265
SetContainBootAnimation(bool isContainBootAnimation)266 void RSRenderNode::SetContainBootAnimation(bool isContainBootAnimation)
267 {
268 isContainBootAnimation_ = isContainBootAnimation;
269 isFullChildrenListValid_ = false;
270 }
271
GetContainBootAnimation() const272 bool RSRenderNode::GetContainBootAnimation() const
273 {
274 return isContainBootAnimation_;
275 }
276
MoveChild(SharedPtr child,int index)277 void RSRenderNode::MoveChild(SharedPtr child, int index)
278 {
279 if (child == nullptr || child->GetParent().lock().get() != this) {
280 return;
281 }
282 auto it = std::find_if(children_.begin(), children_.end(),
283 [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
284 if (it == children_.end()) {
285 return;
286 }
287
288 // Reset parent-child relationship
289 if (index < 0 || index >= static_cast<int>(children_.size())) {
290 children_.emplace_back(child);
291 } else {
292 children_.emplace(std::next(children_.begin(), index), child);
293 }
294 children_.erase(it);
295 SetContentDirty();
296 isFullChildrenListValid_ = false;
297 }
298
RemoveChild(SharedPtr child,bool skipTransition)299 void RSRenderNode::RemoveChild(SharedPtr child, bool skipTransition)
300 {
301 if (child == nullptr) {
302 return;
303 }
304 // break parent-child relationship
305 auto it = std::find_if(children_.begin(), children_.end(),
306 [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
307 if (it == children_.end()) {
308 return;
309 }
310 // avoid duplicate entry in disappearingChildren_ (this should not happen)
311 disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
312 // if child has disappearing transition, add it to disappearingChildren_
313 if (skipTransition == false && child->HasDisappearingTransition(true)) {
314 ROSEN_LOGD("RSRenderNode::RemoveChild %{public}" PRIu64 " move child(id %{public}" PRIu64 ") into"
315 " disappearingChildren", GetId(), child->GetId());
316 // keep shared_ptr alive for transition
317 uint32_t origPos = static_cast<uint32_t>(std::distance(children_.begin(), it));
318 disappearingChildren_.emplace_back(child, origPos);
319 } else {
320 child->ResetParent();
321 }
322 children_.erase(it);
323 if (child->GetBootAnimation()) {
324 SetContainBootAnimation(false);
325 }
326 if (!children_.empty() || !disappearingChildren_.empty()) {
327 isFullChildrenListValid_ = false;
328 } else { // directly clear children list
329 isFullChildrenListValid_ = true;
330 isChildrenSorted_ = true;
331 std::atomic_store_explicit(&fullChildrenList_, EmptyChildrenList, std::memory_order_release);
332 }
333 }
334
SetIsOnTheTree(bool flag,NodeId instanceRootNodeId,NodeId firstLevelNodeId,NodeId cacheNodeId)335 void RSRenderNode::SetIsOnTheTree(bool flag, NodeId instanceRootNodeId, NodeId firstLevelNodeId, NodeId cacheNodeId)
336 {
337 // We do not need to label a child when the child is removed from a parent that is not on the tree
338 if (flag == isOnTheTree_) {
339 return;
340 }
341 isNewOnTree_ = flag && !isOnTheTree_;
342 isOnTheTree_ = flag;
343 if (isOnTheTree_) {
344 instanceRootNodeId_ = instanceRootNodeId;
345 firstLevelNodeId_ = firstLevelNodeId;
346 OnTreeStateChanged();
347 } else {
348 OnTreeStateChanged();
349 instanceRootNodeId_ = instanceRootNodeId;
350 firstLevelNodeId_ = firstLevelNodeId;
351 }
352 // if node is marked as cacheRoot, update subtree status when update surface
353 // in case prepare stage upper cacheRoot cannot specify dirty subnode
354 if (cacheNodeId != INVALID_NODEID) {
355 drawingCacheRootId_ = cacheNodeId;
356 }
357
358 for (auto& weakChild : children_) {
359 auto child = weakChild.lock();
360 if (child == nullptr) {
361 continue;
362 }
363 child->SetIsOnTheTree(flag, instanceRootNodeId, firstLevelNodeId, cacheNodeId);
364 }
365
366 for (auto& [child, _] : disappearingChildren_) {
367 child->SetIsOnTheTree(flag, instanceRootNodeId, firstLevelNodeId, cacheNodeId);
368 }
369 }
370
UpdateChildrenRect(const RectI & subRect)371 void RSRenderNode::UpdateChildrenRect(const RectI& subRect)
372 {
373 if (!subRect.IsEmpty()) {
374 if (childrenRect_.IsEmpty()) {
375 // init as not empty subRect in case join RectI enlarging area
376 childrenRect_ = subRect;
377 } else {
378 childrenRect_ = childrenRect_.JoinRect(subRect);
379 }
380 }
381 }
382
AddCrossParentChild(const SharedPtr & child,int32_t index)383 void RSRenderNode::AddCrossParentChild(const SharedPtr& child, int32_t index)
384 {
385 // AddCrossParentChild only used as: the child is under multiple parents(e.g. a window cross multi-screens),
386 // so this child will not remove from the old parent.
387 if (child == nullptr) {
388 return;
389 }
390
391 // Set parent-child relationship
392 child->SetParent(weak_from_this());
393 if (index < 0 || index >= static_cast<int32_t>(children_.size())) {
394 children_.emplace_back(child);
395 } else {
396 children_.emplace(std::next(children_.begin(), index), child);
397 }
398
399 disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
400 // A child is not on the tree until its parent is on the tree
401 if (isOnTheTree_) {
402 child->SetIsOnTheTree(true, instanceRootNodeId_, firstLevelNodeId_, drawingCacheRootId_);
403 }
404 SetContentDirty();
405 isFullChildrenListValid_ = false;
406 }
407
RemoveCrossParentChild(const SharedPtr & child,const WeakPtr & newParent)408 void RSRenderNode::RemoveCrossParentChild(const SharedPtr& child, const WeakPtr& newParent)
409 {
410 // RemoveCrossParentChild only used as: the child is under multiple parents(e.g. a window cross multi-screens),
411 // set the newParentId to rebuild the parent-child relationship.
412 if (child == nullptr) {
413 return;
414 }
415 // break parent-child relationship
416 auto it = std::find_if(children_.begin(), children_.end(),
417 [&](WeakPtr& ptr) -> bool { return ROSEN_EQ<RSRenderNode>(ptr, child); });
418 if (it == children_.end()) {
419 return;
420 }
421 // avoid duplicate entry in disappearingChildren_ (this should not happen)
422 disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
423 // if child has disappearing transition, add it to disappearingChildren_
424 if (child->HasDisappearingTransition(true)) {
425 ROSEN_LOGD("RSRenderNode::RemoveChild %{public}" PRIu64 " move child(id %{public}" PRIu64 ")"
426 " into disappearingChildren", GetId(), child->GetId());
427 // keep shared_ptr alive for transition
428 uint32_t origPos = static_cast<uint32_t>(std::distance(children_.begin(), it));
429 disappearingChildren_.emplace_back(child, origPos);
430 } else {
431 child->SetParent(newParent);
432 // attention: set new parent means 'old' parent has removed this child
433 hasRemovedChild_ = true;
434 }
435 children_.erase(it);
436 SetContentDirty();
437 if (!children_.empty() || !disappearingChildren_.empty()) {
438 isFullChildrenListValid_ = false;
439 } else { // directly clear children list
440 isFullChildrenListValid_ = true;
441 isChildrenSorted_ = true;
442 std::atomic_store_explicit(&fullChildrenList_, EmptyChildrenList, std::memory_order_release);
443 }
444 }
445
RemoveFromTree(bool skipTransition)446 void RSRenderNode::RemoveFromTree(bool skipTransition)
447 {
448 auto parentPtr = parent_.lock();
449 if (parentPtr == nullptr) {
450 return;
451 }
452 auto child = shared_from_this();
453 parentPtr->RemoveChild(child, skipTransition);
454 if (skipTransition == false) {
455 return;
456 }
457 // force remove child from disappearingChildren_ and clean sortChildren_ cache
458 parentPtr->disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
459 parentPtr->isFullChildrenListValid_ = false;
460 child->ResetParent();
461 }
462
ClearChildren()463 void RSRenderNode::ClearChildren()
464 {
465 if (children_.empty()) {
466 return;
467 }
468 // Cache the parent's transition state to avoid redundant recursively check
469 bool parentHasDisappearingTransition = HasDisappearingTransition(true);
470 uint32_t pos = 0;
471 for (auto& childWeakPtr : children_) {
472 auto child = childWeakPtr.lock();
473 if (child == nullptr) {
474 ++pos;
475 continue;
476 }
477 // avoid duplicate entry in disappearingChildren_ (this should not happen)
478 disappearingChildren_.remove_if([&child](const auto& pair) -> bool { return pair.first == child; });
479 if (parentHasDisappearingTransition || child->HasDisappearingTransition(false)) {
480 // keep shared_ptr alive for transition
481 disappearingChildren_.emplace_back(child, pos);
482 } else {
483 child->ResetParent();
484 }
485 ++pos;
486 }
487 children_.clear();
488 SetContentDirty();
489 if (!disappearingChildren_.empty()) {
490 isFullChildrenListValid_ = false;
491 } else { // directly clear children list
492 isFullChildrenListValid_ = true;
493 isChildrenSorted_ = true;
494 std::atomic_store_explicit(&fullChildrenList_, EmptyChildrenList, std::memory_order_release);
495 }
496 }
497
SetParent(WeakPtr parent)498 void RSRenderNode::SetParent(WeakPtr parent)
499 {
500 UpdateSubSurfaceCnt(parent.lock(), parent_.lock());
501 parent_ = parent;
502 if (isSubSurfaceEnabled_) {
503 AddSubSurfaceNode(shared_from_this(), parent.lock());
504 }
505 }
506
ResetParent()507 void RSRenderNode::ResetParent()
508 {
509 if (auto parentNode = parent_.lock()) {
510 if (isSubSurfaceEnabled_) {
511 auto it = std::find_if(parentNode->disappearingChildren_.begin(), parentNode->disappearingChildren_.end(),
512 [childPtr = shared_from_this()](const auto& pair) -> bool { return pair.first == childPtr; });
513 if (it == parentNode->disappearingChildren_.end()) {
514 RemoveSubSurfaceNode(shared_from_this(), parentNode);
515 }
516 }
517 parentNode->hasRemovedChild_ = true;
518 parentNode->SetContentDirty();
519 UpdateSubSurfaceCnt(nullptr, parentNode);
520 }
521 parent_.reset();
522 SetIsOnTheTree(false);
523 OnResetParent();
524 }
525
GetParent() const526 RSRenderNode::WeakPtr RSRenderNode::GetParent() const
527 {
528 return parent_;
529 }
530
IsFirstLevelSurfaceNode()531 bool RSRenderNode::IsFirstLevelSurfaceNode()
532 {
533 if (!this->IsInstanceOf<RSSurfaceRenderNode>()) {
534 return false;
535 }
536 auto parentNode = parent_.lock();
537 while (parentNode && !parentNode->IsInstanceOf<RSDisplayRenderNode>()) {
538 auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentNode);
539 if (node != nullptr && (node->IsMainWindowType() || node->IsLeashWindow())) {
540 return false;
541 }
542 parentNode = parentNode->GetParent().lock();
543 }
544 return true;
545 }
546
SubSurfaceNodeNeedDraw(PartialRenderType opDropType)547 bool RSRenderNode::SubSurfaceNodeNeedDraw(PartialRenderType opDropType)
548 {
549 for (auto &nodes : subSurfaceNodes_) {
550 for (auto &node : nodes.second) {
551 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.lock());
552 if (surfaceNode != nullptr &&
553 (surfaceNode->SubNodeNeedDraw(surfaceNode->GetOldDirtyInSurface(), opDropType) ||
554 surfaceNode->SubSurfaceNodeNeedDraw(opDropType))) {
555 return true;
556 }
557 }
558 }
559 return false;
560 }
561
AddSubSurfaceNode(SharedPtr child,SharedPtr parent)562 void RSRenderNode::AddSubSurfaceNode(SharedPtr child, SharedPtr parent)
563 {
564 if (parent->subSurfaceNodes_.find(child->GetId()) != parent->subSurfaceNodes_.end()) {
565 return;
566 }
567 std::vector<WeakPtr> subSurfaceNodes;
568 if (child->IsInstanceOf<RSSurfaceRenderNode>() &&
569 (RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsMainWindowType() ||
570 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashWindow())) {
571 subSurfaceNodes.push_back(child);
572 } else {
573 for (auto &nodes : child->subSurfaceNodes_) {
574 subSurfaceNodes.insert(subSurfaceNodes.end(), nodes.second.begin(), nodes.second.end());
575 }
576 }
577 if (subSurfaceNodes.size() == 0) {
578 return;
579 }
580
581 auto childNode = child;
582 auto parentNode = parent;
583 while (parentNode && !parentNode->IsInstanceOf<RSDisplayRenderNode>()) {
584 auto id = childNode->GetId();
585 if (parentNode->subSurfaceNodes_.find(id) == parentNode->subSurfaceNodes_.end()) {
586 parentNode->subSurfaceNodes_.insert({id, subSurfaceNodes});
587 } else {
588 parentNode->subSurfaceNodes_[id].insert(parentNode->subSurfaceNodes_[id].end(),
589 subSurfaceNodes.begin(), subSurfaceNodes.end());
590 }
591 std::sort(parentNode->subSurfaceNodes_[id].begin(), parentNode->subSurfaceNodes_[id].end(),
592 [](const auto &first, const auto &second) {
593 return
594 first.lock()->GetRenderProperties().GetPositionZ() <
595 second.lock()->GetRenderProperties().GetPositionZ();
596 });
597 if (parentNode->IsInstanceOf<RSSurfaceRenderNode>()) {
598 break;
599 }
600 childNode = parentNode;
601 parentNode = parentNode->GetParent().lock();
602 }
603 }
604
RemoveSubSurfaceNode(SharedPtr child,SharedPtr parent)605 void RSRenderNode::RemoveSubSurfaceNode(SharedPtr child, SharedPtr parent)
606 {
607 if (parent->subSurfaceNodes_.find(child->GetId()) == parent->subSurfaceNodes_.end()) {
608 return;
609 }
610 auto subSurfaceNodes = parent->subSurfaceNodes_[child->GetId()];
611 parent->subSurfaceNodes_.erase(child->GetId());
612 auto childNode = parent;
613 auto parentNode = parent->GetParent().lock();
614 while (parentNode && !parentNode->IsInstanceOf<RSDisplayRenderNode>()) {
615 auto id = childNode->GetId();
616 for (auto iter : subSurfaceNodes) {
617 parentNode->subSurfaceNodes_[id].erase(
618 remove_if(parentNode->subSurfaceNodes_[id].begin(), parentNode->subSurfaceNodes_[id].end(),
619 [iter](WeakPtr it) {
620 return iter.lock() && it.lock() && iter.lock()->GetId() == it.lock()->GetId();
621 }),
622 parentNode->subSurfaceNodes_[id].end()
623 );
624 }
625 if (parentNode->subSurfaceNodes_[id].size() == 0) {
626 parentNode->subSurfaceNodes_.erase(id);
627 }
628 if (parentNode->IsInstanceOf<RSSurfaceRenderNode>()) {
629 break;
630 }
631 childNode = parentNode;
632 parentNode = parentNode->GetParent().lock();
633 }
634 }
635
DumpTree(int32_t depth,std::string & out) const636 void RSRenderNode::DumpTree(int32_t depth, std::string& out) const
637 {
638 for (int32_t i = 0; i < depth; ++i) {
639 out += " ";
640 }
641 out += "| ";
642 DumpNodeType(out);
643 out += "[" + std::to_string(GetId()) + "], instanceRootNodeId" + "[" +
644 std::to_string(GetInstanceRootNodeId()) + "]";
645 if (IsSuggestedDrawInGroup()) {
646 out += ", [node group]";
647 }
648 DumpSubClassNode(out);
649 out += ", Properties: " + GetRenderProperties().Dump();
650 out += ", GetBootAnimation: " + std::to_string(GetBootAnimation());
651 out += ", isContainBootAnimation_: " + std::to_string(isContainBootAnimation_);
652 out += ", isNodeDirty: " + std::to_string(static_cast<int>(dirtyStatus_));
653 out += ", isPropertyDirty: " + std::to_string(GetRenderProperties().IsDirty());
654 out += ", IsPureContainer: " + std::to_string(IsPureContainer());
655 DumpDrawCmdModifiers(out);
656 animationManager_.DumpAnimations(out);
657 out += "\n";
658
659 for (auto& child : *GetSortedChildren()) {
660 child->DumpTree(depth + 1, out);
661 }
662 for (auto& [child, pos] : disappearingChildren_) {
663 child->DumpTree(depth + 1, out);
664 }
665 }
666
DumpNodeType(std::string & out) const667 void RSRenderNode::DumpNodeType(std::string& out) const
668 {
669 switch (GetType()) {
670 case RSRenderNodeType::DISPLAY_NODE: {
671 out += "DISPLAY_NODE";
672 break;
673 }
674 case RSRenderNodeType::RS_NODE: {
675 out += "RS_NODE";
676 break;
677 }
678 case RSRenderNodeType::SURFACE_NODE: {
679 out += "SURFACE_NODE";
680 break;
681 }
682 case RSRenderNodeType::CANVAS_NODE: {
683 out += "CANVAS_NODE";
684 break;
685 }
686 case RSRenderNodeType::ROOT_NODE: {
687 out += "ROOT_NODE";
688 break;
689 }
690 case RSRenderNodeType::PROXY_NODE: {
691 out += "PROXY_NODE";
692 break;
693 }
694 case RSRenderNodeType::CANVAS_DRAWING_NODE: {
695 out += "CANVAS_DRAWING_NODE";
696 break;
697 }
698 default: {
699 out += "UNKNOWN_NODE";
700 break;
701 }
702 }
703 }
704
DumpSubClassNode(std::string & out) const705 void RSRenderNode::DumpSubClassNode(std::string& out) const
706 {
707 if (GetType() == RSRenderNodeType::SURFACE_NODE) {
708 auto surfaceNode = (static_cast<const RSSurfaceRenderNode*>(this));
709 auto p = parent_.lock();
710 out += ", Parent [" + (p != nullptr ? std::to_string(p->GetId()) : "null") + "]";
711 out += ", Name [" + surfaceNode->GetName() + "]";
712 const RSSurfaceHandler& surfaceHandler = static_cast<const RSSurfaceHandler&>(*surfaceNode);
713 out += ", hasConsumer: " + std::to_string(surfaceHandler.HasConsumer());
714 std::string contextAlpha = std::to_string(surfaceNode->contextAlpha_);
715 std::string propertyAlpha = std::to_string(surfaceNode->GetRenderProperties().GetAlpha());
716 out += ", Alpha: " + propertyAlpha + " (include ContextAlpha: " + contextAlpha + ")";
717 out += ", Visible: " + std::to_string(surfaceNode->GetRenderProperties().GetVisible());
718 out += ", " + surfaceNode->GetVisibleRegion().GetRegionInfo();
719 out += ", OcclusionBg: " + std::to_string(surfaceNode->GetAbilityBgAlpha());
720 out += ", SecurityLayer: " + std::to_string(surfaceNode->GetSecurityLayer());
721 out += ", skipLayer: " + std::to_string(surfaceNode->GetSkipLayer());
722 } else if (GetType() == RSRenderNodeType::ROOT_NODE) {
723 auto rootNode = static_cast<const RSRootRenderNode*>(this);
724 out += ", Visible: " + std::to_string(rootNode->GetRenderProperties().GetVisible());
725 out += ", Size: [" + std::to_string(rootNode->GetRenderProperties().GetFrameWidth()) + ", " +
726 std::to_string(rootNode->GetRenderProperties().GetFrameHeight()) + "]";
727 out += ", EnableRender: " + std::to_string(rootNode->GetEnableRender());
728 } else if (GetType() == RSRenderNodeType::DISPLAY_NODE) {
729 auto displayNode = static_cast<const RSDisplayRenderNode*>(this);
730 out += ", skipLayer: " + std::to_string(displayNode->GetSecurityDisplay());
731 }
732 }
733
DumpDrawCmdModifiers(std::string & out) const734 void RSRenderNode::DumpDrawCmdModifiers(std::string& out) const
735 {
736 if (renderContent_->drawCmdModifiers_.empty()) {
737 return;
738 }
739 std::string splitStr = ", ";
740 std::string modifierDesc = ", DrawCmdModifiers:[";
741 for (auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
742 modifierDesc += "type:" + std::to_string(static_cast<int>(type)) + ", modifiers: ";
743 std::string propertyDesc = "Property_";
744 for (auto& modifier : modifiers) {
745 DumpDrawCmdModifier(propertyDesc, type, modifier);
746 propertyDesc += "], ";
747 }
748 modifierDesc += propertyDesc.substr(0, propertyDesc.length() - splitStr.length());
749 modifierDesc += splitStr;
750 }
751 out += modifierDesc.substr(0, modifierDesc.length() - splitStr.length());
752 out += "]";
753 }
754
DumpDrawCmdModifier(std::string & propertyDesc,RSModifierType type,std::shared_ptr<RSRenderModifier> & modifier) const755 void RSRenderNode::DumpDrawCmdModifier(std::string& propertyDesc, RSModifierType type,
756 std::shared_ptr<RSRenderModifier>& modifier) const
757 {
758 if (type < RSModifierType::ENV_FOREGROUND_COLOR) {
759 propertyDesc += "drawCmdList:[";
760 auto propertyValue = std::static_pointer_cast<RSRenderProperty<Drawing::DrawCmdListPtr>>
761 (modifier->GetProperty())->Get();
762 propertyDesc += propertyValue->GetOpsWithDesc();
763 std::string::size_type pos = 0;
764 while ((pos = propertyDesc.find("\n", pos)) != std::string::npos) {
765 propertyDesc.replace(pos, 1, ",");
766 }
767 propertyDesc.pop_back();
768 } else if (type == RSModifierType::ENV_FOREGROUND_COLOR) {
769 propertyDesc += "ENV_FOREGROUND_COLOR:[Rgba-";
770 auto propertyValue = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>
771 (modifier->GetProperty())->Get();
772 propertyDesc += std::to_string(propertyValue.AsRgbaInt());
773 } else if (type == RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY) {
774 propertyDesc += "ENV_FOREGROUND_COLOR_STRATEGY:[";
775 auto propertyValue = std::static_pointer_cast<RSRenderProperty<ForegroundColorStrategyType>>
776 (modifier->GetProperty())->Get();
777 propertyDesc += std::to_string(static_cast<int>(propertyValue));
778 } else if (type == RSModifierType::GEOMETRYTRANS) {
779 propertyDesc += "GEOMETRYTRANS:[";
780 auto propertyValue = std::static_pointer_cast<RSRenderProperty<SkMatrix>>
781 (modifier->GetProperty())->Get();
782 propertyValue.dump(propertyDesc, 0);
783 }
784 }
785
ResetIsOnlyBasicGeoTransform()786 void RSRenderNode::ResetIsOnlyBasicGeoTransform()
787 {
788 isOnlyBasicGeoTransform_ = true;
789 }
790
IsOnlyBasicGeoTransform() const791 bool RSRenderNode::IsOnlyBasicGeoTransform() const
792 {
793 return isOnlyBasicGeoTransform_;
794 }
795
796 // attention: current all base node's dirty ops causing content dirty
SetContentDirty()797 void RSRenderNode::SetContentDirty()
798 {
799 isContentDirty_ = true;
800 isOnlyBasicGeoTransform_ = false;
801 SetDirty();
802 }
803
SetDirty(bool forceAddToActiveList)804 void RSRenderNode::SetDirty(bool forceAddToActiveList)
805 {
806 // TO avoid redundant add, only add if both: 1. on-tree node 2. newly dirty node (or forceAddToActiveList = true)
807 #ifndef USE_ROSEN_DRAWING
808 if (dirtyStatus_ == NodeDirty::CLEAN || dirtyTypes_.empty() || forceAddToActiveList) {
809 #else
810 if (dirtyStatus_ == NodeDirty::CLEAN || dirtyTypes_.none() || forceAddToActiveList) {
811 #endif
812 if (auto context = GetContext().lock()) {
813 context->AddActiveNode(shared_from_this());
814 }
815 }
816 dirtyStatus_ = NodeDirty::DIRTY;
817 }
818
819 void RSRenderNode::SetClean()
820 {
821 isNewOnTree_ = false;
822 isContentDirty_ = false;
823 dirtyStatus_ = NodeDirty::CLEAN;
824 }
825
826 void RSRenderNode::CollectSurface(
827 const std::shared_ptr<RSRenderNode>& node, std::vector<RSRenderNode::SharedPtr>& vec, bool isUniRender,
828 bool onlyFirstLevel)
829 {
830 for (auto& child : *node->GetSortedChildren()) {
831 child->CollectSurface(child, vec, isUniRender, onlyFirstLevel);
832 }
833 }
834
835 void RSRenderNode::CollectSurfaceForUIFirstSwitch(uint32_t& leashWindowCount, uint32_t minNodeNum)
836 {
837 for (auto& child : *GetSortedChildren()) {
838 child->CollectSurfaceForUIFirstSwitch(leashWindowCount, minNodeNum);
839 if (leashWindowCount >= minNodeNum) {
840 return;
841 }
842 }
843 }
844
845 void RSRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
846 {
847 if (!visitor) {
848 return;
849 }
850 visitor->PrepareChildren(*this);
851 }
852
853 void RSRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
854 {
855 if (!visitor) {
856 return;
857 }
858 visitor->ProcessChildren(*this);
859 }
860
861 void RSRenderNode::SendCommandFromRT(std::unique_ptr<RSCommand>& command, NodeId nodeId)
862 {
863 auto transactionProxy = RSTransactionProxy::GetInstance();
864 if (transactionProxy != nullptr) {
865 transactionProxy->AddCommandFromRT(command, nodeId);
866 }
867 }
868
869 void RSRenderNode::InternalRemoveSelfFromDisappearingChildren()
870 {
871 // internal use only, force remove self from parent's disappearingChildren_
872 auto parent = parent_.lock();
873 if (parent == nullptr) {
874 return;
875 }
876 auto it = std::find_if(parent->disappearingChildren_.begin(), parent->disappearingChildren_.end(),
877 [childPtr = shared_from_this()](const auto& pair) -> bool { return pair.first == childPtr; });
878 if (it == parent->disappearingChildren_.end()) {
879 return;
880 }
881 parent->disappearingChildren_.erase(it);
882 parent->isFullChildrenListValid_ = false;
883 ResetParent();
884 }
885
886 RSRenderNode::~RSRenderNode()
887 {
888 if (appPid_ != 0) {
889 RSSingleFrameComposer::AddOrRemoveAppPidToMap(false, appPid_);
890 }
891 if (fallbackAnimationOnDestroy_) {
892 FallbackAnimationsToRoot();
893 }
894 if (clearCacheSurfaceFunc_ && (cacheSurface_ || cacheCompletedSurface_)) {
895 clearCacheSurfaceFunc_(std::move(cacheSurface_), std::move(cacheCompletedSurface_), cacheSurfaceThreadIndex_,
896 completedSurfaceThreadIndex_);
897 }
898 ClearCacheSurface();
899 }
900
901 void RSRenderNode::FallbackAnimationsToRoot()
902 {
903 if (animationManager_.animations_.empty()) {
904 return;
905 }
906
907 auto context = GetContext().lock();
908 if (!context) {
909 ROSEN_LOGE("Invalid context");
910 return;
911 }
912 auto target = context->GetNodeMap().GetAnimationFallbackNode();
913 if (!target) {
914 ROSEN_LOGE("Failed to move animation to root, root render node is null!");
915 return;
916 }
917 context->RegisterAnimatingRenderNode(target);
918
919 for (auto& [unused, animation] : animationManager_.animations_) {
920 animation->Detach(true);
921 // avoid infinite loop for fallback animation
922 animation->SetRepeatCount(1);
923 target->animationManager_.AddAnimation(std::move(animation));
924 }
925 animationManager_.animations_.clear();
926 }
927
928 void RSRenderNode::ActivateDisplaySync()
929 {
930 if (!displaySync_) {
931 displaySync_ = std::make_shared<RSRenderDisplaySync>(GetId());
932 }
933 }
934
935 void RSRenderNode::InActivateDisplaySync()
936 {
937 displaySync_ = nullptr;
938 }
939
940 void RSRenderNode::UpdateDisplaySyncRange()
941 {
942 if (!displaySync_) {
943 return;
944 }
945 auto animationRange = animationManager_.GetFrameRateRange();
946 if (animationRange.IsValid()) {
947 displaySync_->SetExpectedFrameRateRange(animationRange);
948 }
949 }
950
951 std::tuple<bool, bool, bool> RSRenderNode::Animate(int64_t timestamp, int64_t period, bool isDisplaySyncEnabled)
952 {
953 if (displaySync_ && displaySync_->OnFrameSkip(timestamp, period, isDisplaySyncEnabled)) {
954 return displaySync_->GetAnimateResult();
955 }
956 RS_OPTIONAL_TRACE_BEGIN("RSRenderNode:Animate node id: [" + std::to_string(GetId()) + "]");
957 auto animateResult = animationManager_.Animate(timestamp, IsOnTheTree());
958 if (displaySync_) {
959 displaySync_->SetAnimateResult(animateResult);
960 }
961 RS_OPTIONAL_TRACE_END();
962 return animateResult;
963 }
964
965 bool RSRenderNode::IsClipBound() const
966 {
967 return GetRenderProperties().GetClipBounds() || GetRenderProperties().GetClipToFrame();
968 }
969
970 const std::shared_ptr<RSRenderContent> RSRenderNode::GetRenderContent() const
971 {
972 return renderContent_;
973 }
974
975 bool RSRenderNode::Update(
976 RSDirtyRegionManager& dirtyManager, const std::shared_ptr<RSRenderNode>& parent, bool parentDirty,
977 std::optional<RectI> clipRect)
978 {
979 // no need to update invisible nodes
980 if (!ShouldPaint() && !isLastVisible_) {
981 SetClean();
982 GetMutableRenderProperties().ResetDirty();
983 return false;
984 }
985 // [planning] surfaceNode use frame instead
986 #ifndef USE_ROSEN_DRAWING
987 std::optional<SkPoint> offset;
988 if (parent != nullptr && !IsInstanceOf<RSSurfaceRenderNode>()) {
989 auto& properties = parent->GetRenderProperties();
990 offset = SkPoint { properties.GetFrameOffsetX(), properties.GetFrameOffsetY() };
991 }
992 #else
993 std::optional<Drawing::Point> offset;
994 if (parent != nullptr && !IsInstanceOf<RSSurfaceRenderNode>()) {
995 auto& properties = parent->GetRenderProperties();
996 offset = Drawing::Point { properties.GetFrameOffsetX(), properties.GetFrameOffsetY() };
997 }
998 #endif
999 // in some case geodirty_ is not marked in drawCmdModifiers_, we should update node geometry
1000 // [planing] using drawcmdModifierDirty from dirtyType_
1001 parentDirty = parentDirty || (dirtyStatus_ != NodeDirty::CLEAN);
1002 auto parentProperties = parent ? &parent->GetRenderProperties() : nullptr;
1003 bool dirty = GetMutableRenderProperties().UpdateGeometry(parentProperties, parentDirty, offset,
1004 GetContextClipRegion());
1005 if ((IsDirty() || dirty) && renderContent_->drawCmdModifiers_.count(RSModifierType::GEOMETRYTRANS)) {
1006 RSModifierContext context = { GetMutableRenderProperties() };
1007 for (auto& modifier : renderContent_->drawCmdModifiers_[RSModifierType::GEOMETRYTRANS]) {
1008 modifier->Apply(context);
1009 }
1010 }
1011 isDirtyRegionUpdated_ = false;
1012 isLastVisible_ = ShouldPaint();
1013 GetMutableRenderProperties().ResetDirty();
1014
1015 // Note:
1016 // 1. cache manager will use dirty region to update cache validity, background filter cache manager should use
1017 // 'dirty region of all the nodes drawn before this node', and foreground filter cache manager should use 'dirty
1018 // region of all the nodes drawn before this node, this node, and the children of this node'
1019 // 2. Filter must be valid when filter cache manager is valid, we make sure that in RSRenderNode::ApplyModifiers().
1020 UpdateFilterCacheWithDirty(dirtyManager, false);
1021 UpdateDirtyRegion(dirtyManager, dirty, clipRect);
1022 return dirty;
1023 }
1024
1025 RSProperties& RSRenderNode::GetMutableRenderProperties()
1026 {
1027 return renderContent_->GetMutableRenderProperties();
1028 }
1029
1030 const RSProperties& RSRenderNode::GetRenderProperties() const
1031 {
1032 return renderContent_->GetRenderProperties();
1033 }
1034
1035 void RSRenderNode::UpdateDirtyRegion(
1036 RSDirtyRegionManager& dirtyManager, bool geoDirty, std::optional<RectI> clipRect)
1037 {
1038 if (!IsDirty() && !geoDirty) {
1039 return;
1040 }
1041 if (RSSystemProperties::GetSkipGeometryNotChangeEnabled()) {
1042 // while node absRect not change and other content not change, return directly for not generate dirty region
1043 if (!IsSelfDrawingNode() && !geometryChangeNotPerceived_ && !geoDirty) {
1044 return;
1045 }
1046 geometryChangeNotPerceived_ = false;
1047 }
1048 if (!oldDirty_.IsEmpty()) {
1049 dirtyManager.MergeDirtyRect(oldDirty_);
1050 }
1051 // merge old dirty if switch to invisible
1052 if (!ShouldPaint() && isLastVisible_) {
1053 ROSEN_LOGD("RSRenderNode:: id %{public}" PRIu64 " UpdateDirtyRegion visible->invisible", GetId());
1054 } else {
1055 RectI drawRegion;
1056 RectI shadowRect;
1057 auto dirtyRect = GetRenderProperties().GetDirtyRect(drawRegion);
1058 auto rectFromRenderProperties = dirtyRect;
1059 if (GetRenderProperties().IsShadowValid()) {
1060 SetShadowValidLastFrame(true);
1061 if (IsInstanceOf<RSSurfaceRenderNode>()) {
1062 const RectF absBounds = {0, 0, GetRenderProperties().GetBoundsWidth(),
1063 GetRenderProperties().GetBoundsHeight()};
1064 RRect absClipRRect = RRect(absBounds, GetRenderProperties().GetCornerRadius());
1065 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &absClipRRect);
1066 } else {
1067 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties());
1068 }
1069 if (!shadowRect.IsEmpty()) {
1070 dirtyRect = dirtyRect.JoinRect(shadowRect);
1071 }
1072 }
1073
1074 auto outline = GetRenderProperties().GetOutline();
1075 RectI outlineRect;
1076 if (outline && outline->HasBorder()) {
1077 RSPropertiesPainter::GetOutlineDirtyRect(outlineRect, GetRenderProperties());
1078 if (!outlineRect.IsEmpty()) {
1079 dirtyRect = dirtyRect.JoinRect(outlineRect);
1080 }
1081 }
1082
1083 if (GetRenderProperties().pixelStretch_) {
1084 auto stretchDirtyRect = GetRenderProperties().GetPixelStretchDirtyRect();
1085 dirtyRect = dirtyRect.JoinRect(stretchDirtyRect);
1086 }
1087
1088 if (clipRect.has_value()) {
1089 dirtyRect = dirtyRect.IntersectRect(*clipRect);
1090 }
1091 oldDirty_ = dirtyRect;
1092 oldDirtyInSurface_ = oldDirty_.IntersectRect(dirtyManager.GetSurfaceRect());
1093 // filter invalid dirtyrect
1094 if (!dirtyRect.IsEmpty()) {
1095 dirtyManager.MergeDirtyRect(dirtyRect);
1096 isDirtyRegionUpdated_ = true;
1097 // save types of dirty region of target dirty manager for dfx
1098 if (dirtyManager.IsTargetForDfx() &&
1099 (GetType() == RSRenderNodeType::CANVAS_NODE || GetType() == RSRenderNodeType::SURFACE_NODE)) {
1100 dirtyManager.UpdateDirtyRegionInfoForDfx(
1101 GetId(), GetType(), DirtyRegionType::UPDATE_DIRTY_REGION, oldDirtyInSurface_);
1102 dirtyManager.UpdateDirtyRegionInfoForDfx(
1103 GetId(), GetType(), DirtyRegionType::OVERLAY_RECT, drawRegion);
1104 dirtyManager.UpdateDirtyRegionInfoForDfx(
1105 GetId(), GetType(), DirtyRegionType::SHADOW_RECT, shadowRect);
1106 dirtyManager.UpdateDirtyRegionInfoForDfx(
1107 GetId(), GetType(), DirtyRegionType::PREPARE_CLIP_RECT, clipRect.value_or(RectI()));
1108 dirtyManager.UpdateDirtyRegionInfoForDfx(
1109 GetId(), GetType(), DirtyRegionType::RENDER_PROPERTIES_RECT, rectFromRenderProperties);
1110 dirtyManager.UpdateDirtyRegionInfoForDfx(
1111 GetId(), GetType(), DirtyRegionType::OUTLINE_RECT, outlineRect);
1112 }
1113 }
1114 }
1115
1116 SetClean();
1117 }
1118
1119 bool RSRenderNode::IsSelfDrawingNode() const
1120 {
1121 return GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE || GetType() == RSRenderNodeType::SURFACE_NODE;
1122 }
1123
1124 bool RSRenderNode::IsDirty() const
1125 {
1126 return dirtyStatus_ != NodeDirty::CLEAN || GetRenderProperties().IsDirty();
1127 }
1128
1129 bool RSRenderNode::IsContentDirty() const
1130 {
1131 // Considering renderNode, it should consider both basenode's case and its properties
1132 return isContentDirty_ || GetRenderProperties().IsContentDirty();
1133 }
1134
1135 void RSRenderNode::UpdateRenderStatus(RectI& dirtyRegion, bool isPartialRenderEnabled)
1136 {
1137 auto dirtyRect = GetRenderProperties().GetDirtyRect();
1138 // should judge if there's any child out of parent
1139 if (!isPartialRenderEnabled || HasChildrenOutOfRect()) {
1140 isRenderUpdateIgnored_ = false;
1141 } else if (dirtyRegion.IsEmpty() || dirtyRect.IsEmpty()) {
1142 isRenderUpdateIgnored_ = true;
1143 } else {
1144 RectI intersectRect = dirtyRegion.IntersectRect(dirtyRect);
1145 isRenderUpdateIgnored_ = intersectRect.IsEmpty();
1146 }
1147 }
1148
1149 void RSRenderNode::UpdateParentChildrenRect(std::shared_ptr<RSRenderNode> parentNode) const
1150 {
1151 if (!ShouldPaint() || (oldDirty_.IsEmpty() && GetChildrenRect().IsEmpty())) {
1152 return;
1153 }
1154 auto renderParent = (parentNode);
1155 if (renderParent) {
1156 // accumulate current node's all children region(including itself)
1157 // apply oldDirty_ as node's real region(including overlay and shadow)
1158 RectI accumulatedRect = GetChildrenRect().JoinRect(oldDirty_);
1159 renderParent->UpdateChildrenRect(accumulatedRect);
1160 // check each child is inside of parent
1161 if (!accumulatedRect.IsInsideOf(renderParent->GetOldDirty())) {
1162 renderParent->UpdateChildrenOutOfRectFlag(true);
1163 }
1164 }
1165 }
1166
1167 bool RSRenderNode::IsBackgroundFilterCacheValid() const
1168 {
1169 auto& manager = GetRenderProperties().GetFilterCacheManager(false);
1170 if (manager == nullptr) {
1171 return false;
1172 }
1173 bool backgroundFilterCacheValid = manager->IsCacheValid();
1174 return backgroundFilterCacheValid;
1175 }
1176
1177 void RSRenderNode::UpdateFilterCacheWithDirty(RSDirtyRegionManager& dirtyManager, bool isForeground)
1178 {
1179 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
1180 if (!RSProperties::FilterCacheEnabled) {
1181 return;
1182 }
1183 auto& properties = GetRenderProperties();
1184 auto& manager = properties.GetFilterCacheManager(isForeground);
1185 if (manager == nullptr) {
1186 return;
1187 }
1188 if (!manager->IsCacheValid()) {
1189 return;
1190 }
1191 auto& cachedImageRect = manager->GetCachedImageRegion();
1192 if (manager->UpdateCacheStateWithDirtyRegion(dirtyManager)) {
1193 dirtyManager.MergeDirtyRect(cachedImageRect);
1194 }
1195 #endif
1196 }
1197
1198 void RSRenderNode::RenderTraceDebug() const
1199 {
1200 if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
1201 RSPropertyTrace::GetInstance().PropertiesDisplayByTrace(GetId(), GetRenderProperties());
1202 }
1203 }
1204
1205 void RSRenderNode::ApplyBoundsGeometry(RSPaintFilterCanvas& canvas)
1206 {
1207 if (RSSystemProperties::GetPropertyDrawableEnable()) {
1208 DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::BOUNDS_MATRIX, canvas);
1209 return;
1210 }
1211 #ifndef USE_ROSEN_DRAWING
1212 renderNodeSaveCount_ = canvas.Save();
1213 #else
1214 renderNodeSaveCount_ = canvas.SaveAllStatus();
1215 #endif
1216 auto boundsGeo = (GetRenderProperties().GetBoundsGeometry());
1217 if (boundsGeo && !boundsGeo->IsEmpty()) {
1218 #ifndef USE_ROSEN_DRAWING
1219 canvas.concat(boundsGeo->GetMatrix());
1220 #else
1221 canvas.ConcatMatrix(boundsGeo->GetMatrix());
1222 #endif
1223 }
1224 }
1225
1226 void RSRenderNode::ApplyAlpha(RSPaintFilterCanvas& canvas)
1227 {
1228 if (RSSystemProperties::GetPropertyDrawableEnable()) {
1229 DrawPropertyDrawable(RSPropertyDrawableSlot::ALPHA, canvas);
1230 return;
1231 }
1232 auto alpha = GetRenderProperties().GetAlpha();
1233 if (alpha < 1.f) {
1234 if (!(GetRenderProperties().GetAlphaOffscreen() || IsForcedDrawInGroup())) {
1235 canvas.MultiplyAlpha(alpha);
1236 } else {
1237 #ifndef USE_ROSEN_DRAWING
1238 auto rect = RSPropertiesPainter::Rect2SkRect(GetRenderProperties().GetBoundsRect());
1239 canvas.saveLayerAlpha(&rect, std::clamp(alpha, 0.f, 1.f) * UINT8_MAX);
1240 #else
1241 auto rect = RSPropertiesPainter::Rect2DrawingRect(GetRenderProperties().GetBoundsRect());
1242 Drawing::Brush brush;
1243 brush.SetAlpha(std::clamp(alpha, 0.f, 1.f) * UINT8_MAX);
1244 Drawing::SaveLayerOps slr(&rect, &brush);
1245 canvas.SaveLayer(slr);
1246 #endif
1247 }
1248 }
1249 }
1250
1251 void RSRenderNode::ProcessTransitionBeforeChildren(RSPaintFilterCanvas& canvas)
1252 {
1253 if (RSSystemProperties::GetPropertyDrawableEnable()) {
1254 DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::MASK, canvas);
1255 return;
1256 }
1257 ApplyBoundsGeometry(canvas);
1258 ApplyAlpha(canvas);
1259 RSPropertiesPainter::DrawMask(GetRenderProperties(), canvas);
1260 }
1261
1262 void RSRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
1263 {
1264 RSRenderNode::ProcessTransitionBeforeChildren(canvas);
1265 }
1266
1267 void RSRenderNode::ProcessTransitionAfterChildren(RSPaintFilterCanvas& canvas)
1268 {
1269 if (RSSystemProperties::GetPropertyDrawableEnable()) {
1270 DrawPropertyDrawable(RSPropertyDrawableSlot::RESTORE_ALL, canvas);
1271 return;
1272 }
1273 canvas.RestoreStatus(renderNodeSaveCount_);
1274 }
1275
1276 void RSRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
1277 {
1278 if (RSSystemProperties::GetPropertyDrawableEnable()) {
1279 DrawPropertyDrawable(RSPropertyDrawableSlot::RESTORE_ALL, canvas);
1280 return;
1281 }
1282 canvas.RestoreStatus(renderNodeSaveCount_);
1283 }
1284
1285 void RSRenderNode::AddModifier(const std::shared_ptr<RSRenderModifier>& modifier, bool isSingleFrameComposer)
1286 {
1287 if (!modifier) {
1288 return;
1289 }
1290 SetDirty();
1291 if (RSSystemProperties::GetSingleFrameComposerEnabled() &&
1292 GetNodeIsSingleFrameComposer() && isSingleFrameComposer) {
1293 if (singleFrameComposer_ == nullptr) {
1294 singleFrameComposer_ = std::make_shared<RSSingleFrameComposer>();
1295 }
1296 singleFrameComposer_->SingleFrameAddModifier(modifier);
1297 return;
1298 }
1299 if (modifier->GetType() == RSModifierType::BOUNDS || modifier->GetType() == RSModifierType::FRAME) {
1300 AddGeometryModifier(modifier);
1301 } else if (modifier->GetType() < RSModifierType::CUSTOM) {
1302 modifiers_.emplace(modifier->GetPropertyId(), modifier);
1303 } else {
1304 modifier->SetSingleFrameModifier(false);
1305 renderContent_->drawCmdModifiers_[modifier->GetType()].emplace_back(modifier);
1306 }
1307 modifier->GetProperty()->Attach(shared_from_this());
1308 }
1309
1310 void RSRenderNode::AddGeometryModifier(const std::shared_ptr<RSRenderModifier>& modifier)
1311 {
1312 // bounds and frame modifiers must be unique
1313 if (modifier->GetType() == RSModifierType::BOUNDS) {
1314 if (boundsModifier_ == nullptr) {
1315 boundsModifier_ = modifier;
1316 } else {
1317 boundsModifier_->Update(modifier->GetProperty(), false);
1318 }
1319 modifiers_.emplace(modifier->GetPropertyId(), boundsModifier_);
1320 }
1321
1322 if (modifier->GetType() == RSModifierType::FRAME) {
1323 if (frameModifier_ == nullptr) {
1324 frameModifier_ = modifier;
1325 } else {
1326 frameModifier_->Update(modifier->GetProperty(), false);
1327 }
1328 modifiers_.emplace(modifier->GetPropertyId(), frameModifier_);
1329 }
1330 }
1331
1332 void RSRenderNode::RemoveModifier(const PropertyId& id)
1333 {
1334 SetDirty();
1335 auto it = modifiers_.find(id);
1336 if (it != modifiers_.end()) {
1337 if (it->second) {
1338 AddDirtyType(it->second->GetType());
1339 }
1340 modifiers_.erase(it);
1341 return;
1342 }
1343 for (auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
1344 modifiers.remove_if([id](const auto& modifier) -> bool {
1345 return modifier ? modifier->GetPropertyId() == id : true;
1346 });
1347 }
1348 }
1349
1350 void RSRenderNode::DumpNodeInfo(DfxString& log)
1351 {
1352 #ifndef USE_ROSEN_DRAWING
1353 for (const auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
1354 for (auto modifier : modifiers) {
1355 modifier->DumpPicture(log);
1356 }
1357 }
1358 #else
1359 // Drawing is not supported
1360 #endif
1361 }
1362
1363 bool RSRenderNode::ApplyModifiers()
1364 {
1365 // quick reject test
1366 #ifndef USE_ROSEN_DRAWING
1367 if (!RSRenderNode::IsDirty() || dirtyTypes_.empty()) {
1368 #else
1369 if (!RSRenderNode::IsDirty() || dirtyTypes_.none()) {
1370 #endif
1371 return false;
1372 }
1373 const auto prevPositionZ = GetRenderProperties().GetPositionZ();
1374
1375 // Reset and re-apply all modifiers
1376 RSModifierContext context = { GetMutableRenderProperties() };
1377
1378 // Reset before apply modifiers
1379 GetMutableRenderProperties().ResetProperty(dirtyTypes_);
1380
1381 // Apply modifiers
1382 for (auto& [id, modifier] : modifiers_) {
1383 #ifndef USE_ROSEN_DRAWING
1384 if (!dirtyTypes_.count(modifier->GetType())) {
1385 #else
1386 if (!dirtyTypes_.test(static_cast<size_t>(modifier->GetType()))) {
1387 #endif
1388 continue;
1389 }
1390 modifier->Apply(context);
1391 if (!BASIC_GEOTRANSFORM_ANIMATION_TYPE.count(modifier->GetType())) {
1392 isOnlyBasicGeoTransform_ = false;
1393 }
1394 }
1395 // execute hooks
1396 GetMutableRenderProperties().OnApplyModifiers();
1397 OnApplyModifiers();
1398
1399 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
1400 if (auto& manager = GetRenderProperties().GetFilterCacheManager(false);
1401 manager != nullptr &&
1402 #ifndef USE_ROSEN_DRAWING
1403 (dirtyTypes_.count(RSModifierType::BACKGROUND_COLOR) || dirtyTypes_.count(RSModifierType::BG_IMAGE))) {
1404 #else
1405 (dirtyTypes_.test(static_cast<size_t>(RSModifierType::BACKGROUND_COLOR)) ||
1406 dirtyTypes_.test(static_cast<size_t>(RSModifierType::BG_IMAGE)))) {
1407 #endif
1408 manager->InvalidateCache();
1409 }
1410 if (auto& manager = GetRenderProperties().GetFilterCacheManager(true)) {
1411 manager->InvalidateCache();
1412 }
1413
1414 if (RSSystemProperties::GetPropertyDrawableEnable()) {
1415 // Generate drawable
1416 UpdateDrawableVec();
1417 }
1418 #endif
1419
1420 // update state
1421 #ifndef USE_ROSEN_DRAWING
1422 dirtyTypes_.clear();
1423 #else
1424 dirtyTypes_.reset();
1425 #endif
1426 UpdateShouldPaint();
1427
1428 // update rate decider scale reference size.
1429 animationManager_.SetRateDeciderScaleSize(GetRenderProperties().GetBoundsWidth(),
1430 GetRenderProperties().GetBoundsHeight());
1431
1432 // return true if positionZ changed
1433 return GetRenderProperties().GetPositionZ() != prevPositionZ;
1434 }
1435
1436 void RSRenderNode::UpdateDrawableVec()
1437 {
1438 #ifndef ROSEN_ARKUI_X
1439 // Collect dirty slots
1440 auto dirtySlots = RSPropertyDrawable::GenerateDirtySlots(GetRenderProperties(), dirtyTypes_);
1441 if (!GetIsUsedBySubThread()) {
1442 UpdateDrawableVecInternal(dirtySlots);
1443 } else if (auto context = context_.lock()) {
1444 context->PostTask([weakPtr = weak_from_this(), dirtySlots]() {
1445 if (auto node = weakPtr.lock()) {
1446 node->UpdateDrawableVecInternal(dirtySlots);
1447 }
1448 });
1449 } else {
1450 ROSEN_LOGI("%{public}s GetIsUsedBySubThread[%{public}d].", __func__, GetIsUsedBySubThread());
1451 UpdateDrawableVecInternal(dirtySlots);
1452 }
1453 #endif
1454 }
1455
1456 void RSRenderNode::UpdateDrawableVecInternal(std::unordered_set<RSPropertyDrawableSlot> dirtySlots)
1457 {
1458 #ifndef ROSEN_ARKUI_X
1459 // initialize necessary save/clip/restore
1460 if (drawableVecStatus_ == 0) {
1461 RSPropertyDrawable::InitializeSaveRestore(*renderContent_, renderContent_->propertyDrawablesVec_);
1462 }
1463 // Update or regenerate drawable
1464 bool drawableChanged =
1465 RSPropertyDrawable::UpdateDrawableVec(*renderContent_, renderContent_->propertyDrawablesVec_, dirtySlots);
1466 // if 1. first initialized or 2. any drawables changed, update save/clip/restore
1467 if (drawableChanged || drawableVecStatus_ == 0) {
1468 RSPropertyDrawable::UpdateSaveRestore(
1469 *renderContent_, renderContent_->propertyDrawablesVec_, drawableVecStatus_);
1470 }
1471 #endif
1472 }
1473
1474 #ifndef USE_ROSEN_DRAWING
1475 void RSRenderNode::UpdateEffectRegion(std::optional<SkIRect>& region, bool isForced)
1476 #else
1477 void RSRenderNode::UpdateEffectRegion(std::optional<Drawing::RectI>& region, bool isForced)
1478 #endif
1479 {
1480 if (!region.has_value()) {
1481 return;
1482 }
1483 const auto& property = GetRenderProperties();
1484 if (!isForced && !property.GetUseEffect()) {
1485 return;
1486 }
1487
1488 auto absRect = property.GetBoundsGeometry()->GetAbsRect();
1489 #ifndef USE_ROSEN_DRAWING
1490 region->join(SkIRect::MakeXYWH(absRect.GetLeft(), absRect.GetTop(), absRect.GetWidth(), absRect.GetHeight()));
1491 #else
1492 region->Join(Drawing::RectI(absRect.GetLeft(), absRect.GetTop(), absRect.GetRight(), absRect.GetBottom()));
1493 #endif
1494 }
1495
1496 std::shared_ptr<RSRenderModifier> RSRenderNode::GetModifier(const PropertyId& id)
1497 {
1498 if (modifiers_.count(id)) {
1499 return modifiers_[id];
1500 }
1501 for (const auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
1502 auto it = std::find_if(modifiers.begin(), modifiers.end(),
1503 [id](const auto& modifier) -> bool { return modifier->GetPropertyId() == id; });
1504 if (it != modifiers.end()) {
1505 return *it;
1506 }
1507 }
1508 return nullptr;
1509 }
1510
1511 void RSRenderNode::FilterModifiersByPid(pid_t pid)
1512 {
1513 // remove all modifiers added by given pid (by matching higher 32 bits of node id)
1514 EraseIf(modifiers_, [pid](const auto& pair) -> bool { return ExtractPid(pair.first) == pid; });
1515
1516 // remove all modifiers added by given pid (by matching higher 32 bits of node id)
1517 for (auto& [type, modifiers] : renderContent_->drawCmdModifiers_) {
1518 modifiers.remove_if(
1519 [pid](const auto& it) -> bool { return ExtractPid(it->GetPropertyId()) == pid; });
1520 }
1521 }
1522
1523 bool RSRenderNode::ShouldPaint() const
1524 {
1525 return shouldPaint_;
1526 }
1527
1528 void RSRenderNode::UpdateShouldPaint()
1529 {
1530 // node should be painted if either it is visible or it has disappearing transition animation, but only when its
1531 // alpha is not zero
1532 shouldPaint_ = (GetRenderProperties().GetAlpha() > 0.0f) &&
1533 (GetRenderProperties().GetVisible() || HasDisappearingTransition(false));
1534 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
1535 if (!shouldPaint_) {
1536 // clear filter cache when node is not visible
1537 GetMutableRenderProperties().ClearFilterCache();
1538 GetMutableRenderProperties().ReleaseColorPickerTaskShadow();
1539 }
1540 #endif
1541 }
1542
1543 void RSRenderNode::SetSharedTransitionParam(const std::optional<SharedTransitionParam>&& sharedTransitionParam)
1544 {
1545 if (!sharedTransitionParam_.has_value() && !sharedTransitionParam.has_value()) {
1546 // both are empty, do nothing
1547 return;
1548 }
1549 sharedTransitionParam_ = sharedTransitionParam;
1550 SetDirty();
1551 }
1552
1553 const std::optional<RSRenderNode::SharedTransitionParam>& RSRenderNode::GetSharedTransitionParam() const
1554 {
1555 return sharedTransitionParam_;
1556 }
1557
1558 void RSRenderNode::SetGlobalAlpha(float alpha)
1559 {
1560 if (globalAlpha_ == alpha) {
1561 return;
1562 }
1563 if ((ROSEN_EQ(globalAlpha_, 1.0f) && alpha != 1.0f) ||
1564 (ROSEN_EQ(alpha, 1.0f) && globalAlpha_ != 1.0f)) {
1565 OnAlphaChanged();
1566 }
1567 globalAlpha_ = alpha;
1568 }
1569
1570 float RSRenderNode::GetGlobalAlpha() const
1571 {
1572 return globalAlpha_;
1573 }
1574
1575 void RSRenderNode::SetBootAnimation(bool isBootAnimation)
1576 {
1577 ROSEN_LOGD("SetBootAnimation:: id:%{public}" PRIu64 "isBootAnimation %{public}d",
1578 GetId(), isBootAnimation);
1579 isBootAnimation_ = isBootAnimation;
1580 }
1581
1582 bool RSRenderNode::GetBootAnimation() const
1583 {
1584 return isBootAnimation_;
1585 }
1586
1587 bool RSRenderNode::NeedInitCacheSurface() const
1588 {
1589 auto cacheType = GetCacheType();
1590 int width = 0;
1591 int height = 0;
1592 if (cacheType == CacheType::ANIMATE_PROPERTY &&
1593 GetRenderProperties().IsShadowValid() && !GetRenderProperties().IsSpherizeValid()) {
1594 const RectF boundsRect = GetRenderProperties().GetBoundsRect();
1595 RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
1596 RectI shadowRect;
1597 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &rrect, false);
1598 width = shadowRect.GetWidth();
1599 height = shadowRect.GetHeight();
1600 } else {
1601 Vector2f size = GetOptionalBufferSize();
1602 width = size.x_;
1603 height = size.y_;
1604 }
1605 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1606 if (cacheSurface_ == nullptr) {
1607 return true;
1608 }
1609 #ifndef USE_ROSEN_DRAWING
1610 return cacheSurface_->width() != width || cacheSurface_->height() !=height;
1611 #else
1612 auto cacheCanvas = cacheSurface_->GetCanvas();
1613 if (cacheCanvas == nullptr) {
1614 return true;
1615 }
1616 return cacheCanvas->GetWidth() != width || cacheCanvas->GetHeight() != height;
1617 #endif
1618 }
1619
1620 bool RSRenderNode::NeedInitCacheCompletedSurface() const
1621 {
1622 Vector2f size = GetOptionalBufferSize();
1623 int width = static_cast<int>(size.x_);
1624 int height = static_cast<int>(size.y_);
1625 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1626 if (cacheCompletedSurface_ == nullptr) {
1627 return true;
1628 }
1629 #ifndef USE_ROSEN_DRAWING
1630 return cacheCompletedSurface_->width() != width || cacheCompletedSurface_->height() !=height;
1631 #else
1632 auto cacheCanvas = cacheCompletedSurface_->GetCanvas();
1633 if (cacheCanvas == nullptr) {
1634 return true;
1635 }
1636 return cacheCanvas->GetWidth() != width || cacheCanvas->GetHeight() != height;
1637 #endif
1638 }
1639
1640 #ifndef USE_ROSEN_DRAWING
1641 #ifdef NEW_SKIA
1642 void RSRenderNode::InitCacheSurface(GrRecordingContext* grContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1643 #else
1644 void RSRenderNode::InitCacheSurface(GrContext* grContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1645 #endif
1646 #else
1647 void RSRenderNode::InitCacheSurface(Drawing::GPUContext* gpuContext, ClearCacheSurfaceFunc func, uint32_t threadIndex)
1648 #endif
1649 {
1650 if (func) {
1651 cacheSurfaceThreadIndex_ = threadIndex;
1652 if (!clearCacheSurfaceFunc_) {
1653 clearCacheSurfaceFunc_ = func;
1654 }
1655 if (cacheSurface_) {
1656 func(std::move(cacheSurface_), nullptr,
1657 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1658 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1659 cacheSurface_ = nullptr;
1660 }
1661 } else {
1662 cacheSurface_ = nullptr;
1663 }
1664 auto cacheType = GetCacheType();
1665 float width = 0.0f, height = 0.0f;
1666 Vector2f size = GetOptionalBufferSize();
1667 boundsWidth_ = size.x_;
1668 boundsHeight_ = size.y_;
1669 if (cacheType == CacheType::ANIMATE_PROPERTY &&
1670 GetRenderProperties().IsShadowValid() && !GetRenderProperties().IsSpherizeValid()) {
1671 const RectF boundsRect = GetRenderProperties().GetBoundsRect();
1672 RRect rrect = RRect(boundsRect, {0, 0, 0, 0});
1673 RectI shadowRect;
1674 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, GetRenderProperties(), &rrect, false);
1675 width = shadowRect.GetWidth();
1676 height = shadowRect.GetHeight();
1677 shadowRectOffsetX_ = -shadowRect.GetLeft();
1678 shadowRectOffsetY_ = -shadowRect.GetTop();
1679 } else {
1680 width = boundsWidth_;
1681 height = boundsHeight_;
1682 }
1683 #ifndef USE_ROSEN_DRAWING
1684 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
1685 if (grContext == nullptr) {
1686 if (func) {
1687 func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
1688 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1689 ClearCacheSurface();
1690 }
1691 return;
1692 }
1693 #ifdef RS_ENABLE_GL
1694 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
1695 OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
1696 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1697 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1698 cacheSurface_ = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
1699 }
1700 #endif
1701 #ifdef RS_ENABLE_VK
1702 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
1703 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
1704 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1705 cacheBackendTexture_ = MakeBackendTexture(width, height);
1706 if (!cacheBackendTexture_.isValid()) {
1707 if (func) {
1708 func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
1709 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1710 ClearCacheSurface();
1711 }
1712 return;
1713 }
1714 GrVkImageInfo imageInfo;
1715 cacheBackendTexture_.getVkImageInfo(&imageInfo);
1716 cacheCleanupHelper_ = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
1717 imageInfo.fImage, imageInfo.fAlloc.fMemory);
1718 SkSurfaceProps props(0, SkPixelGeometry::kUnknown_SkPixelGeometry);
1719 cacheSurface_ = SkSurface::MakeFromBackendTexture(
1720 grContext, cacheBackendTexture_, kBottomLeft_GrSurfaceOrigin, 1, kRGBA_8888_SkColorType,
1721 SkColorSpace::MakeSRGB(), &props, NativeBufferUtils::DeleteVkImage, cacheCleanupHelper_);
1722 }
1723 #endif
1724 #else
1725 cacheSurface_ = SkSurface::MakeRasterN32Premul(width, height);
1726 #endif
1727 #else // USE_ROSEN_DRAWING
1728 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
1729 if (gpuContext == nullptr) {
1730 if (func) {
1731 func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
1732 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1733 ClearCacheSurface();
1734 }
1735 return;
1736 }
1737 #ifdef RS_ENABLE_GL
1738 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
1739 OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
1740 Drawing::ImageInfo info = Drawing::ImageInfo::MakeN32Premul(width, height);
1741 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1742 cacheSurface_ = Drawing::Surface::MakeRenderTarget(gpuContext, true, info);
1743 }
1744 #endif
1745 #ifdef RS_ENABLE_VK
1746 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
1747 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
1748 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1749 cacheBackendTexture_ = MakeBackendTexture(width, height);
1750 auto vkTextureInfo = cacheBackendTexture_.GetTextureInfo().GetVKTextureInfo();
1751 if (!cacheBackendTexture_.isValid() || !vkTextureInfo) {
1752 if (func) {
1753 func(std::move(cacheSurface_), std::move(cacheCompletedSurface_),
1754 cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
1755 ClearCacheSurface();
1756 }
1757 return;
1758 }
1759 cacheCleanupHelper_ = new NativeBufferUtils::VulkanCleanupHelper(RsVulkanContext::GetSingleton(),
1760 vkTextureInfo->vkImage, vkTextureInfo->vkAlloc.memory);
1761 cacheSurface_ = Drawing::Surface::MakeFromBackendTexture(
1762 gpuContext, cacheBackendTexture_.GetTextureInfo(), Drawing::TextureOrigin::BOTTOM_LEFT,
1763 1, Drawing::ColorType::COLORTYPE_RGBA_8888, nullptr,
1764 NativeBufferUtils::DeleteVkImage, cacheCleanupHelper_);
1765 }
1766 #endif
1767 #else
1768 cacheSurface_ = Drawing::Surface::MakeRasterN32Premul(width, height);
1769 #endif
1770 #endif // USE_ROSEN_DRAWING
1771 }
1772
1773 bool RSRenderNode::IsCacheSurfaceValid() const
1774 {
1775 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1776 return (cacheCompletedSurface_ != nullptr);
1777 }
1778
1779 Vector2f RSRenderNode::GetOptionalBufferSize() const
1780 {
1781 const auto& modifier = boundsModifier_ ? boundsModifier_ : frameModifier_;
1782 if (!modifier) {
1783 return {0.0f, 0.0f};
1784 }
1785 auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(modifier->GetProperty());
1786 auto vector4f = renderProperty->Get();
1787 // bounds vector4f: x y z w -> left top width height
1788 return { vector4f.z_, vector4f.w_ };
1789 }
1790
1791 #ifndef USE_ROSEN_DRAWING
1792 void RSRenderNode::DrawCacheSurface(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1793 {
1794 if (ROSEN_EQ(boundsWidth_, 0.f) || ROSEN_EQ(boundsHeight_, 0.f)) {
1795 return;
1796 }
1797 auto cacheType = GetCacheType();
1798 canvas.save();
1799 Vector2f size = GetOptionalBufferSize();
1800 float scaleX = size.x_ / boundsWidth_;
1801 float scaleY = size.y_ / boundsHeight_;
1802 canvas.scale(scaleX, scaleY);
1803 auto cacheImage = GetCompletedImage(canvas, threadIndex, isUIFirst);
1804 if (cacheImage == nullptr) {
1805 canvas.restore();
1806 return;
1807 }
1808 auto samplingOptions = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
1809 if (RSSystemProperties::GetRecordingEnabled()) {
1810 if (cacheImage->isTextureBacked()) {
1811 RS_LOGI("RSRenderNode::DrawCacheSurface convert cacheImage from texture to raster image");
1812 cacheImage = cacheImage->makeRasterImage();
1813 }
1814 }
1815 if ((cacheType == CacheType::ANIMATE_PROPERTY && GetRenderProperties().IsShadowValid()) || isUIFirst) {
1816 auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
1817 Vector2f gravityTranslate = surfaceNode ?
1818 surfaceNode->GetGravityTranslate(cacheImage->Width(), cacheImage->Height()) : Vector2f(0.0f, 0.0f);
1819 canvas.drawImage(cacheImage, -shadowRectOffsetX_ * scaleX + gravityTranslate.x_,
1820 -shadowRectOffsetY_ * scaleY + gravityTranslate.y_, samplingOptions);
1821 } else {
1822 canvas.drawImage(cacheImage, 0.f, 0.f, samplingOptions);
1823 }
1824 canvas.restore();
1825 }
1826
1827 sk_sp<SkImage> RSRenderNode::GetCompletedImage(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1828 {
1829 if (isUIFirst) {
1830 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
1831 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1832 if (!cacheCompletedBackendTexture_.isValid()) {
1833 RS_LOGE("invalid grBackendTexture_");
1834 return nullptr;
1835 }
1836 #ifdef RS_ENABLE_VK
1837 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
1838 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
1839 if (!cacheCompletedSurface_ || !cacheCompletedCleanupHelper_) {
1840 return nullptr;
1841 }
1842 }
1843 #endif
1844 sk_sp<SkImage> image = nullptr;
1845 #ifdef RS_ENABLE_GL
1846 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
1847 OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
1848 image = SkImage::MakeFromTexture(canvas.recordingContext(), cacheCompletedBackendTexture_,
1849 kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
1850 }
1851 #endif
1852
1853 #ifdef RS_ENABLE_VK
1854 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
1855 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
1856 image = SkImage::MakeFromTexture(canvas.recordingContext(), cacheCompletedBackendTexture_,
1857 kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
1858 NativeBufferUtils::DeleteVkImage, cacheCompletedCleanupHelper_->Ref());
1859 }
1860 #endif
1861 return image;
1862 #endif
1863 }
1864
1865 if (!cacheCompletedSurface_) {
1866 RS_LOGE("DrawCacheSurface invalid cacheCompletedSurface");
1867 return nullptr;
1868 }
1869 auto completeImage = cacheCompletedSurface_->makeImageSnapshot();
1870 if (!completeImage) {
1871 RS_LOGE("Get complete image failed");
1872 return nullptr;
1873 }
1874 if (threadIndex == completedSurfaceThreadIndex_) {
1875 return completeImage;
1876 }
1877 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
1878 GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin;
1879 auto backendTexture = completeImage->getBackendTexture(false, &origin);
1880 if (!backendTexture.isValid()) {
1881 RS_LOGE("get backendTexture failed");
1882 return nullptr;
1883 }
1884 auto cacheImage = SkImage::MakeFromTexture(canvas.recordingContext(), backendTexture, origin,
1885 completeImage->colorType(), completeImage->alphaType(), nullptr);
1886 return cacheImage;
1887 #else
1888 return completeImage;
1889 #endif
1890 }
1891 #else
1892 void RSRenderNode::DrawCacheSurface(RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1893 {
1894 if (ROSEN_EQ(boundsWidth_, 0.f) || ROSEN_EQ(boundsHeight_, 0.f)) {
1895 return;
1896 }
1897 auto cacheType = GetCacheType();
1898 canvas.Save();
1899 Vector2f size = GetOptionalBufferSize();
1900 float scaleX = size.x_ / boundsWidth_;
1901 float scaleY = size.y_ / boundsHeight_;
1902 canvas.Scale(scaleX, scaleY);
1903 auto cacheImage = GetCompletedImage(canvas, threadIndex, isUIFirst);
1904 if (cacheImage == nullptr) {
1905 canvas.Restore();
1906 return;
1907 }
1908 auto samplingOptions = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
1909 if (RSSystemProperties::GetRecordingEnabled()) {
1910 if (cacheImage->IsTextureBacked()) {
1911 RS_LOGI("RSRenderNode::DrawCacheSurface convert cacheImage from texture to raster image");
1912 cacheImage = cacheImage->MakeRasterImage();
1913 }
1914 }
1915 Drawing::Brush brush;
1916 canvas.AttachBrush(brush);
1917 if ((cacheType == CacheType::ANIMATE_PROPERTY && GetRenderProperties().IsShadowValid()) || isUIFirst) {
1918 auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
1919 Vector2f gravityTranslate = surfaceNode ?
1920 surfaceNode->GetGravityTranslate(cacheImage->GetWidth(), cacheImage->GetHeight()) : Vector2f(0.0f, 0.0f);
1921 canvas.DrawImage(*cacheImage, -shadowRectOffsetX_ * scaleX + gravityTranslate.x_,
1922 -shadowRectOffsetY_ * scaleY + gravityTranslate.y_, samplingOptions);
1923 } else {
1924 if (canvas.GetTotalMatrix().HasPerspective()) {
1925 // In case of perspective transformation, make dstRect 1px outset to anti-alias
1926 Drawing::Rect dst(0, 0, cacheImage->GetWidth(), cacheImage->GetHeight());
1927 dst.MakeOutset(1, 1);
1928 canvas.DrawImageRect(*cacheImage, dst, samplingOptions);
1929 } else {
1930 canvas.DrawImage(*cacheImage, 0.0, 0.0, samplingOptions);
1931 }
1932 }
1933 canvas.DetachBrush();
1934 canvas.Restore();
1935 }
1936
1937 std::shared_ptr<Drawing::Image> RSRenderNode::GetCompletedImage(
1938 RSPaintFilterCanvas& canvas, uint32_t threadIndex, bool isUIFirst)
1939 {
1940 if (isUIFirst) {
1941 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
1942 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
1943 if (!cacheCompletedBackendTexture_.IsValid()) {
1944 RS_LOGE("invalid grBackendTexture_");
1945 return nullptr;
1946 }
1947 #ifdef RS_ENABLE_VK
1948 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
1949 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
1950 if (!cacheCompletedSurface_ || !cacheCompletedCleanupHelper_) {
1951 return nullptr;
1952 }
1953 }
1954 #endif
1955 auto image = std::make_shared<Drawing::Image>();
1956 Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
1957 Drawing::BitmapFormat info = Drawing::BitmapFormat{ Drawing::COLORTYPE_RGBA_8888,
1958 Drawing::ALPHATYPE_PREMUL };
1959 #ifdef RS_ENABLE_GL
1960 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
1961 OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
1962 image->BuildFromTexture(*canvas.GetGPUContext(), cacheCompletedBackendTexture_.GetTextureInfo(),
1963 origin, info, nullptr);
1964 }
1965 #endif
1966
1967 #ifdef RS_ENABLE_VK
1968 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
1969 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
1970 image->BuildFromTexture(*canvas.GetGPUContext(), cacheCompletedBackendTexture_.GetTextureInfo(),
1971 origin, info, nullptr,
1972 NativeBufferUtils::DeleteVkImage, cacheCompletedCleanupHelper_->Ref());
1973 }
1974 #endif
1975 return image;
1976 #endif
1977 }
1978
1979 if (!cacheCompletedSurface_) {
1980 RS_LOGE("DrawCacheSurface invalid cacheCompletedSurface");
1981 return nullptr;
1982 }
1983 auto completeImage = cacheCompletedSurface_->GetImageSnapshot();
1984 if (!completeImage) {
1985 RS_LOGE("Get complete image failed");
1986 return nullptr;
1987 }
1988 if (threadIndex == completedSurfaceThreadIndex_) {
1989 return completeImage;
1990 }
1991 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
1992 Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
1993 auto backendTexture = completeImage->GetBackendTexture(false, &origin);
1994 if (!backendTexture.IsValid()) {
1995 RS_LOGE("get backendTexture failed");
1996 return nullptr;
1997 }
1998 auto cacheImage = std::make_shared<Drawing::Image>();
1999 Drawing::BitmapFormat info =
2000 Drawing::BitmapFormat{ completeImage->GetColorType(), completeImage->GetAlphaType() };
2001 bool ret = cacheImage->BuildFromTexture(*canvas.GetGPUContext(), backendTexture.GetTextureInfo(),
2002 origin, info, nullptr);
2003 if (!ret) {
2004 RS_LOGE("RSRenderNode::GetCompletedImage image BuildFromTexture failed");
2005 return nullptr;
2006 }
2007 return cacheImage;
2008 #else
2009 return completeImage;
2010 #endif
2011 }
2012 #endif
2013
2014 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2015 void RSRenderNode::UpdateBackendTexture()
2016 {
2017 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2018 if (cacheSurface_ == nullptr) {
2019 return;
2020 }
2021 #ifndef USE_ROSEN_DRAWING
2022 cacheBackendTexture_
2023 = cacheSurface_->getBackendTexture(SkSurface::BackendHandleAccess::kFlushRead_BackendHandleAccess);
2024 #else
2025 cacheBackendTexture_ = cacheSurface_->GetBackendTexture();
2026 #endif
2027 }
2028 #endif
2029
2030 #ifndef USE_ROSEN_DRAWING
2031 sk_sp<SkSurface> RSRenderNode::GetCompletedCacheSurface(uint32_t threadIndex, bool needCheckThread,
2032 bool releaseAfterGet)
2033 #else
2034 std::shared_ptr<Drawing::Surface> RSRenderNode::GetCompletedCacheSurface(uint32_t threadIndex, bool needCheckThread,
2035 bool releaseAfterGet)
2036 #endif
2037 {
2038 {
2039 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2040 if (releaseAfterGet) {
2041 return std::move(cacheCompletedSurface_);
2042 }
2043 if (!needCheckThread || completedSurfaceThreadIndex_ == threadIndex || !cacheCompletedSurface_) {
2044 return cacheCompletedSurface_;
2045 }
2046 }
2047
2048 // freeze cache scene
2049 ClearCacheSurfaceInThread();
2050 return nullptr;
2051 }
2052
2053 void RSRenderNode::ClearCacheSurfaceInThread()
2054 {
2055 if (clearCacheSurfaceFunc_) {
2056 clearCacheSurfaceFunc_(std::move(cacheSurface_), std::move(cacheCompletedSurface_), cacheSurfaceThreadIndex_,
2057 completedSurfaceThreadIndex_);
2058 }
2059 ClearCacheSurface();
2060 }
2061
2062 #ifndef USE_ROSEN_DRAWING
2063 sk_sp<SkSurface> RSRenderNode::GetCacheSurface(uint32_t threadIndex, bool needCheckThread, bool releaseAfterGet)
2064 #else
2065 std::shared_ptr<Drawing::Surface> RSRenderNode::GetCacheSurface(uint32_t threadIndex, bool needCheckThread,
2066 bool releaseAfterGet)
2067 #endif
2068 {
2069 {
2070 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2071 if (releaseAfterGet) {
2072 return std::move(cacheSurface_);
2073 }
2074 if (!needCheckThread || cacheSurfaceThreadIndex_ == threadIndex || !cacheSurface_) {
2075 return cacheSurface_;
2076 }
2077 }
2078
2079 // freeze cache scene
2080 ClearCacheSurfaceInThread();
2081 return nullptr;
2082 }
2083
2084 void RSRenderNode::CheckGroupableAnimation(const PropertyId& id, bool isAnimAdd)
2085 {
2086 if (id <= 0 || GetType() != RSRenderNodeType::CANVAS_NODE) {
2087 return;
2088 }
2089 auto context = GetContext().lock();
2090 if (!RSSystemProperties::GetAnimationCacheEnabled() ||
2091 !context || !context->GetNodeMap().IsResidentProcessNode(GetId())) {
2092 return;
2093 }
2094 auto target = modifiers_.find(id);
2095 if (target == modifiers_.end() || !target->second) {
2096 return;
2097 }
2098 if (isAnimAdd) {
2099 if (GROUPABLE_ANIMATION_TYPE.count(target->second->GetType())) {
2100 MarkNodeGroup(NodeGroupType::GROUPED_BY_ANIM, true, false);
2101 } else if (CACHEABLE_ANIMATION_TYPE.count(target->second->GetType())) {
2102 hasCacheableAnim_ = true;
2103 }
2104 return;
2105 }
2106 bool hasGroupableAnim = false;
2107 hasCacheableAnim_ = false;
2108 for (auto& [_, animation] : animationManager_.animations_) {
2109 if (!animation || id == animation->GetPropertyId()) {
2110 continue;
2111 }
2112 auto itr = modifiers_.find(animation->GetPropertyId());
2113 if (itr == modifiers_.end() || !itr->second) {
2114 continue;
2115 }
2116 hasGroupableAnim = (hasGroupableAnim || (GROUPABLE_ANIMATION_TYPE.count(itr->second->GetType()) != 0));
2117 hasCacheableAnim_ = (hasCacheableAnim_ || (CACHEABLE_ANIMATION_TYPE.count(itr->second->GetType()) != 0));
2118 }
2119 MarkNodeGroup(NodeGroupType::GROUPED_BY_ANIM, hasGroupableAnim, false);
2120 }
2121
2122 bool RSRenderNode::IsForcedDrawInGroup() const
2123 {
2124 return nodeGroupType_ == NodeGroupType::GROUPED_BY_USER;
2125 }
2126
2127 bool RSRenderNode::IsSuggestedDrawInGroup() const
2128 {
2129 return nodeGroupType_ != NodeGroupType::NONE;
2130 }
2131
2132 void RSRenderNode::MarkNodeGroup(NodeGroupType type, bool isNodeGroup, bool includeProperty)
2133 {
2134 if (type >= nodeGroupType_) {
2135 if (isNodeGroup && type == NodeGroupType::GROUPED_BY_UI) {
2136 auto context = GetContext().lock();
2137 if (context && context->GetNodeMap().IsResidentProcessNode(GetId())) {
2138 nodeGroupType_ = type;
2139 SetDirty();
2140 }
2141 } else {
2142 nodeGroupType_ = isNodeGroup ? type : NodeGroupType::NONE;
2143 SetDirty();
2144 }
2145 nodeGroupIncludeProperty_ = includeProperty;
2146 if (type == NodeGroupType::GROUPED_BY_USER) {
2147 GetMutableRenderProperties().SetAlphaOffscreen(isNodeGroup);
2148 }
2149 }
2150 }
2151
2152 bool RSRenderNode::IsNodeGroupIncludeProperty() const
2153 {
2154 return nodeGroupIncludeProperty_;
2155 }
2156
2157 void RSRenderNode::MarkNodeSingleFrameComposer(bool isNodeSingleFrameComposer, pid_t pid)
2158 {
2159 isNodeSingleFrameComposer_ = isNodeSingleFrameComposer;
2160 appPid_ = pid;
2161 }
2162
2163 bool RSRenderNode::GetNodeIsSingleFrameComposer() const
2164 {
2165 return isNodeSingleFrameComposer_;
2166 }
2167
2168 void RSRenderNode::CheckDrawingCacheType()
2169 {
2170 if (nodeGroupType_ == NodeGroupType::NONE) {
2171 SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
2172 } else if (nodeGroupType_ == NodeGroupType::GROUPED_BY_USER) {
2173 SetDrawingCacheType(RSDrawingCacheType::FORCED_CACHE);
2174 } else {
2175 SetDrawingCacheType(RSDrawingCacheType::TARGETED_CACHE);
2176 }
2177 }
2178
2179 void RSRenderNode::ResetFilterRectsInCache(const std::unordered_set<NodeId>& curRects)
2180 {
2181 curCacheFilterRects_ = curRects;
2182 }
2183
2184 void RSRenderNode::GetFilterRectsInCache(std::unordered_map<NodeId, std::unordered_set<NodeId>>& allRects) const
2185 {
2186 if (!curCacheFilterRects_.empty()) {
2187 allRects.emplace(GetId(), curCacheFilterRects_);
2188 }
2189 }
2190
2191 bool RSRenderNode::IsFilterRectsInCache() const
2192 {
2193 return !curCacheFilterRects_.empty();
2194 }
2195
2196 RectI RSRenderNode::GetFilterRect() const
2197 {
2198 auto& properties = GetRenderProperties();
2199 auto geoPtr = (properties.GetBoundsGeometry());
2200 if (!geoPtr) {
2201 return {};
2202 }
2203 if (properties.GetClipBounds() != nullptr) {
2204 #ifndef USE_ROSEN_DRAWING
2205 auto filterRect = properties.GetClipBounds()->GetSkiaPath().getBounds();
2206 auto absRect = geoPtr->GetAbsMatrix().mapRect(filterRect);
2207 return {absRect.x(), absRect.y(), absRect.width(), absRect.height()};
2208 #else
2209 auto filterRect = properties.GetClipBounds()->GetDrawingPath().GetBounds();
2210 Drawing::Rect absRect;
2211 geoPtr->GetAbsMatrix().MapRect(absRect, filterRect);
2212 return {absRect.GetLeft(), absRect.GetTop(), absRect.GetWidth(), absRect.GetHeight()};
2213 #endif
2214 } else {
2215 return geoPtr->GetAbsRect();
2216 }
2217 }
2218
2219 void RSRenderNode::UpdateFullScreenFilterCacheRect(
2220 RSDirtyRegionManager& dirtyManager, bool isForeground) const
2221 {
2222 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
2223 auto& renderProperties = GetRenderProperties();
2224 auto& manager = renderProperties.GetFilterCacheManager(isForeground);
2225 // Record node's cache area if it has valid filter cache
2226 // If there are any invalid caches under full screen cache filter, the occlusion should be invalidated
2227 if (!manager->IsCacheValid() && dirtyManager.IsCacheableFilterRectEmpty()) {
2228 dirtyManager.InvalidateFilterCacheRect();
2229 } else if (ROSEN_EQ(GetGlobalAlpha(), 1.0f) && ROSEN_EQ(renderProperties.GetCornerRadius().x_, 0.0f) &&
2230 manager->GetCachedImageRegion() == dirtyManager.GetSurfaceRect() && !IsInstanceOf<RSEffectRenderNode>()) {
2231 // Only record full screen filter cache for occlusion calculation
2232 dirtyManager.UpdateCacheableFilterRect(manager->GetCachedImageRegion());
2233 }
2234 #endif
2235 }
2236
2237 void RSRenderNode::UpdateFilterCacheManagerWithCacheRegion(
2238 RSDirtyRegionManager& dirtyManager, const std::optional<RectI>& clipRect)
2239 {
2240 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
2241 if (!RSProperties::FilterCacheEnabled) {
2242 return;
2243 }
2244 auto& renderProperties = GetRenderProperties();
2245 if (!renderProperties.NeedFilter()) {
2246 return;
2247 }
2248 auto filterRect = GetFilterRect();
2249 if (clipRect.has_value()) {
2250 filterRect.IntersectRect(*clipRect);
2251 }
2252
2253 // background filter
2254 if (auto& manager = renderProperties.GetFilterCacheManager(false)) {
2255 // invalidate cache if filter region is not inside of cached image region
2256 if (manager->IsCacheValid() && !filterRect.IsInsideOf(manager->GetCachedImageRegion())) {
2257 manager->UpdateCacheStateWithFilterRegion();
2258 if (auto context = GetContext().lock()) {
2259 RS_TRACE_NAME_FMT("background filter of node Id:%" PRIu64 " is invalid", GetId());
2260 context->MarkNeedPurge(ClearMemoryMoment::FILTER_INVALID, RSContext::PurgeType::STRONGLY);
2261 }
2262 }
2263 UpdateFullScreenFilterCacheRect(dirtyManager, false);
2264 }
2265 // foreground filter
2266 if (auto& manager = renderProperties.GetFilterCacheManager(true)) {
2267 // invalidate cache if filter region is not inside of cached image region
2268 if (manager->IsCacheValid() && !filterRect.IsInsideOf(manager->GetCachedImageRegion())) {
2269 manager->UpdateCacheStateWithFilterRegion();
2270 if (auto context = GetContext().lock()) {
2271 RS_TRACE_NAME_FMT("foreground filter of node Id:%" PRIu64 " is invalid", GetId());
2272 context->MarkNeedPurge(ClearMemoryMoment::FILTER_INVALID, RSContext::PurgeType::STRONGLY);
2273 }
2274 }
2275 UpdateFullScreenFilterCacheRect(dirtyManager, true);
2276 }
2277 #endif
2278 }
2279
2280 void RSRenderNode::OnTreeStateChanged()
2281 {
2282 if (isOnTheTree_) {
2283 // Set dirty and force add to active node list, re-generate children list if needed
2284 SetDirty(true);
2285 }
2286 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
2287 if (!isOnTheTree_) {
2288 // clear filter cache when node is removed from tree
2289 GetMutableRenderProperties().ClearFilterCache();
2290 GetMutableRenderProperties().ReleaseColorPickerTaskShadow();
2291 }
2292 #endif
2293 }
2294
2295 bool RSRenderNode::HasDisappearingTransition(bool recursive) const
2296 {
2297 if (disappearingTransitionCount_ > 0) {
2298 return true;
2299 }
2300 if (recursive == false) {
2301 return false;
2302 }
2303 auto parent = GetParent().lock();
2304 if (parent == nullptr) {
2305 return false;
2306 }
2307 return parent->HasDisappearingTransition(true);
2308 }
2309
2310 RSRenderNode::ChildrenListSharedPtr RSRenderNode::GetChildren() const
2311 {
2312 return std::atomic_load_explicit(&fullChildrenList_, std::memory_order_acquire);
2313 }
2314
2315 RSRenderNode::ChildrenListSharedPtr RSRenderNode::GetSortedChildren() const
2316 {
2317 return std::atomic_load_explicit(&fullChildrenList_, std::memory_order_acquire);
2318 }
2319
2320 std::shared_ptr<RSRenderNode> RSRenderNode::GetFirstChild() const
2321 {
2322 return children_.empty() ? nullptr : children_.front().lock();
2323 }
2324
2325 void RSRenderNode::UpdateFullChildrenListIfNeeded()
2326 {
2327 if (!isFullChildrenListValid_) {
2328 GenerateFullChildrenList();
2329 } else if (!isChildrenSorted_) {
2330 ResortChildren();
2331 }
2332 }
2333
2334 void RSRenderNode::GenerateFullChildrenList()
2335 {
2336 // both children_ and disappearingChildren_ are empty, no need to generate fullChildrenList_
2337 if (children_.empty() && disappearingChildren_.empty()) {
2338 auto prevFullChildrenList = fullChildrenList_;
2339 isFullChildrenListValid_ = true;
2340 isChildrenSorted_ = true;
2341 std::atomic_store_explicit(&fullChildrenList_, EmptyChildrenList, std::memory_order_release);
2342 return;
2343 }
2344
2345 // Step 0: Initialize
2346 auto fullChildrenList = std::make_shared<std::vector<std::shared_ptr<RSRenderNode>>>();
2347
2348 // Step 1: Copy all children into sortedChildren while checking and removing expired children.
2349 children_.remove_if([&](const auto& child) -> bool {
2350 auto existingChild = child.lock();
2351 if (existingChild == nullptr) {
2352 ROSEN_LOGI("RSRenderNode::GenerateSortedChildren removing expired child, this is rare but possible.");
2353 return true;
2354 }
2355 if (isContainBootAnimation_ && !existingChild->GetBootAnimation()) {
2356 ROSEN_LOGD("RSRenderNode::GenerateSortedChildren %{public}" PRIu64 " skip"
2357 " move not bootAnimation displaynode"
2358 "child(id %{public}" PRIu64 ")"" into children_", GetId(), existingChild->GetId());
2359 return false;
2360 }
2361 fullChildrenList->emplace_back(std::move(existingChild));
2362 return false;
2363 });
2364
2365 // Step 2: Insert disappearing children into sortedChildren at their original position.
2366 // Note:
2367 // 1. We don't need to check if the disappearing transition is finished; it's already handled in
2368 // RSRenderTransition::OnDetach.
2369 // 2. We don't need to check if the disappearing child is expired; it's already been checked when moving from
2370 // children_ to disappearingChildren_. We hold ownership of the shared_ptr of the child after that.
2371 std::for_each(disappearingChildren_.begin(), disappearingChildren_.end(), [&](const auto& pair) -> void {
2372 auto& disappearingChild = pair.first;
2373 if (isContainBootAnimation_ && !disappearingChild->GetBootAnimation()) {
2374 ROSEN_LOGD("RSRenderNode::GenerateSortedChildren %{public}" PRIu64 " skip"
2375 " move not bootAnimation displaynode"
2376 "child(id %{public}" PRIu64 ")"" into disappearingChild", GetId(), disappearingChild->GetId());
2377 return;
2378 }
2379 const auto& origPos = pair.second;
2380 if (origPos < fullChildrenList->size()) {
2381 fullChildrenList->emplace(std::next(fullChildrenList->begin(), origPos), disappearingChild);
2382 } else {
2383 fullChildrenList->emplace_back(disappearingChild);
2384 }
2385 });
2386
2387 // Step 3: Sort all children by z-order
2388 std::stable_sort(
2389 fullChildrenList->begin(), fullChildrenList->end(), [](const auto& first, const auto& second) -> bool {
2390 return first->GetRenderProperties().GetPositionZ() < second->GetRenderProperties().GetPositionZ();
2391 });
2392
2393 // Keep a reference to fullChildrenList_ to prevent its deletion when swapping it
2394 auto prevFullChildrenList = fullChildrenList_;
2395
2396 // Update the flag to indicate that children are now valid and sorted
2397 isFullChildrenListValid_ = true;
2398 isChildrenSorted_ = true;
2399
2400 // Move the fullChildrenList to fullChildrenList_ atomically
2401 ChildrenListSharedPtr constFullChildrenList = std::move(fullChildrenList);
2402 std::atomic_store_explicit(&fullChildrenList_, constFullChildrenList, std::memory_order_release);
2403 }
2404
2405 void RSRenderNode::ResortChildren()
2406 {
2407 // Make a copy of the fullChildrenList for sorting
2408 auto fullChildrenList = std::make_shared<std::vector<std::shared_ptr<RSRenderNode>>>(*fullChildrenList_);
2409
2410 // Sort the children by their z-order
2411 std::stable_sort(
2412 fullChildrenList->begin(), fullChildrenList->end(), [](const auto& first, const auto& second) -> bool {
2413 return first->GetRenderProperties().GetPositionZ() < second->GetRenderProperties().GetPositionZ();
2414 });
2415
2416 // Keep a reference to fullChildrenList_ to prevent its deletion when swapping it
2417 auto prevFullChildrenList = fullChildrenList_;
2418
2419 // Update the flag to indicate that children are now sorted
2420 isChildrenSorted_ = true;
2421
2422 // Move the fullChildrenList to fullChildrenList_ atomically
2423 ChildrenListSharedPtr constFullChildrenList = std::move(fullChildrenList);
2424 std::atomic_store_explicit(&fullChildrenList_, constFullChildrenList, std::memory_order_release);
2425 }
2426
2427 uint32_t RSRenderNode::GetChildrenCount() const
2428 {
2429 return children_.size();
2430 }
2431
2432 bool RSRenderNode::IsOnTheTree() const
2433 {
2434 return isOnTheTree_;
2435 }
2436 void RSRenderNode::SetTunnelHandleChange(bool change)
2437 {
2438 isTunnelHandleChange_ = change;
2439 }
2440 bool RSRenderNode::GetTunnelHandleChange() const
2441 {
2442 return isTunnelHandleChange_;
2443 }
2444 bool RSRenderNode::HasChildrenOutOfRect() const
2445 {
2446 if (GetRenderProperties().GetClipToBounds() || GetRenderProperties().GetClipToFrame()) {
2447 return false;
2448 }
2449 return hasChildrenOutOfRect_;
2450 }
2451 void RSRenderNode::UpdateChildrenOutOfRectFlag(bool flag)
2452 {
2453 hasChildrenOutOfRect_ = flag;
2454 }
2455 void RSRenderNode::ResetHasRemovedChild()
2456 {
2457 hasRemovedChild_ = false;
2458 }
2459 bool RSRenderNode::HasRemovedChild() const
2460 {
2461 return hasRemovedChild_;
2462 }
2463 void RSRenderNode::ResetChildrenRect()
2464 {
2465 childrenRect_ = RectI();
2466 }
2467 RectI RSRenderNode::GetChildrenRect() const
2468 {
2469 return childrenRect_;
2470 }
2471 bool RSRenderNode::ChildHasFilter() const
2472 {
2473 return childHasFilter_;
2474 }
2475 void RSRenderNode::SetChildHasFilter(bool childHasFilter)
2476 {
2477 childHasFilter_ = childHasFilter;
2478 }
2479 NodeId RSRenderNode::GetInstanceRootNodeId() const
2480 {
2481 return instanceRootNodeId_;
2482 }
2483 const std::shared_ptr<RSRenderNode> RSRenderNode::GetInstanceRootNode() const
2484 {
2485 auto context = GetContext().lock();
2486 if (!context) {
2487 ROSEN_LOGE("Invalid context");
2488 return nullptr;
2489 }
2490 return context->GetNodeMap().GetRenderNode(instanceRootNodeId_);
2491 }
2492 NodeId RSRenderNode::GetFirstLevelNodeId() const
2493 {
2494 return firstLevelNodeId_;
2495 }
2496 bool RSRenderNode::IsRenderUpdateIgnored() const
2497 {
2498 return isRenderUpdateIgnored_;
2499 }
2500 RSAnimationManager& RSRenderNode::GetAnimationManager()
2501 {
2502 return animationManager_;
2503 }
2504 RectI RSRenderNode::GetOldDirty() const
2505 {
2506 return oldDirty_;
2507 }
2508 RectI RSRenderNode::GetOldDirtyInSurface() const
2509 {
2510 return oldDirtyInSurface_;
2511 }
2512 bool RSRenderNode::IsDirtyRegionUpdated() const
2513 {
2514 return isDirtyRegionUpdated_;
2515 }
2516 void RSRenderNode::CleanDirtyRegionUpdated()
2517 {
2518 isDirtyRegionUpdated_ = false;
2519 }
2520 bool RSRenderNode::IsShadowValidLastFrame() const
2521 {
2522 return isShadowValidLastFrame_;
2523 }
2524 void RSRenderNode::SetStaticCached(bool isStaticCached)
2525 {
2526 isStaticCached_ = isStaticCached;
2527 // ensure defrost subtree would be updated
2528 if (!isStaticCached_) {
2529 SetContentDirty();
2530 }
2531 }
2532 bool RSRenderNode::IsStaticCached() const
2533 {
2534 return isStaticCached_;
2535 }
2536 void RSRenderNode::UpdateCompletedCacheSurface()
2537 {
2538 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2539 std::swap(cacheSurface_, cacheCompletedSurface_);
2540 std::swap(cacheSurfaceThreadIndex_, completedSurfaceThreadIndex_);
2541 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
2542 std::swap(cacheBackendTexture_, cacheCompletedBackendTexture_);
2543 #ifdef RS_ENABLE_VK
2544 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
2545 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
2546 std::swap(cacheCleanupHelper_, cacheCompletedCleanupHelper_);
2547 }
2548 #endif
2549 SetTextureValidFlag(true);
2550 #endif
2551 }
2552 void RSRenderNode::SetTextureValidFlag(bool isValid)
2553 {
2554 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
2555 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2556 isTextureValid_ = isValid;
2557 #endif
2558 }
2559 void RSRenderNode::ClearCacheSurface(bool isClearCompletedCacheSurface)
2560 {
2561 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2562 cacheSurface_ = nullptr;
2563 #ifdef RS_ENABLE_VK
2564 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
2565 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
2566 cacheCleanupHelper_ = nullptr;
2567 }
2568 #endif
2569 if (isClearCompletedCacheSurface) {
2570 cacheCompletedSurface_ = nullptr;
2571 #ifdef RS_ENABLE_VK
2572 if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::VULKAN ||
2573 OHOS::Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::DDGR) {
2574 cacheCompletedCleanupHelper_ = nullptr;
2575 }
2576 #endif
2577 #if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
2578 isTextureValid_ = false;
2579 #endif
2580 }
2581 }
2582 void RSRenderNode::SetCacheType(CacheType cacheType)
2583 {
2584 cacheType_ = cacheType;
2585 }
2586 CacheType RSRenderNode::GetCacheType() const
2587 {
2588 return cacheType_;
2589 }
2590 int RSRenderNode::GetShadowRectOffsetX() const
2591 {
2592 return shadowRectOffsetX_;
2593 }
2594 int RSRenderNode::GetShadowRectOffsetY() const
2595 {
2596 return shadowRectOffsetY_;
2597 }
2598 void RSRenderNode::SetDrawingCacheType(RSDrawingCacheType cacheType)
2599 {
2600 drawingCacheType_ = cacheType;
2601 }
2602 RSDrawingCacheType RSRenderNode::GetDrawingCacheType() const
2603 {
2604 return drawingCacheType_;
2605 }
2606 void RSRenderNode::SetDrawingCacheChanged(bool cacheChanged)
2607 {
2608 isDrawingCacheChanged_ = drawingCacheNeedUpdate_ || cacheChanged;
2609 drawingCacheNeedUpdate_ = isDrawingCacheChanged_;
2610 }
2611 bool RSRenderNode::GetDrawingCacheChanged() const
2612 {
2613 return isDrawingCacheChanged_;
2614 }
2615 void RSRenderNode::ResetDrawingCacheNeedUpdate()
2616 {
2617 drawingCacheNeedUpdate_ = false;
2618 }
2619 void RSRenderNode::SetCacheGeoPreparationDelay(bool val)
2620 {
2621 cacheGeoPreparationDelay_ = cacheGeoPreparationDelay_ || val;
2622 }
2623 void RSRenderNode::ResetCacheGeoPreparationDelay()
2624 {
2625 cacheGeoPreparationDelay_ = false;
2626 }
2627 bool RSRenderNode::GetCacheGeoPreparationDelay() const
2628 {
2629 return cacheGeoPreparationDelay_;
2630 }
2631
2632 void RSRenderNode::StoreMustRenewedInfo()
2633 {
2634 mustRenewedInfo_ = hasHardwareNode_ || hasFilter_ || hasEffectNode_;
2635 }
2636
2637 bool RSRenderNode::HasMustRenewedInfo() const
2638 {
2639 return mustRenewedInfo_;
2640 }
2641
2642 void RSRenderNode::SetUseEffectNodes(bool val)
2643 {
2644 hasEffectNode_ = val;
2645 }
2646
2647 bool RSRenderNode::HasUseEffectNodes() const
2648 {
2649 return hasEffectNode_;
2650 }
2651
2652 void RSRenderNode::SetVisitedCacheRootIds(const std::unordered_set<NodeId>& visitedNodes)
2653 {
2654 visitedCacheRoots_ = visitedNodes;
2655 }
2656 const std::unordered_set<NodeId>& RSRenderNode::GetVisitedCacheRootIds() const
2657 {
2658 return visitedCacheRoots_;
2659 }
2660 void RSRenderNode::UpdateSubSurfaceCnt(SharedPtr curParent, SharedPtr preParent)
2661 {
2662 uint32_t subSurfaceCnt = GetType() == RSRenderNodeType::SURFACE_NODE ?
2663 subSurfaceCnt_ + 1 : subSurfaceCnt_;
2664 if (subSurfaceCnt == 0) {
2665 return;
2666 }
2667 if (curParent) {
2668 curParent->subSurfaceCnt_ += subSurfaceCnt;
2669 UpdateSubSurfaceCnt(curParent->GetParent().lock(), nullptr);
2670 }
2671 if (preParent) {
2672 preParent->subSurfaceCnt_ -= subSurfaceCnt;
2673 UpdateSubSurfaceCnt(nullptr, preParent->GetParent().lock());
2674 }
2675 }
2676 bool RSRenderNode::HasSubSurface() const
2677 {
2678 return subSurfaceCnt_ > 0;
2679 }
2680 void RSRenderNode::SetDrawingCacheRootId(NodeId id)
2681 {
2682 drawingCacheRootId_ = id;
2683 }
2684 NodeId RSRenderNode::GetDrawingCacheRootId() const
2685 {
2686 return drawingCacheRootId_;
2687 }
2688 void RSRenderNode::SetIsMarkDriven(bool isMarkDriven)
2689 {
2690 isMarkDriven_ = isMarkDriven;
2691 }
2692 bool RSRenderNode::IsMarkDriven() const
2693 {
2694 return isMarkDriven_;
2695 }
2696 void RSRenderNode::SetIsMarkDrivenRender(bool isMarkDrivenRender)
2697 {
2698 isMarkDrivenRender_ = isMarkDrivenRender;
2699 }
2700 bool RSRenderNode::IsMarkDrivenRender() const
2701 {
2702 return isMarkDrivenRender_;
2703 }
2704 void RSRenderNode::SetItemIndex(int index)
2705 {
2706 itemIndex_ = index;
2707 }
2708 int RSRenderNode::GetItemIndex() const
2709 {
2710 return itemIndex_;
2711 }
2712 void RSRenderNode::SetPaintState(bool paintState)
2713 {
2714 paintState_ = paintState;
2715 }
2716 bool RSRenderNode::GetPaintState() const
2717 {
2718 return paintState_;
2719 }
2720 void RSRenderNode::SetIsContentChanged(bool isChanged)
2721 {
2722 isContentChanged_ = isChanged;
2723 }
2724 bool RSRenderNode::IsContentChanged() const
2725 {
2726 return isContentChanged_ || HasAnimation();
2727 }
2728 bool RSRenderNode::HasAnimation() const
2729 {
2730 return !animationManager_.animations_.empty();
2731 }
2732 bool RSRenderNode::HasFilter() const
2733 {
2734 return hasFilter_;
2735 }
2736 void RSRenderNode::SetHasFilter(bool hasFilter)
2737 {
2738 hasFilter_ = hasFilter;
2739 }
2740 std::recursive_mutex& RSRenderNode::GetSurfaceMutex() const
2741 {
2742 return surfaceMutex_;
2743 }
2744 bool RSRenderNode::HasHardwareNode() const
2745 {
2746 return hasHardwareNode_;
2747 }
2748 void RSRenderNode::SetHasHardwareNode(bool hasHardwareNode)
2749 {
2750 hasHardwareNode_ = hasHardwareNode;
2751 }
2752 bool RSRenderNode::HasAbilityComponent() const
2753 {
2754 return hasAbilityComponent_;
2755 }
2756 void RSRenderNode::SetHasAbilityComponent(bool hasAbilityComponent)
2757 {
2758 hasAbilityComponent_ = hasAbilityComponent;
2759 }
2760 uint32_t RSRenderNode::GetCacheSurfaceThreadIndex() const
2761 {
2762 return cacheSurfaceThreadIndex_;
2763 }
2764 uint32_t RSRenderNode::GetCompletedSurfaceThreadIndex() const
2765 {
2766 return completedSurfaceThreadIndex_;
2767 }
2768
2769 bool RSRenderNode::IsMainThreadNode() const
2770 {
2771 return isMainThreadNode_;
2772 }
2773 void RSRenderNode::SetIsMainThreadNode(bool isMainThreadNode)
2774 {
2775 isMainThreadNode_ = isMainThreadNode;
2776 }
2777 bool RSRenderNode::IsScale() const
2778 {
2779 return isScale_;
2780 }
2781 void RSRenderNode::SetIsScale(bool isScale)
2782 {
2783 isScale_ = isScale;
2784 }
2785 void RSRenderNode::SetPriority(NodePriorityType priority)
2786 {
2787 priority_ = priority;
2788 }
2789 NodePriorityType RSRenderNode::GetPriority()
2790 {
2791 return priority_;
2792 }
2793 bool RSRenderNode::IsAncestorDirty() const
2794 {
2795 return isAncestorDirty_;
2796 }
2797 void RSRenderNode::SetIsAncestorDirty(bool isAncestorDirty)
2798 {
2799 isAncestorDirty_ = isAncestorDirty;
2800 }
2801 bool RSRenderNode::IsParentLeashWindow() const
2802 {
2803 return isParentLeashWindow_;
2804 }
2805 void RSRenderNode::SetParentLeashWindow()
2806 {
2807 isParentLeashWindow_ = true;
2808 }
2809 bool RSRenderNode::IsParentScbScreen() const
2810 {
2811 return isParentScbScreen_;
2812 }
2813 void RSRenderNode::SetParentScbScreen()
2814 {
2815 isParentScbScreen_ = true;
2816 }
2817 bool RSRenderNode::HasCachedTexture() const
2818 {
2819 #if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
2820 std::scoped_lock<std::recursive_mutex> lock(surfaceMutex_);
2821 return isTextureValid_;
2822 #else
2823 return true;
2824 #endif
2825 }
2826 void RSRenderNode::SetDrawRegion(const std::shared_ptr<RectF>& rect)
2827 {
2828 drawRegion_ = rect;
2829 GetMutableRenderProperties().SetDrawRegion(rect);
2830 }
2831 const std::shared_ptr<RectF>& RSRenderNode::GetDrawRegion() const
2832 {
2833 return drawRegion_;
2834 }
2835 void RSRenderNode::SetOutOfParent(OutOfParentType outOfParent)
2836 {
2837 outOfParent_ = outOfParent;
2838 }
2839 OutOfParentType RSRenderNode::GetOutOfParent() const
2840 {
2841 return outOfParent_;
2842 }
2843 RSRenderNode::NodeGroupType RSRenderNode::GetNodeGroupType()
2844 {
2845 return nodeGroupType_;
2846 }
2847
2848 void RSRenderNode::MarkNonGeometryChanged()
2849 {
2850 geometryChangeNotPerceived_ = true;
2851 }
2852
2853 bool RSRenderNode::GetIsUsedBySubThread() const
2854 {
2855 return isUsedBySubThread_.load();
2856 }
2857 void RSRenderNode::SetIsUsedBySubThread(bool isUsedBySubThread)
2858 {
2859 isUsedBySubThread_.store(isUsedBySubThread);
2860 }
2861
2862 bool RSRenderNode::GetLastIsNeedAssignToSubThread() const
2863 {
2864 return lastIsNeedAssignToSubThread_;
2865 }
2866 void RSRenderNode::SetLastIsNeedAssignToSubThread(bool lastIsNeedAssignToSubThread)
2867 {
2868 lastIsNeedAssignToSubThread_ = lastIsNeedAssignToSubThread;
2869 }
2870 } // namespace Rosen
2871 } // namespace OHOS
2872